├── vendor ├── github.com │ ├── pborman │ │ └── uuid │ │ │ ├── CONTRIBUTORS │ │ │ ├── doc.go │ │ │ ├── CONTRIBUTING.md │ │ │ ├── README.md │ │ │ ├── version4.go │ │ │ ├── version1.go │ │ │ ├── LICENSE │ │ │ ├── sql.go │ │ │ ├── hash.go │ │ │ ├── util.go │ │ │ ├── marshal.go │ │ │ ├── dce.go │ │ │ ├── node.go │ │ │ ├── time.go │ │ │ └── uuid.go │ └── masterzen │ │ ├── simplexml │ │ └── dom │ │ │ ├── namespace.go │ │ │ ├── document.go │ │ │ └── element.go │ │ ├── winrm │ │ ├── error.go │ │ ├── powershell.go │ │ ├── ntlm.go │ │ ├── parameters.go │ │ ├── Makefile │ │ ├── shell.go │ │ ├── endpoint.go │ │ ├── soap │ │ │ ├── message.go │ │ │ ├── namespaces.go │ │ │ └── header.go │ │ ├── http.go │ │ ├── auth.go │ │ ├── response.go │ │ ├── client.go │ │ ├── request.go │ │ ├── command.go │ │ └── README.md │ │ └── azure-sdk-for-go │ │ └── core │ │ ├── http │ │ ├── race.go │ │ ├── jar.go │ │ ├── lex.go │ │ ├── doc.go │ │ ├── filetransport.go │ │ ├── triv.go │ │ ├── status.go │ │ ├── chunked.go │ │ ├── sniff.go │ │ ├── header.go │ │ └── response.go │ │ └── tls │ │ ├── alert.go │ │ ├── generate_cert.go │ │ ├── ticket.go │ │ ├── tls.go │ │ └── prf.go └── vendor.json ├── main.go ├── scripts ├── gogetcookie.sh ├── gofmtcheck.sh ├── errcheck.sh └── changelog-links.sh ├── .gitignore ├── website ├── docs │ ├── r │ │ ├── checkpoint.html.markdown │ │ ├── virtual_disk.html.markdown │ │ └── virtual_machine.html.markdown │ └── index.html.markdown └── scvmm.erb ├── scvmm ├── provider_test.go ├── config.go ├── provider.go ├── validation_library.go ├── powershell_scripts_execution.go ├── resource_scvmm_virtual_machine_test.go ├── resource_scvmm_checkpoint_test.go └── resource_scvmm_virtual_disk_test.go ├── tf-scvmm-devrc.mk.example ├── GNUmakefile └── README.md /vendor/github.com/pborman/uuid/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | Paul Borman 2 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/simplexml/dom/namespace.go: -------------------------------------------------------------------------------- 1 | package dom 2 | 3 | type Namespace struct { 4 | Prefix string 5 | Uri string 6 | } 7 | 8 | func (ns *Namespace) SetTo(node *Element) { 9 | node.SetNamespace(ns.Prefix, ns.Uri) 10 | } 11 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/hashicorp/terraform/plugin" 5 | "github.com/GSLabDev/terraform-provider-scvmm/scvmm" 6 | ) 7 | 8 | func main() { 9 | plugin.Serve(&plugin.ServeOpts{ 10 | ProviderFunc: scvmm.Provider}) 11 | } 12 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/winrm/error.go: -------------------------------------------------------------------------------- 1 | package winrm 2 | 3 | import "fmt" 4 | 5 | // errWinrm generic error struct 6 | type errWinrm struct { 7 | message string 8 | } 9 | 10 | // ErrWinrm implements the Error type interface 11 | func (e errWinrm) Error() string { 12 | return fmt.Sprintf("%s", e.message) 13 | } 14 | -------------------------------------------------------------------------------- /scripts/gogetcookie.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | touch ~/.gitcookies 4 | chmod 0600 ~/.gitcookies 5 | 6 | git config --global http.cookiefile ~/.gitcookies 7 | 8 | tr , \\t <<\__END__ >>~/.gitcookies 9 | .googlesource.com,TRUE,/,TRUE,2147483647,o,git-paul.hashicorp.com=1/z7s05EYPudQ9qoe6dMVfmAVwgZopEkZBb1a2mA5QtHE 10 | __END__ 11 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/azure-sdk-for-go/core/http/race.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build race 6 | 7 | package http 8 | 9 | func init() { 10 | raceEnabled = true 11 | } 12 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // The uuid package generates and inspects UUIDs. 6 | // 7 | // UUIDs are based on RFC 4122 and DCE 1.1: Authentication and Security Services. 8 | package uuid 9 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | # How to contribute 2 | 3 | We definitely welcome patches and contribution to this project! 4 | 5 | ### Legal requirements 6 | 7 | In order to protect both you and ourselves, you will need to sign the 8 | [Contributor License Agreement](https://cla.developers.google.com/clas). 9 | 10 | You may have already signed it for other Google projects. 11 | -------------------------------------------------------------------------------- /scripts/gofmtcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Check gofmt 4 | echo "==> Checking that code complies with gofmt requirements..." 5 | gofmt_files=$(gofmt -l `find . -name '*.go' | grep -v vendor`) 6 | if [[ -n ${gofmt_files} ]]; then 7 | echo 'gofmt needs running on the following files:' 8 | echo "${gofmt_files}" 9 | echo "You can use the command: \`make fmt\` to reformat code." 10 | exit 1 11 | fi 12 | 13 | exit 0 14 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | *.dll 2 | *.exe 3 | .DS_Store 4 | example.tf 5 | terraform.tfplan 6 | terraform.tfstate 7 | bin/ 8 | modules-dev/ 9 | /pkg/ 10 | website/.vagrant 11 | website/.bundle 12 | website/build 13 | website/node_modules 14 | .vagrant/ 15 | *.backup 16 | ./*.tfstate 17 | .terraform/ 18 | *.log 19 | *.bak 20 | *~ 21 | .*.swp 22 | .idea 23 | *.iml 24 | *.test 25 | *.iml 26 | 27 | website/vendor 28 | 29 | # Test exclusions 30 | !command/test-fixtures/**/*.tfstate 31 | !command/test-fixtures/**/.terraform/ 32 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/winrm/powershell.go: -------------------------------------------------------------------------------- 1 | package winrm 2 | 3 | import ( 4 | "encoding/base64" 5 | "fmt" 6 | ) 7 | 8 | // Powershell wraps a PowerShell script 9 | // and prepares it for execution by the winrm client 10 | func Powershell(psCmd string) string { 11 | // 2 byte chars to make PowerShell happy 12 | wideCmd := "" 13 | for _, b := range []byte(psCmd) { 14 | wideCmd += string(b) + "\x00" 15 | } 16 | 17 | // Base64 encode the command 18 | input := []uint8(wideCmd) 19 | encodedCmd := base64.StdEncoding.EncodeToString(input) 20 | 21 | // Create the powershell.exe command line to execute the script 22 | return fmt.Sprintf("powershell.exe -EncodedCommand %s", encodedCmd) 23 | } 24 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/README.md: -------------------------------------------------------------------------------- 1 | This project was automatically exported from code.google.com/p/go-uuid 2 | 3 | # uuid ![build status](https://travis-ci.org/pborman/uuid.svg?branch=master) 4 | The uuid package generates and inspects UUIDs based on [RFC 4122](http://tools.ietf.org/html/rfc4122) and DCE 1.1: Authentication and Security Services. 5 | 6 | ###### Install 7 | `go get github.com/pborman/uuid` 8 | 9 | ###### Documentation 10 | [![GoDoc](https://godoc.org/github.com/pborman/uuid?status.svg)](http://godoc.org/github.com/pborman/uuid) 11 | 12 | Full `go doc` style documentation for the package can be viewed online without installing this package by using the GoDoc site here: 13 | http://godoc.org/github.com/pborman/uuid 14 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/simplexml/dom/document.go: -------------------------------------------------------------------------------- 1 | package dom 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | ) 7 | 8 | type Document struct { 9 | root *Element 10 | PrettyPrint bool 11 | Indentation string 12 | DocType bool 13 | } 14 | 15 | func CreateDocument() *Document { 16 | return &Document{ PrettyPrint: false, Indentation: " ", DocType: true } 17 | } 18 | 19 | func (doc *Document) SetRoot(node *Element) { 20 | node.parent = nil 21 | doc.root = node 22 | } 23 | 24 | func (doc *Document) String() string { 25 | var b bytes.Buffer 26 | if doc.DocType { 27 | fmt.Fprintln(&b, ``) 28 | } 29 | 30 | if doc.root != nil { 31 | doc.root.Bytes(&b, doc.PrettyPrint, doc.Indentation, 0) 32 | } 33 | 34 | return string(b.Bytes()) 35 | } -------------------------------------------------------------------------------- /vendor/github.com/masterzen/winrm/ntlm.go: -------------------------------------------------------------------------------- 1 | package winrm 2 | 3 | import ( 4 | "github.com/Azure/go-ntlmssp" 5 | "github.com/masterzen/winrm/soap" 6 | ) 7 | 8 | // ClientNTLM provides a transport via NTLMv2 9 | type ClientNTLM struct { 10 | clientRequest 11 | } 12 | 13 | // Transport creates the wrapped NTLM transport 14 | func (c *ClientNTLM) Transport(endpoint *Endpoint) error { 15 | c.clientRequest.Transport(endpoint) 16 | c.clientRequest.transport = &ntlmssp.Negotiator{RoundTripper: c.clientRequest.transport} 17 | return nil 18 | } 19 | 20 | // Post make post to the winrm soap service (forwarded to clientRequest implementation) 21 | func (c ClientNTLM) Post(client *Client, request *soap.SoapMessage) (string, error) { 22 | return c.clientRequest.Post(client, request) 23 | } 24 | -------------------------------------------------------------------------------- /scripts/errcheck.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | # Check gofmt 4 | echo "==> Checking for unchecked errors..." 5 | 6 | if ! which errcheck > /dev/null; then 7 | echo "==> Installing errcheck..." 8 | go get -u github.com/kisielk/errcheck 9 | fi 10 | 11 | err_files=$(errcheck -ignoretests \ 12 | -ignore 'github.com/hashicorp/terraform/helper/schema:Set' \ 13 | -ignore 'bytes:.*' \ 14 | -ignore 'io:Close|Write' \ 15 | $(go list ./...| grep -v /vendor/)) 16 | 17 | if [[ -n ${err_files} ]]; then 18 | echo 'Unchecked errors found in the following places:' 19 | echo "${err_files}" 20 | echo "Please handle returned errors. You can check directly with \`make errcheck\`" 21 | exit 1 22 | fi 23 | 24 | exit 0 25 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/winrm/parameters.go: -------------------------------------------------------------------------------- 1 | package winrm 2 | 3 | // Parameters struct defines 4 | // metadata information and http transport config 5 | type Parameters struct { 6 | Timeout string 7 | Locale string 8 | EnvelopeSize int 9 | TransportDecorator func() Transporter 10 | } 11 | 12 | // DefaultParameters return constant config 13 | // of type Parameters 14 | var DefaultParameters = NewParameters("PT60S", "en-US", 153600) 15 | 16 | // NewParameters return new struct of type Parameters 17 | // this struct makes the configuration for the request, size message, etc. 18 | func NewParameters(timeout, locale string, envelopeSize int) *Parameters { 19 | return &Parameters{ 20 | Timeout: timeout, 21 | Locale: locale, 22 | EnvelopeSize: envelopeSize, 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/winrm/Makefile: -------------------------------------------------------------------------------- 1 | NO_COLOR=\033[0m 2 | OK_COLOR=\033[32;01m 3 | ERROR_COLOR=\033[31;01m 4 | WARN_COLOR=\033[33;01m 5 | DEPS = $(go list -f '{{range .TestImports}}{{.}} {{end}}' ./... | fgrep -v 'winrm') 6 | 7 | all: deps 8 | @mkdir -p bin/ 9 | @printf "$(OK_COLOR)==> Building$(NO_COLOR)\n" 10 | @go build github.com/masterzen/winrm 11 | 12 | deps: 13 | @printf "$(OK_COLOR)==> Installing dependencies$(NO_COLOR)\n" 14 | @go get -d -v ./... 15 | @echo $(DEPS) | xargs -n1 go get -d 16 | 17 | updatedeps: 18 | go list ./... | xargs go list -f '{{join .Deps "\n"}}' | grep -v github.com/masterzen/winrm | sort -u | xargs go get -f -u -v 19 | 20 | clean: 21 | @rm -rf bin/ pkg/ src/ 22 | 23 | format: 24 | go fmt ./... 25 | 26 | ci: deps 27 | @printf "$(OK_COLOR)==> Testing with Coveralls...$(NO_COLOR)\n" 28 | "$(CURDIR)/scripts/test.sh" 29 | 30 | test: deps 31 | @printf "$(OK_COLOR)==> Testing...$(NO_COLOR)\n" 32 | go test ./... 33 | 34 | .PHONY: all clean deps format test updatedeps 35 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/version4.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | // Random returns a Random (Version 4) UUID or panics. 8 | // 9 | // The strength of the UUIDs is based on the strength of the crypto/rand 10 | // package. 11 | // 12 | // A note about uniqueness derived from from the UUID Wikipedia entry: 13 | // 14 | // Randomly generated UUIDs have 122 random bits. One's annual risk of being 15 | // hit by a meteorite is estimated to be one chance in 17 billion, that 16 | // means the probability is about 0.00000000006 (6 × 10−11), 17 | // equivalent to the odds of creating a few tens of trillions of UUIDs in a 18 | // year and having one duplicate. 19 | func NewRandom() UUID { 20 | uuid := make([]byte, 16) 21 | randomBits([]byte(uuid)) 22 | uuid[6] = (uuid[6] & 0x0f) | 0x40 // Version 4 23 | uuid[8] = (uuid[8] & 0x3f) | 0x80 // Variant is 10 24 | return uuid 25 | } 26 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/azure-sdk-for-go/core/http/jar.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package http 6 | 7 | import ( 8 | "net/url" 9 | ) 10 | 11 | // A CookieJar manages storage and use of cookies in HTTP requests. 12 | // 13 | // Implementations of CookieJar must be safe for concurrent use by multiple 14 | // goroutines. 15 | // 16 | // The net/http/cookiejar package provides a CookieJar implementation. 17 | type CookieJar interface { 18 | // SetCookies handles the receipt of the cookies in a reply for the 19 | // given URL. It may or may not choose to save the cookies, depending 20 | // on the jar's policy and implementation. 21 | SetCookies(u *url.URL, cookies []*Cookie) 22 | 23 | // Cookies returns the cookies to send in a request for the given URL. 24 | // It is up to the implementation to honor the standard cookie use 25 | // restrictions such as in RFC 6265. 26 | Cookies(u *url.URL) []*Cookie 27 | } 28 | -------------------------------------------------------------------------------- /scripts/changelog-links.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # This script rewrites [GH-nnnn]-style references in the CHANGELOG.md file to 4 | # be Markdown links to the given github issues. 5 | # 6 | # This is run during releases so that the issue references in all of the 7 | # released items are presented as clickable links, but we can just use the 8 | # easy [GH-nnnn] shorthand for quickly adding items to the "Unrelease" section 9 | # while merging things between releases. 10 | 11 | set -e 12 | 13 | if [[ ! -f CHANGELOG.md ]]; then 14 | echo "ERROR: CHANGELOG.md not found in pwd." 15 | echo "Please run this from the root of the terraform provider repository" 16 | exit 1 17 | fi 18 | 19 | if [[ `uname` == "Darwin" ]]; then 20 | echo "Using BSD sed" 21 | SED="sed -i.bak -E -e" 22 | else 23 | echo "Using GNU sed" 24 | SED="sed -i.bak -r -e" 25 | fi 26 | 27 | PROVIDER_URL="https:\/\/github.com\/terraform-providers\/terraform-provider-aws" 28 | 29 | $SED "s/GH-([0-9]+)/\[#\1\]\($PROVIDER_URL\/\1\)/g" -e 's/\[\[#(.+)([0-9])\)]$/(\[#\1\2))/g' CHANGELOG.md 30 | 31 | rm CHANGELOG.md.bak 32 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/winrm/shell.go: -------------------------------------------------------------------------------- 1 | package winrm 2 | 3 | // Shell is the local view of a WinRM Shell of a given Client 4 | type Shell struct { 5 | client *Client 6 | id string 7 | } 8 | 9 | // Execute command on the given Shell, returning either an error or a Command 10 | func (s *Shell) Execute(command string, arguments ...string) (*Command, error) { 11 | request := NewExecuteCommandRequest(s.client.url, s.id, command, arguments, &s.client.Parameters) 12 | defer request.Free() 13 | 14 | response, err := s.client.sendRequest(request) 15 | if err != nil { 16 | return nil, err 17 | } 18 | 19 | commandID, err := ParseExecuteCommandResponse(response) 20 | if err != nil { 21 | return nil, err 22 | } 23 | 24 | cmd := newCommand(s, commandID) 25 | 26 | return cmd, nil 27 | } 28 | 29 | // Close will terminate this shell. No commands can be issued once the shell is closed. 30 | func (s *Shell) Close() error { 31 | request := NewDeleteShellRequest(s.client.url, s.id, &s.client.Parameters) 32 | defer request.Free() 33 | 34 | _, err := s.client.sendRequest(request) 35 | return err 36 | } 37 | -------------------------------------------------------------------------------- /website/docs/r/checkpoint.html.markdown: -------------------------------------------------------------------------------- 1 | --- 2 | layout: "scvmm" 3 | page_title: "Microsoft SCVMM: scvmm_checkpoint" 4 | sidebar_current: "docs-scvmm-resource-inventory-folder" 5 | description: |- 6 | Provides a SCVMM Checkpoint resource. This can be used to create and delete Checkpoint in Virtual Machine existing on SCVMM Server. 7 | --- 8 | 9 | # scvvm\_checkpoint 10 | 11 | Provides a SCVMM Checkpoint resource. This can be used to create and delete Checkpoint in Virtual Machine existing on SCVMM Server. It adds a checkpoint to virtual machine using a powershell script. 12 | 13 | ## Example Usage 14 | 15 | ```hcl 16 | resource "scvmm_checkpoint" "demoCheck" { 17 | timeout=1000 18 | vmm_server="${scvmm_virtual_disk.demoDisk.vmm_server}" 19 | vm_name="${scvmm_virtual_machine.CreateVM.vm_name}" 20 | checkpoint_name="demo_checkpoint" 21 | } 22 | ``` 23 | 24 | ## Argument Reference 25 | 26 | The following arguments are supported: 27 | 28 | * `timeout` - (Required) The time within which the specified resource should be created 29 | * `vmm_server` - (Required) The Virtual Machine Manager of the Virtual Machine 30 | * `vm_name` - (Required) The Virtual Machine Name to which the Virtual Disk will be attached 31 | * `checkpoint_name` - (Required) The Checkpoint name -------------------------------------------------------------------------------- /scvmm/provider_test.go: -------------------------------------------------------------------------------- 1 | package scvmm 2 | 3 | import ( 4 | "github.com/hashicorp/terraform/helper/schema" 5 | "github.com/hashicorp/terraform/terraform" 6 | "os" 7 | "testing" 8 | ) 9 | 10 | var testAccProviders map[string]terraform.ResourceProvider 11 | var testAccProvider *schema.Provider 12 | 13 | func init() { 14 | testAccProvider = Provider().(*schema.Provider) 15 | testAccProviders = map[string]terraform.ResourceProvider{ 16 | "scvmm": testAccProvider, 17 | } 18 | } 19 | 20 | func TestProvider(t *testing.T) { 21 | if err := Provider().(*schema.Provider).InternalValidate(); err != nil { 22 | t.Fatalf("err: %s", err) 23 | } 24 | } 25 | 26 | func TestProvider_impl(t *testing.T) { 27 | var _ terraform.ResourceProvider = Provider() 28 | } 29 | func testAccPreCheck(t *testing.T) { 30 | if v := os.Getenv("SCVMM_SERVER_IP"); v == "" { 31 | t.Fatal("SCVMM_SERVER_IP must be set for acceptance tests") 32 | } 33 | 34 | if v := os.Getenv("SCVMM_SERVER_PORT"); v == "" { 35 | t.Fatal("SCVMM_SERVER_PORT must be set for acceptance tests") 36 | } 37 | 38 | if v := os.Getenv("SCVMM_SERVER_USER"); v == "" { 39 | t.Fatal("SCVMM_SERVER_USER must be set for acceptance tests") 40 | } 41 | 42 | if v := os.Getenv("SCVMM_SERVER_PASSWORD"); v == "" { 43 | t.Fatal("SCVMM_SERVER_PASSWORD must be set for acceptance tests") 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/version1.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import ( 8 | "encoding/binary" 9 | ) 10 | 11 | // NewUUID returns a Version 1 UUID based on the current NodeID and clock 12 | // sequence, and the current time. If the NodeID has not been set by SetNodeID 13 | // or SetNodeInterface then it will be set automatically. If the NodeID cannot 14 | // be set NewUUID returns nil. If clock sequence has not been set by 15 | // SetClockSequence then it will be set automatically. If GetTime fails to 16 | // return the current NewUUID returns nil. 17 | func NewUUID() UUID { 18 | if nodeID == nil { 19 | SetNodeInterface("") 20 | } 21 | 22 | now, seq, err := GetTime() 23 | if err != nil { 24 | return nil 25 | } 26 | 27 | uuid := make([]byte, 16) 28 | 29 | time_low := uint32(now & 0xffffffff) 30 | time_mid := uint16((now >> 32) & 0xffff) 31 | time_hi := uint16((now >> 48) & 0x0fff) 32 | time_hi |= 0x1000 // Version 1 33 | 34 | binary.BigEndian.PutUint32(uuid[0:], time_low) 35 | binary.BigEndian.PutUint16(uuid[4:], time_mid) 36 | binary.BigEndian.PutUint16(uuid[6:], time_hi) 37 | binary.BigEndian.PutUint16(uuid[8:], seq) 38 | copy(uuid[10:], nodeID) 39 | 40 | return uuid 41 | } 42 | -------------------------------------------------------------------------------- /website/docs/r/virtual_disk.html.markdown: -------------------------------------------------------------------------------- 1 | --- 2 | layout: "scvmm" 3 | page_title: "Microsoft SCVMM: scvmm_virtual_disk" 4 | sidebar_current: "docs-scvmm-resource-inventory-folder" 5 | description: |- 6 | Provides a SCVMM Virtual Disk resource. This can be used to create and delete Virtual Disk in SCVMM Server. 7 | --- 8 | 9 | # scvvm\_virtual\_disk 10 | 11 | Provides a SCVMM Virtual Disk resource. This can be used to create and delete Virtual Disk in Virtual Machine existing in SCVMM. It adds a disk drive using a powershell script to the SCSI Adapter. 12 | 13 | ## Example Usage 14 | 15 | ```hcl 16 | resource "scvmm_virtual_disk" "demoDisk" { 17 | timeout = 10000 18 | vmm_server = "${scvmm_virtual_machine.CreateVM.vmm_server}" 19 | vm_name = "${scvmm_virtual_machine.CreateVM.vm_name}" 20 | virtual_disk_name = "demo_disk" 21 | virtual_disk_size = 10000 22 | } 23 | ``` 24 | 25 | ## Argument Reference 26 | 27 | The following arguments are supported: 28 | 29 | * `timeout` - (Required) The time within which the specified resource should be created 30 | * `vmm_server` - (Required) The Virtual Machine Manager of the Virtual Machine 31 | * `vm_name` - (Required) The Virtual Machine Name to which the Virtual Disk will be attached 32 | * `virtual_disk_name` - (Required) The Virtual Disk name 33 | * `virtual_disk_size` - (Required) The size of the Virtual Disk in Mega Bytes -------------------------------------------------------------------------------- /website/docs/r/virtual_machine.html.markdown: -------------------------------------------------------------------------------- 1 | --- 2 | layout: "scvmm" 3 | page_title: "Microsoft SCVMM: scvmm_virtual_machine" 4 | sidebar_current: "docs-scvmm-resource-inventory-folder" 5 | description: |- 6 | Provides a SCVMM Virtual Machine resource. This can be used to create and delete Virtual Machine in SCVMM Server. 7 | --- 8 | 9 | # scvvm\_virtual\_machine 10 | 11 | Provides a SCVMM Virtual Machine resource. This can be used to create and delete Virtual Machine from SCVMM. It does this by running script on remote machine which makes use of vmm server, vm name, cloud name and template name as parameters. 12 | 13 | ## Example Usage 14 | 15 | ```hcl 16 | resource "scvmm_virtual_machine" "CreateVM" { 17 | timeout = "10000" 18 | vmm_server = "WIN-2F929KU8HIU" 19 | vm_name = "Test_VM_demo01" 20 | template_name = "TestVMTemplate" 21 | cloud_name = "GSL Cloud" 22 | } 23 | ``` 24 | 25 | ## Argument Reference 26 | 27 | The following arguments are supported: 28 | 29 | * `timeout` - (Required) The time within which the specified resource should be created 30 | * `vmm_server` - (Required) The Virtual Machine Manager of the Virtual Machine 31 | * `vm_name` - (Required) The Virtual Machine Name 32 | * `template_name` - (Required) The template name containg all the configuration for Virtual Machine 33 | * `cloud_name` - (Required) The cloud in which the Virtual Machine should be created -------------------------------------------------------------------------------- /website/scvmm.erb: -------------------------------------------------------------------------------- 1 | <% wrap_layout :inner do %> 2 | <% content_for :sidebar do %> 3 | 29 | <% end %> 30 | <%= yield %> 31 | <% end %> -------------------------------------------------------------------------------- /tf-scvmm-devrc.mk.example: -------------------------------------------------------------------------------- 1 | # This file is designed to assist you with configuring your environment for 2 | # testing the Active Directory provider, and also serves as a catalog of the environment 3 | # variables that are required to test all of the resources in this provider. 4 | # 5 | # This should be copied to ~/.tf-ad-devrc.mk and edited accordingly. 6 | # 7 | # Note that the use of all of this file is not required - environment variables 8 | # can still be completely set from the command line or your existing 9 | # environment. In this case, don't use this file as it may cause conflicts. 10 | # 11 | # NOTE: Remove the annotations from any variables that have them inline, or 12 | # else make will add the whitespace to the variable as well. 13 | # 14 | # The essentials. None of the tests will run if you don't have these. 15 | export SCVMM_SERVER_IP ?= server.ip 16 | export SCVMM_SERVER_PORT ?= server.port 17 | export SCVMM_SERVER_USER ?= server.user 18 | export SCVMM_SERVER_PASSWORD ?= server.password 19 | 20 | # The following variables are shared across various tests. To ensure all tests 21 | # succeed, it's probably best to set all of these to valid values. 22 | export SCVMM_VMM_SERVER ?= scvmm-vmm-server # vmm server to be selected 23 | export SCVMM_TEMPLATE_NAME ?= scvmm-template-name # template to be used to create virtual machine 24 | export SCVMM_CLOUD_NAME ?= scvmm-cloud-name # cloud to be used 25 | # vi: filetype=make -------------------------------------------------------------------------------- /scvmm/config.go: -------------------------------------------------------------------------------- 1 | package scvmm 2 | 3 | import ( 4 | "fmt" 5 | "log" 6 | "strings" 7 | 8 | "github.com/masterzen/winrm" 9 | ) 10 | 11 | // Config ... SCVMM configuration details 12 | type Config struct { 13 | ServerIP string 14 | Port int 15 | Username string 16 | Password string 17 | } 18 | 19 | //Connection ... Create a new connection with winrm to Powershell. 20 | func (c *Config) Connection() (*winrm.Client, error) { 21 | 22 | endpoint := winrm.NewEndpoint(c.ServerIP, c.Port, false, false, nil, nil, nil, 0) 23 | winrmConnection, err := winrm.NewClient(endpoint, c.Username, c.Password) 24 | if err != nil { 25 | log.Printf("[ERROR] Failed to connect winrm: %v\n", err) 26 | return nil, err 27 | } 28 | 29 | shell, err := winrmConnection.CreateShell() 30 | if err != nil { 31 | log.Printf("[Error] While creating Shell %s", err) 32 | if strings.Contains(err.Error(), "http response error: 401") { 33 | return nil, fmt.Errorf("[Error] Please check whether username and password are correct.\n Error: %s", err.Error()) 34 | } else if strings.Contains(err.Error(), "unknown error Post") { 35 | return nil, fmt.Errorf("[Error] Please check whether server ip and port number are correct.\n Error: %s", err.Error()) 36 | } else { 37 | return nil, fmt.Errorf("[Error] While creating Shell %s", err) 38 | } 39 | } 40 | defer shell.Close() 41 | 42 | log.Printf("[DEBUG] Winrm connection successful") 43 | return winrmConnection, nil 44 | } 45 | -------------------------------------------------------------------------------- /vendor/vendor.json: -------------------------------------------------------------------------------- 1 | { 2 | "comment": "", 3 | "ignore": "test", 4 | "package": [ 5 | { 6 | "checksumSHA1": "t7hEeujQesCSzjZIPcE80XgQ9M0=", 7 | "path": "github.com/masterzen/azure-sdk-for-go/core/http", 8 | "revision": "ee4f0065d00cd12b542f18f5bc45799e88163b12", 9 | "revisionTime": "2016-10-14T13:56:28Z" 10 | }, 11 | { 12 | "checksumSHA1": "xJVMikTtYbfI2KqKeUXaO4292JU=", 13 | "path": "github.com/masterzen/azure-sdk-for-go/core/tls", 14 | "revision": "ee4f0065d00cd12b542f18f5bc45799e88163b12", 15 | "revisionTime": "2016-10-14T13:56:28Z" 16 | }, 17 | { 18 | "checksumSHA1": "yg57Q4J8Ob0LoYvqDxsWZ6AHffE=", 19 | "path": "github.com/masterzen/simplexml/dom", 20 | "revision": "4572e39b1ab9fe03ee513ce6fc7e289e98482190", 21 | "revisionTime": "2016-06-08T18:30:07Z" 22 | }, 23 | { 24 | "checksumSHA1": "8z5kCCFRsBkhXic9jxxeIV3bBn8=", 25 | "path": "github.com/masterzen/winrm", 26 | "revision": "a2df6b1315e6fd5885eb15c67ed259e85854125f", 27 | "revisionTime": "2017-08-14T13:39:27Z" 28 | }, 29 | { 30 | "checksumSHA1": "XFSXma+KmkhkIPsh4dTd/eyja5s=", 31 | "path": "github.com/masterzen/winrm/soap", 32 | "revision": "a2df6b1315e6fd5885eb15c67ed259e85854125f", 33 | "revisionTime": "2017-08-14T13:39:27Z" 34 | }, 35 | { 36 | "checksumSHA1": "Se195FlZ160eaEk/uVx4KdTPSxU=", 37 | "path": "github.com/pborman/uuid", 38 | "revision": "e790cca94e6cc75c7064b1332e63811d4aae1a53", 39 | "revisionTime": "2017-06-12T15:36:48Z" 40 | } 41 | ], 42 | "rootPath": "github.com/idmsubs/terraform-provider-scvmm" 43 | } 44 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009,2014 Google Inc. All rights reserved. 2 | 3 | Redistribution and use in source and binary forms, with or without 4 | modification, are permitted provided that the following conditions are 5 | met: 6 | 7 | * Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | * Redistributions in binary form must reproduce the above 10 | copyright notice, this list of conditions and the following disclaimer 11 | in the documentation and/or other materials provided with the 12 | distribution. 13 | * Neither the name of Google Inc. nor the names of its 14 | contributors may be used to endorse or promote products derived from 15 | this software without specific prior written permission. 16 | 17 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 18 | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 19 | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR 20 | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT 21 | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, 22 | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 23 | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 24 | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 25 | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 26 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 | -------------------------------------------------------------------------------- /GNUmakefile: -------------------------------------------------------------------------------- 1 | TEST?=$$(go list ./... |grep -v 'vendor') 2 | GOFMT_FILES?=$$(find . -name '*.go' |grep -v vendor) 3 | COVER_TEST?=$$(go list ./... |grep -v 'vendor') 4 | 5 | default: build 6 | 7 | build: fmtcheck 8 | go get 9 | go install 10 | 11 | test: fmtcheck 12 | go test -i $(TEST) || exit 1 13 | echo $(TEST) | \ 14 | xargs -t -n4 go test $(TESTARGS) -timeout=30s -parallel=4 15 | 16 | testacc: fmtcheck 17 | TF_ACC=1 go test $(TEST) -v $(TESTARGS) -timeout 120m 18 | 19 | testrace: fmtcheck 20 | TF_ACC= go test -race $(TEST) $(TESTARGS) 21 | 22 | cover: 23 | @go tool cover 2>/dev/null; if [ $$? -eq 3 ]; then \ 24 | go get -u golang.org/x/tools/cmd/cover; \ 25 | fi 26 | go test $(COVER_TEST) -coverprofile=coverage.out 27 | go tool cover -html=coverage.out 28 | rm coverage.out 29 | 30 | vet: 31 | @echo "go vet ." 32 | @go vet $$(go list ./... | grep -v vendor/) ; if [ $$? -eq 1 ]; then \ 33 | echo ""; \ 34 | echo "Vet found suspicious constructs. Please check the reported constructs"; \ 35 | echo "and fix them if necessary before submitting the code for review."; \ 36 | exit 1; \ 37 | fi 38 | 39 | fmt: 40 | gofmt -w $(GOFMT_FILES) 41 | 42 | fmtcheck: 43 | @sh -c "'$(CURDIR)/scripts/gofmtcheck.sh'" 44 | 45 | errcheck: 46 | @sh -c "'$(CURDIR)/scripts/errcheck.sh'" 47 | 48 | vendor-status: 49 | @govendor status 50 | 51 | test-compile: fmtcheck 52 | @if [ "$(TEST)" = "./..." ]; then \ 53 | echo "ERROR: Set TEST to a specific package. For example,"; \ 54 | echo " make test-compile TEST=./aws"; \ 55 | exit 1; \ 56 | fi 57 | go test -c $(TEST) $(TESTARGS) 58 | 59 | .PHONY: build test testacc testrace cover vet fmt fmtcheck errcheck vendor-status test-compile 60 | -------------------------------------------------------------------------------- /scvmm/provider.go: -------------------------------------------------------------------------------- 1 | package scvmm 2 | 3 | import ( 4 | "log" 5 | 6 | "github.com/hashicorp/terraform/helper/schema" 7 | "github.com/hashicorp/terraform/terraform" 8 | ) 9 | 10 | // Provider ... provides scvmm capability to terraform 11 | func Provider() terraform.ResourceProvider { 12 | return &schema.Provider{ 13 | Schema: map[string]*schema.Schema{ 14 | "server_ip": { 15 | Type: schema.TypeString, 16 | Required: true, 17 | Description: "SCVMM Server IP", 18 | DefaultFunc: schema.EnvDefaultFunc("SCVMM_SERVER_IP", nil), 19 | }, 20 | "port": { 21 | Type: schema.TypeInt, 22 | Required: true, 23 | Description: "Server Port", 24 | DefaultFunc: schema.EnvDefaultFunc("SCVMM_SERVER_PORT", nil), 25 | }, 26 | "user_name": { 27 | Type: schema.TypeString, 28 | Required: true, 29 | Description: "User name", 30 | DefaultFunc: schema.EnvDefaultFunc("SCVMM_SERVER_USER", nil), 31 | }, 32 | "user_password": { 33 | Type: schema.TypeString, 34 | Required: true, 35 | Description: "Password for provided user_name", 36 | DefaultFunc: schema.EnvDefaultFunc("SCVMM_SERVER_PASSWORD", nil), 37 | }, 38 | }, 39 | ResourcesMap: map[string]*schema.Resource{ 40 | "scvmm_virtual_machine": resourceSCVMMVirtualMachine(), 41 | "scvmm_virtual_disk": resourceSCVMMVirtualDisk(), 42 | "scvmm_checkpoint": resourceSCVMMCheckpoint(), 43 | }, 44 | ConfigureFunc: providerConfigure, 45 | } 46 | } 47 | 48 | func providerConfigure(d *schema.ResourceData) (interface{}, error) { 49 | config := Config{ 50 | ServerIP: d.Get("server_ip").(string), 51 | Port: d.Get("port").(int), 52 | Username: d.Get("user_name").(string), 53 | Password: d.Get("user_password").(string), 54 | } 55 | 56 | log.Println("[DEBUG] Initializing Winrm Connection") 57 | return config.Connection() 58 | } 59 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/azure-sdk-for-go/core/http/lex.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package http 6 | 7 | // This file deals with lexical matters of HTTP 8 | 9 | var isTokenTable = [127]bool{ 10 | '!': true, 11 | '#': true, 12 | '$': true, 13 | '%': true, 14 | '&': true, 15 | '\'': true, 16 | '*': true, 17 | '+': true, 18 | '-': true, 19 | '.': true, 20 | '0': true, 21 | '1': true, 22 | '2': true, 23 | '3': true, 24 | '4': true, 25 | '5': true, 26 | '6': true, 27 | '7': true, 28 | '8': true, 29 | '9': true, 30 | 'A': true, 31 | 'B': true, 32 | 'C': true, 33 | 'D': true, 34 | 'E': true, 35 | 'F': true, 36 | 'G': true, 37 | 'H': true, 38 | 'I': true, 39 | 'J': true, 40 | 'K': true, 41 | 'L': true, 42 | 'M': true, 43 | 'N': true, 44 | 'O': true, 45 | 'P': true, 46 | 'Q': true, 47 | 'R': true, 48 | 'S': true, 49 | 'T': true, 50 | 'U': true, 51 | 'W': true, 52 | 'V': true, 53 | 'X': true, 54 | 'Y': true, 55 | 'Z': true, 56 | '^': true, 57 | '_': true, 58 | '`': true, 59 | 'a': true, 60 | 'b': true, 61 | 'c': true, 62 | 'd': true, 63 | 'e': true, 64 | 'f': true, 65 | 'g': true, 66 | 'h': true, 67 | 'i': true, 68 | 'j': true, 69 | 'k': true, 70 | 'l': true, 71 | 'm': true, 72 | 'n': true, 73 | 'o': true, 74 | 'p': true, 75 | 'q': true, 76 | 'r': true, 77 | 's': true, 78 | 't': true, 79 | 'u': true, 80 | 'v': true, 81 | 'w': true, 82 | 'x': true, 83 | 'y': true, 84 | 'z': true, 85 | '|': true, 86 | '~': true, 87 | } 88 | 89 | func isToken(r rune) bool { 90 | i := int(r) 91 | return i < len(isTokenTable) && isTokenTable[i] 92 | } 93 | 94 | func isNotToken(r rune) bool { 95 | return !isToken(r) 96 | } 97 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/sql.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import ( 8 | "database/sql/driver" 9 | "errors" 10 | "fmt" 11 | ) 12 | 13 | // Scan implements sql.Scanner so UUIDs can be read from databases transparently 14 | // Currently, database types that map to string and []byte are supported. Please 15 | // consult database-specific driver documentation for matching types. 16 | func (uuid *UUID) Scan(src interface{}) error { 17 | switch src.(type) { 18 | case string: 19 | // if an empty UUID comes from a table, we return a null UUID 20 | if src.(string) == "" { 21 | return nil 22 | } 23 | 24 | // see uuid.Parse for required string format 25 | parsed := Parse(src.(string)) 26 | 27 | if parsed == nil { 28 | return errors.New("Scan: invalid UUID format") 29 | } 30 | 31 | *uuid = parsed 32 | case []byte: 33 | b := src.([]byte) 34 | 35 | // if an empty UUID comes from a table, we return a null UUID 36 | if len(b) == 0 { 37 | return nil 38 | } 39 | 40 | // assumes a simple slice of bytes if 16 bytes 41 | // otherwise attempts to parse 42 | if len(b) == 16 { 43 | *uuid = UUID(b) 44 | } else { 45 | u := Parse(string(b)) 46 | 47 | if u == nil { 48 | return errors.New("Scan: invalid UUID format") 49 | } 50 | 51 | *uuid = u 52 | } 53 | 54 | default: 55 | return fmt.Errorf("Scan: unable to scan type %T into UUID", src) 56 | } 57 | 58 | return nil 59 | } 60 | 61 | // Value implements sql.Valuer so that UUIDs can be written to databases 62 | // transparently. Currently, UUIDs map to strings. Please consult 63 | // database-specific driver documentation for matching types. 64 | func (uuid UUID) Value() (driver.Value, error) { 65 | return uuid.String(), nil 66 | } 67 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/hash.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import ( 8 | "crypto/md5" 9 | "crypto/sha1" 10 | "hash" 11 | ) 12 | 13 | // Well known Name Space IDs and UUIDs 14 | var ( 15 | NameSpace_DNS = Parse("6ba7b810-9dad-11d1-80b4-00c04fd430c8") 16 | NameSpace_URL = Parse("6ba7b811-9dad-11d1-80b4-00c04fd430c8") 17 | NameSpace_OID = Parse("6ba7b812-9dad-11d1-80b4-00c04fd430c8") 18 | NameSpace_X500 = Parse("6ba7b814-9dad-11d1-80b4-00c04fd430c8") 19 | NIL = Parse("00000000-0000-0000-0000-000000000000") 20 | ) 21 | 22 | // NewHash returns a new UUID derived from the hash of space concatenated with 23 | // data generated by h. The hash should be at least 16 byte in length. The 24 | // first 16 bytes of the hash are used to form the UUID. The version of the 25 | // UUID will be the lower 4 bits of version. NewHash is used to implement 26 | // NewMD5 and NewSHA1. 27 | func NewHash(h hash.Hash, space UUID, data []byte, version int) UUID { 28 | h.Reset() 29 | h.Write(space) 30 | h.Write([]byte(data)) 31 | s := h.Sum(nil) 32 | uuid := make([]byte, 16) 33 | copy(uuid, s) 34 | uuid[6] = (uuid[6] & 0x0f) | uint8((version&0xf)<<4) 35 | uuid[8] = (uuid[8] & 0x3f) | 0x80 // RFC 4122 variant 36 | return uuid 37 | } 38 | 39 | // NewMD5 returns a new MD5 (Version 3) UUID based on the 40 | // supplied name space and data. 41 | // 42 | // NewHash(md5.New(), space, data, 3) 43 | func NewMD5(space UUID, data []byte) UUID { 44 | return NewHash(md5.New(), space, data, 3) 45 | } 46 | 47 | // NewSHA1 returns a new SHA1 (Version 5) UUID based on the 48 | // supplied name space and data. 49 | // 50 | // NewHash(sha1.New(), space, data, 5) 51 | func NewSHA1(space UUID, data []byte) UUID { 52 | return NewHash(sha1.New(), space, data, 5) 53 | } 54 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/winrm/endpoint.go: -------------------------------------------------------------------------------- 1 | package winrm 2 | 3 | import ( 4 | "fmt" 5 | "time" 6 | ) 7 | 8 | // Endpoint struct holds configurations 9 | // for the server endpoint 10 | type Endpoint struct { 11 | // host name or ip address 12 | Host string 13 | // port to determine if it's http or https default 14 | // winrm ports (http:5985, https:5986).Versions 15 | // of winrm can be customized to listen on other ports 16 | Port int 17 | // set the flag true for https connections 18 | HTTPS bool 19 | // set the flag true for skipping ssl verifications 20 | Insecure bool 21 | // if set, used to verify the hostname on the returned certificate 22 | TLSServerName string 23 | // pointer pem certs, and key 24 | CACert []byte // cert auth to intdetify the server cert 25 | Key []byte // public key for client auth connections 26 | Cert []byte // cert for client auth connections 27 | // duration timeout for the underling tcp conn(http/https base protocol) 28 | // if the time exceeds the connection is cloded/timeouts 29 | Timeout time.Duration 30 | } 31 | 32 | func (ep *Endpoint) url() string { 33 | var scheme string 34 | if ep.HTTPS { 35 | scheme = "https" 36 | } else { 37 | scheme = "http" 38 | } 39 | 40 | return fmt.Sprintf("%s://%s:%d/wsman", scheme, ep.Host, ep.Port) 41 | } 42 | 43 | // NewEndpoint returns new pointer to struct Endpoint, with a default 60s response header timeout 44 | func NewEndpoint(host string, port int, https bool, insecure bool, Cacert, cert, key []byte, timeout time.Duration) *Endpoint { 45 | endpoint := &Endpoint{ 46 | Host: host, 47 | Port: port, 48 | HTTPS: https, 49 | Insecure: insecure, 50 | CACert: Cacert, 51 | Key: key, 52 | Cert: cert, 53 | } 54 | // if the timeout was set 55 | if timeout != 0 { 56 | endpoint.Timeout = timeout 57 | } else { 58 | // assign default 60sec timeout 59 | endpoint.Timeout = 60 * time.Second 60 | } 61 | 62 | return endpoint 63 | } 64 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/winrm/soap/message.go: -------------------------------------------------------------------------------- 1 | package soap 2 | 3 | import ( 4 | "github.com/masterzen/simplexml/dom" 5 | ) 6 | 7 | type SoapMessage struct { 8 | document *dom.Document 9 | envelope *dom.Element 10 | header *SoapHeader 11 | body *dom.Element 12 | } 13 | 14 | type MessageBuilder interface { 15 | SetBody(*dom.Element) 16 | NewBody() *dom.Element 17 | CreateElement(*dom.Element, string, dom.Namespace) *dom.Element 18 | CreateBodyElement(string, dom.Namespace) *dom.Element 19 | Header() *SoapHeader 20 | Doc() *dom.Document 21 | Free() 22 | String() string 23 | } 24 | 25 | func NewMessage() (message *SoapMessage) { 26 | doc := dom.CreateDocument() 27 | e := dom.CreateElement("Envelope") 28 | doc.SetRoot(e) 29 | AddUsualNamespaces(e) 30 | DOM_NS_SOAP_ENV.SetTo(e) 31 | 32 | message = &SoapMessage{document: doc, envelope: e} 33 | return 34 | } 35 | 36 | func (message *SoapMessage) NewBody() (body *dom.Element) { 37 | body = dom.CreateElement("Body") 38 | message.envelope.AddChild(body) 39 | DOM_NS_SOAP_ENV.SetTo(body) 40 | return 41 | } 42 | 43 | func (message *SoapMessage) String() string { 44 | return message.document.String() 45 | } 46 | 47 | func (message *SoapMessage) Doc() *dom.Document { 48 | return message.document 49 | } 50 | 51 | func (message *SoapMessage) Free() { 52 | } 53 | 54 | func (message *SoapMessage) CreateElement(parent *dom.Element, name string, ns dom.Namespace) (element *dom.Element) { 55 | element = dom.CreateElement(name) 56 | parent.AddChild(element) 57 | ns.SetTo(element) 58 | return 59 | } 60 | 61 | func (message *SoapMessage) CreateBodyElement(name string, ns dom.Namespace) (element *dom.Element) { 62 | if message.body == nil { 63 | message.body = message.NewBody() 64 | } 65 | return message.CreateElement(message.body, name, ns) 66 | } 67 | 68 | func (message *SoapMessage) Header() *SoapHeader { 69 | if message.header == nil { 70 | message.header = &SoapHeader{message: message} 71 | } 72 | return message.header 73 | } 74 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/util.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import ( 8 | "io" 9 | ) 10 | 11 | // randomBits completely fills slice b with random data. 12 | func randomBits(b []byte) { 13 | if _, err := io.ReadFull(rander, b); err != nil { 14 | panic(err.Error()) // rand should never fail 15 | } 16 | } 17 | 18 | // xvalues returns the value of a byte as a hexadecimal digit or 255. 19 | var xvalues = [256]byte{ 20 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 21 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 22 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 23 | 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 255, 255, 255, 255, 255, 255, 24 | 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, 25 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 26 | 255, 10, 11, 12, 13, 14, 15, 255, 255, 255, 255, 255, 255, 255, 255, 255, 27 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 28 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 29 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 30 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 31 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 32 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 33 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 34 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 35 | 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 36 | } 37 | 38 | // xtob converts the the first two hex bytes of x into a byte. 39 | func xtob(x string) (byte, bool) { 40 | b1 := xvalues[x[0]] 41 | b2 := xvalues[x[1]] 42 | return (b1 << 4) | b2, b1 != 255 && b2 != 255 43 | } 44 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/marshal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2016 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import ( 8 | "errors" 9 | "fmt" 10 | ) 11 | 12 | // MarshalText implements encoding.TextMarshaler. 13 | func (u UUID) MarshalText() ([]byte, error) { 14 | if len(u) != 16 { 15 | return nil, nil 16 | } 17 | var js [36]byte 18 | encodeHex(js[:], u) 19 | return js[:], nil 20 | } 21 | 22 | // UnmarshalText implements encoding.TextUnmarshaler. 23 | func (u *UUID) UnmarshalText(data []byte) error { 24 | if len(data) == 0 { 25 | return nil 26 | } 27 | id := Parse(string(data)) 28 | if id == nil { 29 | return errors.New("invalid UUID") 30 | } 31 | *u = id 32 | return nil 33 | } 34 | 35 | // MarshalBinary implements encoding.BinaryMarshaler. 36 | func (u UUID) MarshalBinary() ([]byte, error) { 37 | return u[:], nil 38 | } 39 | 40 | // UnmarshalBinary implements encoding.BinaryUnmarshaler. 41 | func (u *UUID) UnmarshalBinary(data []byte) error { 42 | if len(data) == 0 { 43 | return nil 44 | } 45 | if len(data) != 16 { 46 | return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) 47 | } 48 | var id [16]byte 49 | copy(id[:], data) 50 | *u = id[:] 51 | return nil 52 | } 53 | 54 | // MarshalText implements encoding.TextMarshaler. 55 | func (u Array) MarshalText() ([]byte, error) { 56 | var js [36]byte 57 | encodeHex(js[:], u[:]) 58 | return js[:], nil 59 | } 60 | 61 | // UnmarshalText implements encoding.TextUnmarshaler. 62 | func (u *Array) UnmarshalText(data []byte) error { 63 | id := Parse(string(data)) 64 | if id == nil { 65 | return errors.New("invalid UUID") 66 | } 67 | *u = id.Array() 68 | return nil 69 | } 70 | 71 | // MarshalBinary implements encoding.BinaryMarshaler. 72 | func (u Array) MarshalBinary() ([]byte, error) { 73 | return u[:], nil 74 | } 75 | 76 | // UnmarshalBinary implements encoding.BinaryUnmarshaler. 77 | func (u *Array) UnmarshalBinary(data []byte) error { 78 | if len(data) != 16 { 79 | return fmt.Errorf("invalid UUID (got %d bytes)", len(data)) 80 | } 81 | copy(u[:], data) 82 | return nil 83 | } 84 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/dce.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import ( 8 | "encoding/binary" 9 | "fmt" 10 | "os" 11 | ) 12 | 13 | // A Domain represents a Version 2 domain 14 | type Domain byte 15 | 16 | // Domain constants for DCE Security (Version 2) UUIDs. 17 | const ( 18 | Person = Domain(0) 19 | Group = Domain(1) 20 | Org = Domain(2) 21 | ) 22 | 23 | // NewDCESecurity returns a DCE Security (Version 2) UUID. 24 | // 25 | // The domain should be one of Person, Group or Org. 26 | // On a POSIX system the id should be the users UID for the Person 27 | // domain and the users GID for the Group. The meaning of id for 28 | // the domain Org or on non-POSIX systems is site defined. 29 | // 30 | // For a given domain/id pair the same token may be returned for up to 31 | // 7 minutes and 10 seconds. 32 | func NewDCESecurity(domain Domain, id uint32) UUID { 33 | uuid := NewUUID() 34 | if uuid != nil { 35 | uuid[6] = (uuid[6] & 0x0f) | 0x20 // Version 2 36 | uuid[9] = byte(domain) 37 | binary.BigEndian.PutUint32(uuid[0:], id) 38 | } 39 | return uuid 40 | } 41 | 42 | // NewDCEPerson returns a DCE Security (Version 2) UUID in the person 43 | // domain with the id returned by os.Getuid. 44 | // 45 | // NewDCEPerson(Person, uint32(os.Getuid())) 46 | func NewDCEPerson() UUID { 47 | return NewDCESecurity(Person, uint32(os.Getuid())) 48 | } 49 | 50 | // NewDCEGroup returns a DCE Security (Version 2) UUID in the group 51 | // domain with the id returned by os.Getgid. 52 | // 53 | // NewDCEGroup(Group, uint32(os.Getgid())) 54 | func NewDCEGroup() UUID { 55 | return NewDCESecurity(Group, uint32(os.Getgid())) 56 | } 57 | 58 | // Domain returns the domain for a Version 2 UUID or false. 59 | func (uuid UUID) Domain() (Domain, bool) { 60 | if v, _ := uuid.Version(); v != 2 { 61 | return 0, false 62 | } 63 | return Domain(uuid[9]), true 64 | } 65 | 66 | // Id returns the id for a Version 2 UUID or false. 67 | func (uuid UUID) Id() (uint32, bool) { 68 | if v, _ := uuid.Version(); v != 2 { 69 | return 0, false 70 | } 71 | return binary.BigEndian.Uint32(uuid[0:4]), true 72 | } 73 | 74 | func (d Domain) String() string { 75 | switch d { 76 | case Person: 77 | return "Person" 78 | case Group: 79 | return "Group" 80 | case Org: 81 | return "Org" 82 | } 83 | return fmt.Sprintf("Domain%d", int(d)) 84 | } 85 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/azure-sdk-for-go/core/http/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | /* 6 | Package http provides HTTP client and server implementations. 7 | 8 | Get, Head, Post, and PostForm make HTTP (or HTTPS) requests: 9 | 10 | resp, err := http.Get("http://example.com/") 11 | ... 12 | resp, err := http.Post("http://example.com/upload", "image/jpeg", &buf) 13 | ... 14 | resp, err := http.PostForm("http://example.com/form", 15 | url.Values{"key": {"Value"}, "id": {"123"}}) 16 | 17 | The client must close the response body when finished with it: 18 | 19 | resp, err := http.Get("http://example.com/") 20 | if err != nil { 21 | // handle error 22 | } 23 | defer resp.Body.Close() 24 | body, err := ioutil.ReadAll(resp.Body) 25 | // ... 26 | 27 | For control over HTTP client headers, redirect policy, and other 28 | settings, create a Client: 29 | 30 | client := &http.Client{ 31 | CheckRedirect: redirectPolicyFunc, 32 | } 33 | 34 | resp, err := client.Get("http://example.com") 35 | // ... 36 | 37 | req, err := http.NewRequest("GET", "http://example.com", nil) 38 | // ... 39 | req.Header.Add("If-None-Match", `W/"wyzzy"`) 40 | resp, err := client.Do(req) 41 | // ... 42 | 43 | For control over proxies, TLS configuration, keep-alives, 44 | compression, and other settings, create a Transport: 45 | 46 | tr := &http.Transport{ 47 | TLSClientConfig: &tls.Config{RootCAs: pool}, 48 | DisableCompression: true, 49 | } 50 | client := &http.Client{Transport: tr} 51 | resp, err := client.Get("https://example.com") 52 | 53 | Clients and Transports are safe for concurrent use by multiple 54 | goroutines and for efficiency should only be created once and re-used. 55 | 56 | ListenAndServe starts an HTTP server with a given address and handler. 57 | The handler is usually nil, which means to use DefaultServeMux. 58 | Handle and HandleFunc add handlers to DefaultServeMux: 59 | 60 | http.Handle("/foo", fooHandler) 61 | 62 | http.HandleFunc("/bar", func(w http.ResponseWriter, r *http.Request) { 63 | fmt.Fprintf(w, "Hello, %q", html.EscapeString(r.URL.Path)) 64 | }) 65 | 66 | log.Fatal(http.ListenAndServe(":8080", nil)) 67 | 68 | More control over the server's behavior is available by creating a 69 | custom Server: 70 | 71 | s := &http.Server{ 72 | Addr: ":8080", 73 | Handler: myHandler, 74 | ReadTimeout: 10 * time.Second, 75 | WriteTimeout: 10 * time.Second, 76 | MaxHeaderBytes: 1 << 20, 77 | } 78 | log.Fatal(s.ListenAndServe()) 79 | */ 80 | package http 81 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/azure-sdk-for-go/core/tls/alert.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package tls 6 | 7 | import "strconv" 8 | 9 | type alert uint8 10 | 11 | const ( 12 | // alert level 13 | alertLevelWarning = 1 14 | alertLevelError = 2 15 | ) 16 | 17 | const ( 18 | alertCloseNotify alert = 0 19 | alertUnexpectedMessage alert = 10 20 | alertBadRecordMAC alert = 20 21 | alertDecryptionFailed alert = 21 22 | alertRecordOverflow alert = 22 23 | alertDecompressionFailure alert = 30 24 | alertHandshakeFailure alert = 40 25 | alertBadCertificate alert = 42 26 | alertUnsupportedCertificate alert = 43 27 | alertCertificateRevoked alert = 44 28 | alertCertificateExpired alert = 45 29 | alertCertificateUnknown alert = 46 30 | alertIllegalParameter alert = 47 31 | alertUnknownCA alert = 48 32 | alertAccessDenied alert = 49 33 | alertDecodeError alert = 50 34 | alertDecryptError alert = 51 35 | alertProtocolVersion alert = 70 36 | alertInsufficientSecurity alert = 71 37 | alertInternalError alert = 80 38 | alertUserCanceled alert = 90 39 | alertNoRenegotiation alert = 100 40 | ) 41 | 42 | var alertText = map[alert]string{ 43 | alertCloseNotify: "close notify", 44 | alertUnexpectedMessage: "unexpected message", 45 | alertBadRecordMAC: "bad record MAC", 46 | alertDecryptionFailed: "decryption failed", 47 | alertRecordOverflow: "record overflow", 48 | alertDecompressionFailure: "decompression failure", 49 | alertHandshakeFailure: "handshake failure", 50 | alertBadCertificate: "bad certificate", 51 | alertUnsupportedCertificate: "unsupported certificate", 52 | alertCertificateRevoked: "revoked certificate", 53 | alertCertificateExpired: "expired certificate", 54 | alertCertificateUnknown: "unknown certificate", 55 | alertIllegalParameter: "illegal parameter", 56 | alertUnknownCA: "unknown certificate authority", 57 | alertAccessDenied: "access denied", 58 | alertDecodeError: "error decoding message", 59 | alertDecryptError: "error decrypting message", 60 | alertProtocolVersion: "protocol version not supported", 61 | alertInsufficientSecurity: "insufficient security level", 62 | alertInternalError: "internal error", 63 | alertUserCanceled: "user canceled", 64 | alertNoRenegotiation: "no renegotiation", 65 | } 66 | 67 | func (e alert) String() string { 68 | s, ok := alertText[e] 69 | if ok { 70 | return s 71 | } 72 | return "alert(" + strconv.Itoa(int(e)) + ")" 73 | } 74 | 75 | func (e alert) Error() string { 76 | return e.String() 77 | } 78 | -------------------------------------------------------------------------------- /scvmm/validation_library.go: -------------------------------------------------------------------------------- 1 | package scvmm 2 | 3 | import ( 4 | "fmt" 5 | "regexp" 6 | "strconv" 7 | 8 | "github.com/pborman/uuid" 9 | ) 10 | 11 | func validateTimeout(v interface{}, k string) (warnings []string, errors []error) { 12 | timeoutString := v.(string) 13 | _, err := strconv.ParseInt(timeoutString, 10, 64) 14 | if err != nil { 15 | return returnError("Timeout should be a natural number with base 10", err) 16 | } 17 | return nil, nil 18 | } 19 | 20 | func validateVirtualMachineName(v interface{}, k string) (warnings []string, errors []error) { 21 | virtualMachineName := v.(string) 22 | match, err := regexp.MatchString("^[^*?:<>|/[\\]]+$", virtualMachineName) 23 | if err != nil { 24 | return returnError("Regex error: Please report bug to terraform", err) 25 | } 26 | if !match { 27 | return returnError("VM Name should not contain special chars (^*?:<>|/\\).", fmt.Errorf("VM Name is not correct")) 28 | } 29 | return nil, nil 30 | } 31 | 32 | func validateTemplateName(v interface{}, k string) (warnings []string, errors []error) { 33 | templateName := v.(string) 34 | match, err := regexp.MatchString("^[^*?:<>|/[\\]]+$", templateName) 35 | if err != nil { 36 | return returnError("Regex error: Please report bug to terraform", err) 37 | } 38 | if !match { 39 | return returnError("Template Name should not contain special chars (^*?:<>|/\\).", fmt.Errorf("Template Name is not correct")) 40 | } 41 | return nil, nil 42 | } 43 | 44 | func validateVMMServer(v interface{}, k string) (warnings []string, errors []error) { 45 | vmmServerName := v.(string) 46 | match, err := regexp.MatchString("^[\\w\\d.\\-_]+$", vmmServerName) 47 | if err != nil { 48 | return returnError("Regex error: Please report bug to terraform", err) 49 | } 50 | if !match { 51 | return returnError("Name should not contain special chars (^*?:<>|/\\).", fmt.Errorf("VMMServer Name is not correct")) 52 | } 53 | return nil, nil 54 | } 55 | 56 | func validateCloudName(v interface{}, k string) (warnings []string, errors []error) { 57 | cloudName := v.(string) 58 | match, err := regexp.MatchString("^[\\w\\s\\d.\\-_]+$", cloudName) 59 | if err != nil { 60 | return returnError("Regex error: Please report bug to terraform", err) 61 | } 62 | if !match { 63 | return returnError("Cloud Name should not contain special chars (^*?:<>|/\\).", fmt.Errorf("Cloud Name Name is not correct")) 64 | } 65 | return nil, nil 66 | } 67 | 68 | func validateGUID(v interface{}, k string) (warnings []string, errors []error) { 69 | input := v.(string) 70 | uuid := uuid.Parse(input) 71 | if uuid == nil { 72 | return returnError("GUID is not correct, it should be in format xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx", fmt.Errorf("GUID is not correct")) 73 | } 74 | return nil, nil 75 | } 76 | 77 | func returnError(message string, err error) (warnings []string, errors []error) { 78 | var errorVar []error 79 | var warningVar []string 80 | return append(warningVar, message), append(errorVar, err) 81 | } 82 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/winrm/http.go: -------------------------------------------------------------------------------- 1 | package winrm 2 | 3 | import ( 4 | "crypto/tls" 5 | "fmt" 6 | "io/ioutil" 7 | "net" 8 | "net/http" 9 | "strings" 10 | "time" 11 | 12 | "github.com/masterzen/winrm/soap" 13 | ) 14 | 15 | var soapXML = "application/soap+xml" 16 | 17 | // body func reads the response body and return it as a string 18 | func body(response *http.Response) (string, error) { 19 | 20 | // if we recived the content we expected 21 | if strings.Contains(response.Header.Get("Content-Type"), "application/soap+xml") { 22 | body, err := ioutil.ReadAll(response.Body) 23 | defer func() { 24 | // defer can modify the returned value before 25 | // it is actually passed to the calling statement 26 | if errClose := response.Body.Close(); errClose != nil && err == nil { 27 | err = errClose 28 | } 29 | }() 30 | if err != nil { 31 | return "", fmt.Errorf("error while reading request body %s", err) 32 | } 33 | 34 | return string(body), nil 35 | } 36 | 37 | return "", fmt.Errorf("invalid content type") 38 | } 39 | 40 | type clientRequest struct { 41 | transport http.RoundTripper 42 | } 43 | 44 | func (c *clientRequest) Transport(endpoint *Endpoint) error { 45 | transport := &http.Transport{ 46 | Proxy: http.ProxyFromEnvironment, 47 | TLSClientConfig: &tls.Config{ 48 | InsecureSkipVerify: endpoint.Insecure, 49 | ServerName: endpoint.TLSServerName, 50 | }, 51 | Dial: (&net.Dialer{ 52 | Timeout: 30 * time.Second, 53 | KeepAlive: 30 * time.Second, 54 | }).Dial, 55 | ResponseHeaderTimeout: endpoint.Timeout, 56 | } 57 | 58 | if endpoint.CACert != nil && len(endpoint.CACert) > 0 { 59 | certPool, err := readCACerts(endpoint.CACert) 60 | if err != nil { 61 | return err 62 | } 63 | 64 | transport.TLSClientConfig.RootCAs = certPool 65 | } 66 | 67 | c.transport = transport 68 | 69 | return nil 70 | } 71 | 72 | // Post make post to the winrm soap service 73 | func (c clientRequest) Post(client *Client, request *soap.SoapMessage) (string, error) { 74 | httpClient := &http.Client{Transport: c.transport} 75 | 76 | req, err := http.NewRequest("POST", client.url, strings.NewReader(request.String())) 77 | if err != nil { 78 | return "", fmt.Errorf("impossible to create http request %s", err) 79 | } 80 | req.Header.Set("Content-Type", soapXML+";charset=UTF-8") 81 | req.SetBasicAuth(client.username, client.password) 82 | resp, err := httpClient.Do(req) 83 | if err != nil { 84 | return "", fmt.Errorf("unknown error %s", err) 85 | } 86 | 87 | body, err := body(resp) 88 | if err != nil { 89 | return "", fmt.Errorf("http response error: %d - %s", resp.StatusCode, err.Error()) 90 | } 91 | 92 | // if we have different 200 http status code 93 | // we must replace the error 94 | defer func() { 95 | if resp.StatusCode != 200 { 96 | body, err = "", fmt.Errorf("http error %d: %s", resp.StatusCode, body) 97 | } 98 | }() 99 | 100 | return body, err 101 | } 102 | -------------------------------------------------------------------------------- /website/docs/index.html.markdown: -------------------------------------------------------------------------------- 1 | --- 2 | layout: "scvmm" 3 | page_title: "Provider: SCVMM" 4 | sidebar_current: "docs-scvmm-index" 5 | description: |- 6 | The SCVMM provider is used to interact with the resources supported by 7 | Microsoft SCVMM. The provider needs to be configured with the proper credentials 8 | before it can be used. 9 | --- 10 | 11 | # SCVMM Provider 12 | 13 | The SCVMM provider is used to interact with the resources supported by 14 | SCVMM. 15 | The provider needs to be configured with the proper credentials before it can be used. 16 | 17 | Use the navigation to the left to read about the available resources. 18 | 19 | ~> **NOTE:** The SCVMM Provider currently represents _initial support_ 20 | and therefore may undergo significant changes as the community improves it. This 21 | provider at this time only supports adding Virtual Machine, Virtual Disk and Checkpoint Resource 22 | 23 | ## Example Usage 24 | 25 | ```hcl 26 | # Configure the Microsoft SCVMM Provider 27 | provider "scvmm" { 28 | server_ip = "${var.scvmm_server_ip}" 29 | port = ${var.scvmm_server_port} 30 | user_name = "${var.scvmm_server_user}" 31 | user_password = "${var.scvmm_server_password}" 32 | } 33 | 34 | # Add a Virtual Machine 35 | resource "scvmm_virtual_machine" "CreateVM" { 36 | timeout = "10000" 37 | vmm_server = "WIN-2F929KU8HIU" 38 | vm_name = "Test_VM_demo01" 39 | template_name = "TestVMTemplate" 40 | cloud_name = "GSL Cloud" 41 | } 42 | 43 | #Add a Virtual Disk 44 | resource "scvmm_virtual_disk" "demoDisk" { 45 | timeout = 10000 46 | vmm_server = "${scvmm_virtual_machine.CreateVM.vmm_server}" 47 | vm_name = "${scvmm_virtual_machine.CreateVM.vm_name}" 48 | virtual_disk_name = "demo_disk" 49 | virtual_disk_size = 10000 50 | } 51 | 52 | resource "scvmm_checkpoint" "demoCheck" { 53 | timeout=1000 54 | vmm_server="${scvmm_virtual_disk.demoDisk.vmm_server}" 55 | vm_name="${scvmm_virtual_machine.CreateVM.vm_name}" 56 | checkpoint_name="demo_checkpoint" 57 | } 58 | ``` 59 | 60 | ## Argument Reference 61 | 62 | The following arguments are used to configure the SCVMM Provider: 63 | 64 | * `user_name` - (Required) This is the username for SCVMM server login. Can also 65 | be specified with the `SCVMM_SERVER_USER` environment variable. 66 | * `user_password` - (Required) This is the password for Open Daylight API operations. Can 67 | also be specified with the `SCVMM_SERVER_PASSWORD` environment variable. 68 | * `server_ip` - (Required) This is the SCVMM server ip for SCVMM 69 | operations. Can also be specified with the `SCVMM_SERVER_IP` environment 70 | variable. 71 | * `port` - (Required) This is the port for winrm operations of the SCVMM Server. 72 | 73 | ## Acceptance Tests 74 | 75 | The Active Directory provider's acceptance tests require the above provider 76 | configuration fields to be set using the documented environment variables. 77 | 78 | Once all these variables are in place, the tests can be run like this: 79 | 80 | ``` 81 | make testacc TEST=./builtin/providers/scvmm 82 | ``` 83 | -------------------------------------------------------------------------------- /scvmm/powershell_scripts_execution.go: -------------------------------------------------------------------------------- 1 | package scvmm 2 | 3 | import ( 4 | "bytes" 5 | "io" 6 | "io/ioutil" 7 | "log" 8 | "math/rand" 9 | "strconv" 10 | "strings" 11 | "sync" 12 | "time" 13 | 14 | "github.com/masterzen/winrm" 15 | ) 16 | 17 | // ResultFunc ... function to be called after asynchronous Command result sent to winrm 18 | type ResultFunc func(string) 19 | 20 | //execScript ... Executes the script with params using winrm Client and creating temp file with the file name passed 21 | func execScript(client *winrm.Client, script string, fileName string, arguments string) (string, string) { 22 | shell, err := client.CreateShell() 23 | if err != nil { 24 | log.Printf("[Error] While creating shell %s", err.Error()) 25 | return "", err.Error() 26 | } 27 | var cmd *winrm.Command 28 | cmd, err = shell.Execute("powershell.exe") 29 | if err != nil { 30 | log.Printf("[Error] While executing powershell %s", err.Error()) 31 | return "", err.Error() 32 | } 33 | 34 | script = strings.Replace(script, "\n", "`r`n", -1) 35 | script = strings.Replace(script, "\"", "`\"", -1) 36 | script = strings.Replace(script, "$", "`$", -1) 37 | 38 | var output, errorOutput string 39 | 40 | outputFunc := func(input string) { 41 | log.Println("[DEBUG] Output received \n" + input) 42 | output = input 43 | } 44 | errorFunc := func(input string) { 45 | log.Println("[DEBUG] Error Output received \n" + input) 46 | errorOutput = input 47 | } 48 | 49 | var wg sync.WaitGroup 50 | wg.Add(8) 51 | currentTime := time.Now().UTC() 52 | randomNumber := strconv.Itoa(rand.Intn(1000)) 53 | file := randomNumber + "_" + fileName + "_" + currentTime.Format("20060102150405") + ".ps1" 54 | log.Println("[DEBUG] Shell script: " + file) 55 | log.Println("[DEBUG] Arguments: " + arguments) 56 | execCommand(cmd, "echo \""+script+"\" > C:\\Temp\\"+file+"\n", nil, nil, &wg) 57 | execCommand(cmd, "C:\\Temp\\"+file+" "+arguments+" \n", outputFunc, errorFunc, &wg) 58 | execCommand(cmd, "rm C:\\Temp\\"+file+"\n", nil, nil, &wg) 59 | execCommand(cmd, "exit\n", nil, nil, &wg) 60 | log.Println("[DEBUG] Waiting for commands to be executed.") 61 | cmd.Wait() 62 | wg.Wait() 63 | shell.Close() 64 | log.Println("[DEBUG] winrm Shell closed") 65 | return output, errorOutput 66 | } 67 | 68 | // execCommand ... The function to execute the command and recieve the output in the functions passed 69 | func execCommand(cmd *winrm.Command, command string, outputFun, errorFun ResultFunc, wg *sync.WaitGroup) { 70 | stdin := bytes.NewBufferString(command) 71 | log.Printf("[DEBUG] Executing command %s", command) 72 | io.Copy(cmd.Stdin, stdin) 73 | go func() { 74 | defer (*wg).Done() 75 | if outputFun != nil { 76 | output, _ := ioutil.ReadAll(cmd.Stdout) 77 | for !strings.Contains(string(output), "exit") { 78 | output, _ = ioutil.ReadAll(cmd.Stdout) 79 | } 80 | outputFun(string(output)) 81 | } 82 | }() 83 | go func() { 84 | defer (*wg).Done() 85 | if errorFun != nil { 86 | output, _ := ioutil.ReadAll(cmd.Stderr) 87 | errorFun(string(output)) 88 | } 89 | }() 90 | } 91 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/winrm/soap/namespaces.go: -------------------------------------------------------------------------------- 1 | package soap 2 | 3 | import ( 4 | "github.com/ChrisTrenkamp/goxpath" 5 | "github.com/masterzen/simplexml/dom" 6 | ) 7 | 8 | // Namespaces 9 | const ( 10 | NS_SOAP_ENV = "http://www.w3.org/2003/05/soap-envelope" 11 | NS_ADDRESSING = "http://schemas.xmlsoap.org/ws/2004/08/addressing" 12 | NS_CIMBINDING = "http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd" 13 | NS_ENUM = "http://schemas.xmlsoap.org/ws/2004/09/enumeration" 14 | NS_TRANSFER = "http://schemas.xmlsoap.org/ws/2004/09/transfer" 15 | NS_WSMAN_DMTF = "http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd" 16 | NS_WSMAN_MSFT = "http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd" 17 | NS_SCHEMA_INST = "http://www.w3.org/2001/XMLSchema-instance" 18 | NS_WIN_SHELL = "http://schemas.microsoft.com/wbem/wsman/1/windows/shell" 19 | NS_WSMAN_FAULT = "http://schemas.microsoft.com/wbem/wsman/1/wsmanfault" 20 | ) 21 | 22 | // Namespace Prefixes 23 | const ( 24 | NSP_SOAP_ENV = "env" 25 | NSP_ADDRESSING = "a" 26 | NSP_CIMBINDING = "b" 27 | NSP_ENUM = "n" 28 | NSP_TRANSFER = "x" 29 | NSP_WSMAN_DMTF = "w" 30 | NSP_WSMAN_MSFT = "p" 31 | NSP_SCHEMA_INST = "xsi" 32 | NSP_WIN_SHELL = "rsp" 33 | NSP_WSMAN_FAULT = "f" 34 | ) 35 | 36 | // DOM Namespaces 37 | var ( 38 | DOM_NS_SOAP_ENV = dom.Namespace{"env", "http://www.w3.org/2003/05/soap-envelope"} 39 | DOM_NS_ADDRESSING = dom.Namespace{"a", "http://schemas.xmlsoap.org/ws/2004/08/addressing"} 40 | DOM_NS_CIMBINDING = dom.Namespace{"b", "http://schemas.dmtf.org/wbem/wsman/1/cimbinding.xsd"} 41 | DOM_NS_ENUM = dom.Namespace{"n", "http://schemas.xmlsoap.org/ws/2004/09/enumeration"} 42 | DOM_NS_TRANSFER = dom.Namespace{"x", "http://schemas.xmlsoap.org/ws/2004/09/transfer"} 43 | DOM_NS_WSMAN_DMTF = dom.Namespace{"w", "http://schemas.dmtf.org/wbem/wsman/1/wsman.xsd"} 44 | DOM_NS_WSMAN_MSFT = dom.Namespace{"p", "http://schemas.microsoft.com/wbem/wsman/1/wsman.xsd"} 45 | DOM_NS_SCHEMA_INST = dom.Namespace{"xsi", "http://www.w3.org/2001/XMLSchema-instance"} 46 | DOM_NS_WIN_SHELL = dom.Namespace{"rsp", "http://schemas.microsoft.com/wbem/wsman/1/windows/shell"} 47 | DOM_NS_WSMAN_FAULT = dom.Namespace{"f", "http://schemas.microsoft.com/wbem/wsman/1/wsmanfault"} 48 | ) 49 | 50 | var MostUsed = [...]dom.Namespace{ 51 | DOM_NS_SOAP_ENV, 52 | DOM_NS_ADDRESSING, 53 | DOM_NS_WIN_SHELL, 54 | DOM_NS_WSMAN_DMTF, 55 | DOM_NS_WSMAN_MSFT, 56 | } 57 | 58 | func AddUsualNamespaces(node *dom.Element) { 59 | for _, ns := range MostUsed { 60 | node.DeclareNamespace(ns) 61 | } 62 | } 63 | 64 | func GetAllXPathNamespaces() func(o *goxpath.Opts) { 65 | ns := map[string]string{ 66 | NSP_SOAP_ENV: NS_SOAP_ENV, 67 | NSP_ADDRESSING: NS_ADDRESSING, 68 | NSP_CIMBINDING: NS_CIMBINDING, 69 | NSP_ENUM: NS_ENUM, 70 | NSP_TRANSFER: NS_TRANSFER, 71 | NSP_WSMAN_DMTF: NS_WSMAN_DMTF, 72 | NSP_WSMAN_MSFT: NS_WSMAN_MSFT, 73 | NSP_SCHEMA_INST: NS_SCHEMA_INST, 74 | NSP_WIN_SHELL: NS_WIN_SHELL, 75 | NSP_WSMAN_FAULT: NS_WSMAN_FAULT, 76 | } 77 | 78 | return func(o *goxpath.Opts) { 79 | o.NS = ns 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/winrm/auth.go: -------------------------------------------------------------------------------- 1 | package winrm 2 | 3 | import ( 4 | "fmt" 5 | "io/ioutil" 6 | "net" 7 | "strings" 8 | "time" 9 | 10 | "github.com/masterzen/azure-sdk-for-go/core/http" 11 | "github.com/masterzen/azure-sdk-for-go/core/tls" 12 | 13 | "github.com/masterzen/winrm/soap" 14 | ) 15 | 16 | type ClientAuthRequest struct { 17 | transport http.RoundTripper 18 | } 19 | 20 | func (c *ClientAuthRequest) Transport(endpoint *Endpoint) error { 21 | cert, err := tls.X509KeyPair(endpoint.Cert, endpoint.Key) 22 | if err != nil { 23 | return err 24 | } 25 | 26 | transport := &http.Transport{ 27 | Proxy: http.ProxyFromEnvironment, 28 | TLSClientConfig: &tls.Config{ 29 | InsecureSkipVerify: endpoint.Insecure, 30 | Certificates: []tls.Certificate{cert}, 31 | }, 32 | Dial: (&net.Dialer{ 33 | Timeout: 30 * time.Second, 34 | KeepAlive: 30 * time.Second, 35 | }).Dial, 36 | ResponseHeaderTimeout: endpoint.Timeout, 37 | } 38 | 39 | if endpoint.CACert != nil && len(endpoint.CACert) > 0 { 40 | certPool, err := readCACerts(endpoint.CACert) 41 | if err != nil { 42 | return err 43 | } 44 | 45 | transport.TLSClientConfig.RootCAs = certPool 46 | } 47 | 48 | c.transport = transport 49 | 50 | return nil 51 | } 52 | 53 | // parse func reads the response body and return it as a string 54 | func parse(response *http.Response) (string, error) { 55 | 56 | // if we recived the content we expected 57 | if strings.Contains(response.Header.Get("Content-Type"), "application/soap+xml") { 58 | body, err := ioutil.ReadAll(response.Body) 59 | defer func() { 60 | // defer can modify the returned value before 61 | // it is actually passed to the calling statement 62 | if errClose := response.Body.Close(); errClose != nil && err == nil { 63 | err = errClose 64 | } 65 | }() 66 | if err != nil { 67 | return "", fmt.Errorf("error while reading request body %s", err) 68 | } 69 | 70 | return string(body), nil 71 | } 72 | 73 | return "", fmt.Errorf("invalid content type") 74 | } 75 | 76 | func (c ClientAuthRequest) Post(client *Client, request *soap.SoapMessage) (string, error) { 77 | httpClient := &http.Client{Transport: c.transport} 78 | 79 | req, err := http.NewRequest("POST", client.url, strings.NewReader(request.String())) 80 | if err != nil { 81 | return "", fmt.Errorf("impossible to create http request %s", err) 82 | } 83 | 84 | req.Header.Set("Content-Type", soapXML+";charset=UTF-8") 85 | req.Header.Set("Authorization", "http://schemas.dmtf.org/wbem/wsman/1/wsman/secprofile/https/mutual") 86 | 87 | resp, err := httpClient.Do(req) 88 | if err != nil { 89 | return "", fmt.Errorf("unknown error %s", err) 90 | } 91 | 92 | body, err := parse(resp) 93 | if err != nil { 94 | return "", fmt.Errorf("http response error: %d - %s", resp.StatusCode, err.Error()) 95 | } 96 | 97 | // if we have different 200 http status code 98 | // we must replace the error 99 | defer func() { 100 | if resp.StatusCode != 200 { 101 | body, err = "", fmt.Errorf("http error %d: %s", resp.StatusCode, body) 102 | } 103 | }() 104 | 105 | return body, err 106 | } 107 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/node.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import ( 8 | "net" 9 | "sync" 10 | ) 11 | 12 | var ( 13 | nodeMu sync.Mutex 14 | interfaces []net.Interface // cached list of interfaces 15 | ifname string // name of interface being used 16 | nodeID []byte // hardware for version 1 UUIDs 17 | ) 18 | 19 | // NodeInterface returns the name of the interface from which the NodeID was 20 | // derived. The interface "user" is returned if the NodeID was set by 21 | // SetNodeID. 22 | func NodeInterface() string { 23 | defer nodeMu.Unlock() 24 | nodeMu.Lock() 25 | return ifname 26 | } 27 | 28 | // SetNodeInterface selects the hardware address to be used for Version 1 UUIDs. 29 | // If name is "" then the first usable interface found will be used or a random 30 | // Node ID will be generated. If a named interface cannot be found then false 31 | // is returned. 32 | // 33 | // SetNodeInterface never fails when name is "". 34 | func SetNodeInterface(name string) bool { 35 | defer nodeMu.Unlock() 36 | nodeMu.Lock() 37 | return setNodeInterface(name) 38 | } 39 | 40 | func setNodeInterface(name string) bool { 41 | if interfaces == nil { 42 | var err error 43 | interfaces, err = net.Interfaces() 44 | if err != nil && name != "" { 45 | return false 46 | } 47 | } 48 | 49 | for _, ifs := range interfaces { 50 | if len(ifs.HardwareAddr) >= 6 && (name == "" || name == ifs.Name) { 51 | if setNodeID(ifs.HardwareAddr) { 52 | ifname = ifs.Name 53 | return true 54 | } 55 | } 56 | } 57 | 58 | // We found no interfaces with a valid hardware address. If name 59 | // does not specify a specific interface generate a random Node ID 60 | // (section 4.1.6) 61 | if name == "" { 62 | if nodeID == nil { 63 | nodeID = make([]byte, 6) 64 | } 65 | randomBits(nodeID) 66 | return true 67 | } 68 | return false 69 | } 70 | 71 | // NodeID returns a slice of a copy of the current Node ID, setting the Node ID 72 | // if not already set. 73 | func NodeID() []byte { 74 | defer nodeMu.Unlock() 75 | nodeMu.Lock() 76 | if nodeID == nil { 77 | setNodeInterface("") 78 | } 79 | nid := make([]byte, 6) 80 | copy(nid, nodeID) 81 | return nid 82 | } 83 | 84 | // SetNodeID sets the Node ID to be used for Version 1 UUIDs. The first 6 bytes 85 | // of id are used. If id is less than 6 bytes then false is returned and the 86 | // Node ID is not set. 87 | func SetNodeID(id []byte) bool { 88 | defer nodeMu.Unlock() 89 | nodeMu.Lock() 90 | if setNodeID(id) { 91 | ifname = "user" 92 | return true 93 | } 94 | return false 95 | } 96 | 97 | func setNodeID(id []byte) bool { 98 | if len(id) < 6 { 99 | return false 100 | } 101 | if nodeID == nil { 102 | nodeID = make([]byte, 6) 103 | } 104 | copy(nodeID, id) 105 | return true 106 | } 107 | 108 | // NodeID returns the 6 byte node id encoded in uuid. It returns nil if uuid is 109 | // not valid. The NodeID is only well defined for version 1 and 2 UUIDs. 110 | func (uuid UUID) NodeID() []byte { 111 | if len(uuid) != 16 { 112 | return nil 113 | } 114 | node := make([]byte, 6) 115 | copy(node, uuid[10:]) 116 | return node 117 | } 118 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/winrm/response.go: -------------------------------------------------------------------------------- 1 | package winrm 2 | 3 | import ( 4 | "encoding/base64" 5 | "fmt" 6 | "io" 7 | "strconv" 8 | "strings" 9 | 10 | "github.com/ChrisTrenkamp/goxpath" 11 | "github.com/ChrisTrenkamp/goxpath/tree" 12 | "github.com/ChrisTrenkamp/goxpath/tree/xmltree" 13 | "github.com/masterzen/winrm/soap" 14 | ) 15 | 16 | func first(node tree.Node, xpath string) (string, error) { 17 | nodes, err := xPath(node, xpath) 18 | if err != nil { 19 | return "", err 20 | } 21 | if len(nodes) < 1 { 22 | return "", err 23 | } 24 | return nodes[0].ResValue(), nil 25 | } 26 | 27 | func any(node tree.Node, xpath string) (bool, error) { 28 | nodes, err := xPath(node, xpath) 29 | if err != nil { 30 | return false, err 31 | } 32 | if len(nodes) > 0 { 33 | return true, nil 34 | } 35 | return false, nil 36 | } 37 | 38 | func xPath(node tree.Node, xpath string) (tree.NodeSet, error) { 39 | xpExec := goxpath.MustParse(xpath) 40 | nodes, err := xpExec.ExecNode(node, soap.GetAllXPathNamespaces()) 41 | if err != nil { 42 | return nil, err 43 | } 44 | return nodes, nil 45 | } 46 | 47 | func ParseOpenShellResponse(response string) (string, error) { 48 | doc, err := xmltree.ParseXML(strings.NewReader(response)) 49 | if err != nil { 50 | return "", err 51 | } 52 | return first(doc, "//w:Selector[@Name='ShellId']") 53 | } 54 | 55 | func ParseExecuteCommandResponse(response string) (string, error) { 56 | doc, err := xmltree.ParseXML(strings.NewReader(response)) 57 | if err != nil { 58 | return "", err 59 | } 60 | return first(doc, "//rsp:CommandId") 61 | } 62 | 63 | func ParseSlurpOutputErrResponse(response string, stdout, stderr io.Writer) (bool, int, error) { 64 | var ( 65 | finished bool 66 | exitCode int 67 | ) 68 | 69 | doc, err := xmltree.ParseXML(strings.NewReader(response)) 70 | 71 | stdouts, _ := xPath(doc, "//rsp:Stream[@Name='stdout']") 72 | for _, node := range stdouts { 73 | content, _ := base64.StdEncoding.DecodeString(node.ResValue()) 74 | stdout.Write(content) 75 | } 76 | stderrs, _ := xPath(doc, "//rsp:Stream[@Name='stderr']") 77 | for _, node := range stderrs { 78 | content, _ := base64.StdEncoding.DecodeString(node.ResValue()) 79 | stderr.Write(content) 80 | } 81 | 82 | ended, _ := any(doc, "//*[@State='http://schemas.microsoft.com/wbem/wsman/1/windows/shell/CommandState/Done']") 83 | 84 | if ended { 85 | finished = ended 86 | if exitBool, _ := any(doc, "//rsp:ExitCode"); exitBool { 87 | exit, _ := first(doc, "//rsp:ExitCode") 88 | exitCode, _ = strconv.Atoi(exit) 89 | } 90 | } else { 91 | finished = false 92 | } 93 | 94 | return finished, exitCode, err 95 | } 96 | 97 | func ParseSlurpOutputResponse(response string, stream io.Writer, streamType string) (bool, int, error) { 98 | var ( 99 | finished bool 100 | exitCode int 101 | ) 102 | 103 | doc, err := xmltree.ParseXML(strings.NewReader(response)) 104 | 105 | nodes, _ := xPath(doc, fmt.Sprintf("//rsp:Stream[@Name='%s']", streamType)) 106 | for _, node := range nodes { 107 | content, _ := base64.StdEncoding.DecodeString(node.ResValue()) 108 | stream.Write(content) 109 | } 110 | 111 | ended, _ := any(doc, "//*[@State='http://schemas.microsoft.com/wbem/wsman/1/windows/shell/CommandState/Done']") 112 | 113 | if ended { 114 | finished = ended 115 | if exitBool, _ := any(doc, "//rsp:ExitCode"); exitBool { 116 | exit, _ := first(doc, "//rsp:ExitCode") 117 | exitCode, _ = strconv.Atoi(exit) 118 | } 119 | } else { 120 | finished = false 121 | } 122 | 123 | return finished, exitCode, err 124 | } 125 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/azure-sdk-for-go/core/http/filetransport.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package http 6 | 7 | import ( 8 | "fmt" 9 | "io" 10 | ) 11 | 12 | // fileTransport implements RoundTripper for the 'file' protocol. 13 | type fileTransport struct { 14 | fh fileHandler 15 | } 16 | 17 | // NewFileTransport returns a new RoundTripper, serving the provided 18 | // FileSystem. The returned RoundTripper ignores the URL host in its 19 | // incoming requests, as well as most other properties of the 20 | // request. 21 | // 22 | // The typical use case for NewFileTransport is to register the "file" 23 | // protocol with a Transport, as in: 24 | // 25 | // t := &http.Transport{} 26 | // t.RegisterProtocol("file", http.NewFileTransport(http.Dir("/"))) 27 | // c := &http.Client{Transport: t} 28 | // res, err := c.Get("file:///etc/passwd") 29 | // ... 30 | func NewFileTransport(fs FileSystem) RoundTripper { 31 | return fileTransport{fileHandler{fs}} 32 | } 33 | 34 | func (t fileTransport) RoundTrip(req *Request) (resp *Response, err error) { 35 | // We start ServeHTTP in a goroutine, which may take a long 36 | // time if the file is large. The newPopulateResponseWriter 37 | // call returns a channel which either ServeHTTP or finish() 38 | // sends our *Response on, once the *Response itself has been 39 | // populated (even if the body itself is still being 40 | // written to the res.Body, a pipe) 41 | rw, resc := newPopulateResponseWriter() 42 | go func() { 43 | t.fh.ServeHTTP(rw, req) 44 | rw.finish() 45 | }() 46 | return <-resc, nil 47 | } 48 | 49 | func newPopulateResponseWriter() (*populateResponse, <-chan *Response) { 50 | pr, pw := io.Pipe() 51 | rw := &populateResponse{ 52 | ch: make(chan *Response), 53 | pw: pw, 54 | res: &Response{ 55 | Proto: "HTTP/1.0", 56 | ProtoMajor: 1, 57 | Header: make(Header), 58 | Close: true, 59 | Body: pr, 60 | }, 61 | } 62 | return rw, rw.ch 63 | } 64 | 65 | // populateResponse is a ResponseWriter that populates the *Response 66 | // in res, and writes its body to a pipe connected to the response 67 | // body. Once writes begin or finish() is called, the response is sent 68 | // on ch. 69 | type populateResponse struct { 70 | res *Response 71 | ch chan *Response 72 | wroteHeader bool 73 | hasContent bool 74 | sentResponse bool 75 | pw *io.PipeWriter 76 | } 77 | 78 | func (pr *populateResponse) finish() { 79 | if !pr.wroteHeader { 80 | pr.WriteHeader(500) 81 | } 82 | if !pr.sentResponse { 83 | pr.sendResponse() 84 | } 85 | pr.pw.Close() 86 | } 87 | 88 | func (pr *populateResponse) sendResponse() { 89 | if pr.sentResponse { 90 | return 91 | } 92 | pr.sentResponse = true 93 | 94 | if pr.hasContent { 95 | pr.res.ContentLength = -1 96 | } 97 | pr.ch <- pr.res 98 | } 99 | 100 | func (pr *populateResponse) Header() Header { 101 | return pr.res.Header 102 | } 103 | 104 | func (pr *populateResponse) WriteHeader(code int) { 105 | if pr.wroteHeader { 106 | return 107 | } 108 | pr.wroteHeader = true 109 | 110 | pr.res.StatusCode = code 111 | pr.res.Status = fmt.Sprintf("%d %s", code, StatusText(code)) 112 | } 113 | 114 | func (pr *populateResponse) Write(p []byte) (n int, err error) { 115 | if !pr.wroteHeader { 116 | pr.WriteHeader(StatusOK) 117 | } 118 | pr.hasContent = true 119 | if !pr.sentResponse { 120 | pr.sendResponse() 121 | } 122 | return pr.pw.Write(p) 123 | } 124 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/azure-sdk-for-go/core/tls/generate_cert.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | // Generate a self-signed X.509 certificate for a TLS server. Outputs to 8 | // 'cert.pem' and 'key.pem' and will overwrite existing files. 9 | 10 | package main 11 | 12 | import ( 13 | "crypto/rand" 14 | "crypto/rsa" 15 | "crypto/x509" 16 | "crypto/x509/pkix" 17 | "encoding/pem" 18 | "flag" 19 | "fmt" 20 | "log" 21 | "math/big" 22 | "net" 23 | "os" 24 | "strings" 25 | "time" 26 | ) 27 | 28 | var ( 29 | host = flag.String("host", "", "Comma-separated hostnames and IPs to generate a certificate for") 30 | validFrom = flag.String("start-date", "", "Creation date formatted as Jan 1 15:04:05 2011") 31 | validFor = flag.Duration("duration", 365*24*time.Hour, "Duration that certificate is valid for") 32 | isCA = flag.Bool("ca", false, "whether this cert should be its own Certificate Authority") 33 | rsaBits = flag.Int("rsa-bits", 2048, "Size of RSA key to generate") 34 | ) 35 | 36 | func main() { 37 | flag.Parse() 38 | 39 | if len(*host) == 0 { 40 | log.Fatalf("Missing required --host parameter") 41 | } 42 | 43 | priv, err := rsa.GenerateKey(rand.Reader, *rsaBits) 44 | if err != nil { 45 | log.Fatalf("failed to generate private key: %s", err) 46 | return 47 | } 48 | 49 | var notBefore time.Time 50 | if len(*validFrom) == 0 { 51 | notBefore = time.Now() 52 | } else { 53 | notBefore, err = time.Parse("Jan 2 15:04:05 2006", *validFrom) 54 | if err != nil { 55 | fmt.Fprintf(os.Stderr, "Failed to parse creation date: %s\n", err) 56 | os.Exit(1) 57 | } 58 | } 59 | 60 | notAfter := notBefore.Add(*validFor) 61 | 62 | // end of ASN.1 time 63 | endOfTime := time.Date(2049, 12, 31, 23, 59, 59, 0, time.UTC) 64 | if notAfter.After(endOfTime) { 65 | notAfter = endOfTime 66 | } 67 | 68 | template := x509.Certificate{ 69 | SerialNumber: new(big.Int).SetInt64(0), 70 | Subject: pkix.Name{ 71 | Organization: []string{"Acme Co"}, 72 | }, 73 | NotBefore: notBefore, 74 | NotAfter: notAfter, 75 | 76 | KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature, 77 | ExtKeyUsage: []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth}, 78 | BasicConstraintsValid: true, 79 | } 80 | 81 | hosts := strings.Split(*host, ",") 82 | for _, h := range hosts { 83 | if ip := net.ParseIP(h); ip != nil { 84 | template.IPAddresses = append(template.IPAddresses, ip) 85 | } else { 86 | template.DNSNames = append(template.DNSNames, h) 87 | } 88 | } 89 | 90 | if *isCA { 91 | template.IsCA = true 92 | template.KeyUsage |= x509.KeyUsageCertSign 93 | } 94 | 95 | derBytes, err := x509.CreateCertificate(rand.Reader, &template, &template, &priv.PublicKey, priv) 96 | if err != nil { 97 | log.Fatalf("Failed to create certificate: %s", err) 98 | return 99 | } 100 | 101 | certOut, err := os.Create("cert.pem") 102 | if err != nil { 103 | log.Fatalf("failed to open cert.pem for writing: %s", err) 104 | return 105 | } 106 | pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes}) 107 | certOut.Close() 108 | log.Print("written cert.pem\n") 109 | 110 | keyOut, err := os.OpenFile("key.pem", os.O_WRONLY|os.O_CREATE|os.O_TRUNC, 0600) 111 | if err != nil { 112 | log.Print("failed to open key.pem for writing:", err) 113 | return 114 | } 115 | pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(priv)}) 116 | keyOut.Close() 117 | log.Print("written key.pem\n") 118 | } 119 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/azure-sdk-for-go/core/http/triv.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // +build ignore 6 | 7 | package main 8 | 9 | import ( 10 | "bytes" 11 | "expvar" 12 | "flag" 13 | "fmt" 14 | "io" 15 | "log" 16 | "net/http" 17 | "os" 18 | "os/exec" 19 | "strconv" 20 | "sync" 21 | ) 22 | 23 | // hello world, the web server 24 | var helloRequests = expvar.NewInt("hello-requests") 25 | 26 | func HelloServer(w http.ResponseWriter, req *http.Request) { 27 | helloRequests.Add(1) 28 | io.WriteString(w, "hello, world!\n") 29 | } 30 | 31 | // Simple counter server. POSTing to it will set the value. 32 | type Counter struct { 33 | mu sync.Mutex // protects n 34 | n int 35 | } 36 | 37 | // This makes Counter satisfy the expvar.Var interface, so we can export 38 | // it directly. 39 | func (ctr *Counter) String() string { 40 | ctr.mu.Lock() 41 | defer ctr.mu.Unlock() 42 | return fmt.Sprintf("%d", ctr.n) 43 | } 44 | 45 | func (ctr *Counter) ServeHTTP(w http.ResponseWriter, req *http.Request) { 46 | ctr.mu.Lock() 47 | defer ctr.mu.Unlock() 48 | switch req.Method { 49 | case "GET": 50 | ctr.n++ 51 | case "POST": 52 | buf := new(bytes.Buffer) 53 | io.Copy(buf, req.Body) 54 | body := buf.String() 55 | if n, err := strconv.Atoi(body); err != nil { 56 | fmt.Fprintf(w, "bad POST: %v\nbody: [%v]\n", err, body) 57 | } else { 58 | ctr.n = n 59 | fmt.Fprint(w, "counter reset\n") 60 | } 61 | } 62 | fmt.Fprintf(w, "counter = %d\n", ctr.n) 63 | } 64 | 65 | // simple flag server 66 | var booleanflag = flag.Bool("boolean", true, "another flag for testing") 67 | 68 | func FlagServer(w http.ResponseWriter, req *http.Request) { 69 | w.Header().Set("Content-Type", "text/plain; charset=utf-8") 70 | fmt.Fprint(w, "Flags:\n") 71 | flag.VisitAll(func(f *flag.Flag) { 72 | if f.Value.String() != f.DefValue { 73 | fmt.Fprintf(w, "%s = %s [default = %s]\n", f.Name, f.Value.String(), f.DefValue) 74 | } else { 75 | fmt.Fprintf(w, "%s = %s\n", f.Name, f.Value.String()) 76 | } 77 | }) 78 | } 79 | 80 | // simple argument server 81 | func ArgServer(w http.ResponseWriter, req *http.Request) { 82 | for _, s := range os.Args { 83 | fmt.Fprint(w, s, " ") 84 | } 85 | } 86 | 87 | // a channel (just for the fun of it) 88 | type Chan chan int 89 | 90 | func ChanCreate() Chan { 91 | c := make(Chan) 92 | go func(c Chan) { 93 | for x := 0; ; x++ { 94 | c <- x 95 | } 96 | }(c) 97 | return c 98 | } 99 | 100 | func (ch Chan) ServeHTTP(w http.ResponseWriter, req *http.Request) { 101 | io.WriteString(w, fmt.Sprintf("channel send #%d\n", <-ch)) 102 | } 103 | 104 | // exec a program, redirecting output 105 | func DateServer(rw http.ResponseWriter, req *http.Request) { 106 | rw.Header().Set("Content-Type", "text/plain; charset=utf-8") 107 | 108 | date, err := exec.Command("/bin/date").Output() 109 | if err != nil { 110 | http.Error(rw, err.Error(), 500) 111 | return 112 | } 113 | rw.Write(date) 114 | } 115 | 116 | func Logger(w http.ResponseWriter, req *http.Request) { 117 | log.Print(req.URL) 118 | http.Error(w, "oops", 404) 119 | } 120 | 121 | var webroot = flag.String("root", os.Getenv("HOME"), "web root directory") 122 | 123 | func main() { 124 | flag.Parse() 125 | 126 | // The counter is published as a variable directly. 127 | ctr := new(Counter) 128 | expvar.Publish("counter", ctr) 129 | http.Handle("/counter", ctr) 130 | http.Handle("/", http.HandlerFunc(Logger)) 131 | http.Handle("/go/", http.StripPrefix("/go/", http.FileServer(http.Dir(*webroot)))) 132 | http.Handle("/chan", ChanCreate()) 133 | http.HandleFunc("/flags", FlagServer) 134 | http.HandleFunc("/args", ArgServer) 135 | http.HandleFunc("/go/hello", HelloServer) 136 | http.HandleFunc("/date", DateServer) 137 | err := http.ListenAndServe(":12345", nil) 138 | if err != nil { 139 | log.Panicln("ListenAndServe:", err) 140 | } 141 | } 142 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/time.go: -------------------------------------------------------------------------------- 1 | // Copyright 2014 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import ( 8 | "encoding/binary" 9 | "sync" 10 | "time" 11 | ) 12 | 13 | // A Time represents a time as the number of 100's of nanoseconds since 15 Oct 14 | // 1582. 15 | type Time int64 16 | 17 | const ( 18 | lillian = 2299160 // Julian day of 15 Oct 1582 19 | unix = 2440587 // Julian day of 1 Jan 1970 20 | epoch = unix - lillian // Days between epochs 21 | g1582 = epoch * 86400 // seconds between epochs 22 | g1582ns100 = g1582 * 10000000 // 100s of a nanoseconds between epochs 23 | ) 24 | 25 | var ( 26 | timeMu sync.Mutex 27 | lasttime uint64 // last time we returned 28 | clock_seq uint16 // clock sequence for this run 29 | 30 | timeNow = time.Now // for testing 31 | ) 32 | 33 | // UnixTime converts t the number of seconds and nanoseconds using the Unix 34 | // epoch of 1 Jan 1970. 35 | func (t Time) UnixTime() (sec, nsec int64) { 36 | sec = int64(t - g1582ns100) 37 | nsec = (sec % 10000000) * 100 38 | sec /= 10000000 39 | return sec, nsec 40 | } 41 | 42 | // GetTime returns the current Time (100s of nanoseconds since 15 Oct 1582) and 43 | // clock sequence as well as adjusting the clock sequence as needed. An error 44 | // is returned if the current time cannot be determined. 45 | func GetTime() (Time, uint16, error) { 46 | defer timeMu.Unlock() 47 | timeMu.Lock() 48 | return getTime() 49 | } 50 | 51 | func getTime() (Time, uint16, error) { 52 | t := timeNow() 53 | 54 | // If we don't have a clock sequence already, set one. 55 | if clock_seq == 0 { 56 | setClockSequence(-1) 57 | } 58 | now := uint64(t.UnixNano()/100) + g1582ns100 59 | 60 | // If time has gone backwards with this clock sequence then we 61 | // increment the clock sequence 62 | if now <= lasttime { 63 | clock_seq = ((clock_seq + 1) & 0x3fff) | 0x8000 64 | } 65 | lasttime = now 66 | return Time(now), clock_seq, nil 67 | } 68 | 69 | // ClockSequence returns the current clock sequence, generating one if not 70 | // already set. The clock sequence is only used for Version 1 UUIDs. 71 | // 72 | // The uuid package does not use global static storage for the clock sequence or 73 | // the last time a UUID was generated. Unless SetClockSequence a new random 74 | // clock sequence is generated the first time a clock sequence is requested by 75 | // ClockSequence, GetTime, or NewUUID. (section 4.2.1.1) sequence is generated 76 | // for 77 | func ClockSequence() int { 78 | defer timeMu.Unlock() 79 | timeMu.Lock() 80 | return clockSequence() 81 | } 82 | 83 | func clockSequence() int { 84 | if clock_seq == 0 { 85 | setClockSequence(-1) 86 | } 87 | return int(clock_seq & 0x3fff) 88 | } 89 | 90 | // SetClockSeq sets the clock sequence to the lower 14 bits of seq. Setting to 91 | // -1 causes a new sequence to be generated. 92 | func SetClockSequence(seq int) { 93 | defer timeMu.Unlock() 94 | timeMu.Lock() 95 | setClockSequence(seq) 96 | } 97 | 98 | func setClockSequence(seq int) { 99 | if seq == -1 { 100 | var b [2]byte 101 | randomBits(b[:]) // clock sequence 102 | seq = int(b[0])<<8 | int(b[1]) 103 | } 104 | old_seq := clock_seq 105 | clock_seq = uint16(seq&0x3fff) | 0x8000 // Set our variant 106 | if old_seq != clock_seq { 107 | lasttime = 0 108 | } 109 | } 110 | 111 | // Time returns the time in 100s of nanoseconds since 15 Oct 1582 encoded in 112 | // uuid. It returns false if uuid is not valid. The time is only well defined 113 | // for version 1 and 2 UUIDs. 114 | func (uuid UUID) Time() (Time, bool) { 115 | if len(uuid) != 16 { 116 | return 0, false 117 | } 118 | time := int64(binary.BigEndian.Uint32(uuid[0:4])) 119 | time |= int64(binary.BigEndian.Uint16(uuid[4:6])) << 32 120 | time |= int64(binary.BigEndian.Uint16(uuid[6:8])&0xfff) << 48 121 | return Time(time), true 122 | } 123 | 124 | // ClockSequence returns the clock sequence encoded in uuid. It returns false 125 | // if uuid is not valid. The clock sequence is only well defined for version 1 126 | // and 2 UUIDs. 127 | func (uuid UUID) ClockSequence() (int, bool) { 128 | if len(uuid) != 16 { 129 | return 0, false 130 | } 131 | return int(binary.BigEndian.Uint16(uuid[8:10])) & 0x3fff, true 132 | } 133 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/azure-sdk-for-go/core/tls/ticket.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package tls 6 | 7 | import ( 8 | "bytes" 9 | "crypto/aes" 10 | "crypto/cipher" 11 | "crypto/hmac" 12 | "crypto/sha256" 13 | "crypto/subtle" 14 | "errors" 15 | "io" 16 | ) 17 | 18 | // sessionState contains the information that is serialized into a session 19 | // ticket in order to later resume a connection. 20 | type sessionState struct { 21 | vers uint16 22 | cipherSuite uint16 23 | masterSecret []byte 24 | certificates [][]byte 25 | } 26 | 27 | func (s *sessionState) equal(i interface{}) bool { 28 | s1, ok := i.(*sessionState) 29 | if !ok { 30 | return false 31 | } 32 | 33 | if s.vers != s1.vers || 34 | s.cipherSuite != s1.cipherSuite || 35 | !bytes.Equal(s.masterSecret, s1.masterSecret) { 36 | return false 37 | } 38 | 39 | if len(s.certificates) != len(s1.certificates) { 40 | return false 41 | } 42 | 43 | for i := range s.certificates { 44 | if !bytes.Equal(s.certificates[i], s1.certificates[i]) { 45 | return false 46 | } 47 | } 48 | 49 | return true 50 | } 51 | 52 | func (s *sessionState) marshal() []byte { 53 | length := 2 + 2 + 2 + len(s.masterSecret) + 2 54 | for _, cert := range s.certificates { 55 | length += 4 + len(cert) 56 | } 57 | 58 | ret := make([]byte, length) 59 | x := ret 60 | x[0] = byte(s.vers >> 8) 61 | x[1] = byte(s.vers) 62 | x[2] = byte(s.cipherSuite >> 8) 63 | x[3] = byte(s.cipherSuite) 64 | x[4] = byte(len(s.masterSecret) >> 8) 65 | x[5] = byte(len(s.masterSecret)) 66 | x = x[6:] 67 | copy(x, s.masterSecret) 68 | x = x[len(s.masterSecret):] 69 | 70 | x[0] = byte(len(s.certificates) >> 8) 71 | x[1] = byte(len(s.certificates)) 72 | x = x[2:] 73 | 74 | for _, cert := range s.certificates { 75 | x[0] = byte(len(cert) >> 24) 76 | x[1] = byte(len(cert) >> 16) 77 | x[2] = byte(len(cert) >> 8) 78 | x[3] = byte(len(cert)) 79 | copy(x[4:], cert) 80 | x = x[4+len(cert):] 81 | } 82 | 83 | return ret 84 | } 85 | 86 | func (s *sessionState) unmarshal(data []byte) bool { 87 | if len(data) < 8 { 88 | return false 89 | } 90 | 91 | s.vers = uint16(data[0])<<8 | uint16(data[1]) 92 | s.cipherSuite = uint16(data[2])<<8 | uint16(data[3]) 93 | masterSecretLen := int(data[4])<<8 | int(data[5]) 94 | data = data[6:] 95 | if len(data) < masterSecretLen { 96 | return false 97 | } 98 | 99 | s.masterSecret = data[:masterSecretLen] 100 | data = data[masterSecretLen:] 101 | 102 | if len(data) < 2 { 103 | return false 104 | } 105 | 106 | numCerts := int(data[0])<<8 | int(data[1]) 107 | data = data[2:] 108 | 109 | s.certificates = make([][]byte, numCerts) 110 | for i := range s.certificates { 111 | if len(data) < 4 { 112 | return false 113 | } 114 | certLen := int(data[0])<<24 | int(data[1])<<16 | int(data[2])<<8 | int(data[3]) 115 | data = data[4:] 116 | if certLen < 0 { 117 | return false 118 | } 119 | if len(data) < certLen { 120 | return false 121 | } 122 | s.certificates[i] = data[:certLen] 123 | data = data[certLen:] 124 | } 125 | 126 | if len(data) > 0 { 127 | return false 128 | } 129 | 130 | return true 131 | } 132 | 133 | func (c *Conn) encryptTicket(state *sessionState) ([]byte, error) { 134 | serialized := state.marshal() 135 | encrypted := make([]byte, aes.BlockSize+len(serialized)+sha256.Size) 136 | iv := encrypted[:aes.BlockSize] 137 | macBytes := encrypted[len(encrypted)-sha256.Size:] 138 | 139 | if _, err := io.ReadFull(c.config.rand(), iv); err != nil { 140 | return nil, err 141 | } 142 | block, err := aes.NewCipher(c.config.SessionTicketKey[:16]) 143 | if err != nil { 144 | return nil, errors.New("tls: failed to create cipher while encrypting ticket: " + err.Error()) 145 | } 146 | cipher.NewCTR(block, iv).XORKeyStream(encrypted[aes.BlockSize:], serialized) 147 | 148 | mac := hmac.New(sha256.New, c.config.SessionTicketKey[16:32]) 149 | mac.Write(encrypted[:len(encrypted)-sha256.Size]) 150 | mac.Sum(macBytes[:0]) 151 | 152 | return encrypted, nil 153 | } 154 | 155 | func (c *Conn) decryptTicket(encrypted []byte) (*sessionState, bool) { 156 | if len(encrypted) < aes.BlockSize+sha256.Size { 157 | return nil, false 158 | } 159 | 160 | iv := encrypted[:aes.BlockSize] 161 | macBytes := encrypted[len(encrypted)-sha256.Size:] 162 | 163 | mac := hmac.New(sha256.New, c.config.SessionTicketKey[16:32]) 164 | mac.Write(encrypted[:len(encrypted)-sha256.Size]) 165 | expected := mac.Sum(nil) 166 | 167 | if subtle.ConstantTimeCompare(macBytes, expected) != 1 { 168 | return nil, false 169 | } 170 | 171 | block, err := aes.NewCipher(c.config.SessionTicketKey[:16]) 172 | if err != nil { 173 | return nil, false 174 | } 175 | ciphertext := encrypted[aes.BlockSize : len(encrypted)-sha256.Size] 176 | plaintext := ciphertext 177 | cipher.NewCTR(block, iv).XORKeyStream(plaintext, ciphertext) 178 | 179 | state := new(sessionState) 180 | ok := state.unmarshal(plaintext) 181 | return state, ok 182 | } 183 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/azure-sdk-for-go/core/http/status.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package http 6 | 7 | // HTTP status codes, defined in RFC 2616. 8 | const ( 9 | StatusContinue = 100 10 | StatusSwitchingProtocols = 101 11 | 12 | StatusOK = 200 13 | StatusCreated = 201 14 | StatusAccepted = 202 15 | StatusNonAuthoritativeInfo = 203 16 | StatusNoContent = 204 17 | StatusResetContent = 205 18 | StatusPartialContent = 206 19 | 20 | StatusMultipleChoices = 300 21 | StatusMovedPermanently = 301 22 | StatusFound = 302 23 | StatusSeeOther = 303 24 | StatusNotModified = 304 25 | StatusUseProxy = 305 26 | StatusTemporaryRedirect = 307 27 | 28 | StatusBadRequest = 400 29 | StatusUnauthorized = 401 30 | StatusPaymentRequired = 402 31 | StatusForbidden = 403 32 | StatusNotFound = 404 33 | StatusMethodNotAllowed = 405 34 | StatusNotAcceptable = 406 35 | StatusProxyAuthRequired = 407 36 | StatusRequestTimeout = 408 37 | StatusConflict = 409 38 | StatusGone = 410 39 | StatusLengthRequired = 411 40 | StatusPreconditionFailed = 412 41 | StatusRequestEntityTooLarge = 413 42 | StatusRequestURITooLong = 414 43 | StatusUnsupportedMediaType = 415 44 | StatusRequestedRangeNotSatisfiable = 416 45 | StatusExpectationFailed = 417 46 | StatusTeapot = 418 47 | 48 | StatusInternalServerError = 500 49 | StatusNotImplemented = 501 50 | StatusBadGateway = 502 51 | StatusServiceUnavailable = 503 52 | StatusGatewayTimeout = 504 53 | StatusHTTPVersionNotSupported = 505 54 | 55 | // New HTTP status codes from RFC 6585. Not exported yet in Go 1.1. 56 | // See discussion at https://codereview.appspot.com/7678043/ 57 | statusPreconditionRequired = 428 58 | statusTooManyRequests = 429 59 | statusRequestHeaderFieldsTooLarge = 431 60 | statusNetworkAuthenticationRequired = 511 61 | ) 62 | 63 | var statusText = map[int]string{ 64 | StatusContinue: "Continue", 65 | StatusSwitchingProtocols: "Switching Protocols", 66 | 67 | StatusOK: "OK", 68 | StatusCreated: "Created", 69 | StatusAccepted: "Accepted", 70 | StatusNonAuthoritativeInfo: "Non-Authoritative Information", 71 | StatusNoContent: "No Content", 72 | StatusResetContent: "Reset Content", 73 | StatusPartialContent: "Partial Content", 74 | 75 | StatusMultipleChoices: "Multiple Choices", 76 | StatusMovedPermanently: "Moved Permanently", 77 | StatusFound: "Found", 78 | StatusSeeOther: "See Other", 79 | StatusNotModified: "Not Modified", 80 | StatusUseProxy: "Use Proxy", 81 | StatusTemporaryRedirect: "Temporary Redirect", 82 | 83 | StatusBadRequest: "Bad Request", 84 | StatusUnauthorized: "Unauthorized", 85 | StatusPaymentRequired: "Payment Required", 86 | StatusForbidden: "Forbidden", 87 | StatusNotFound: "Not Found", 88 | StatusMethodNotAllowed: "Method Not Allowed", 89 | StatusNotAcceptable: "Not Acceptable", 90 | StatusProxyAuthRequired: "Proxy Authentication Required", 91 | StatusRequestTimeout: "Request Timeout", 92 | StatusConflict: "Conflict", 93 | StatusGone: "Gone", 94 | StatusLengthRequired: "Length Required", 95 | StatusPreconditionFailed: "Precondition Failed", 96 | StatusRequestEntityTooLarge: "Request Entity Too Large", 97 | StatusRequestURITooLong: "Request URI Too Long", 98 | StatusUnsupportedMediaType: "Unsupported Media Type", 99 | StatusRequestedRangeNotSatisfiable: "Requested Range Not Satisfiable", 100 | StatusExpectationFailed: "Expectation Failed", 101 | StatusTeapot: "I'm a teapot", 102 | 103 | StatusInternalServerError: "Internal Server Error", 104 | StatusNotImplemented: "Not Implemented", 105 | StatusBadGateway: "Bad Gateway", 106 | StatusServiceUnavailable: "Service Unavailable", 107 | StatusGatewayTimeout: "Gateway Timeout", 108 | StatusHTTPVersionNotSupported: "HTTP Version Not Supported", 109 | 110 | statusPreconditionRequired: "Precondition Required", 111 | statusTooManyRequests: "Too Many Requests", 112 | statusRequestHeaderFieldsTooLarge: "Request Header Fields Too Large", 113 | statusNetworkAuthenticationRequired: "Network Authentication Required", 114 | } 115 | 116 | // StatusText returns a text for the HTTP status code. It returns the empty 117 | // string if the code is unknown. 118 | func StatusText(code int) string { 119 | return statusText[code] 120 | } 121 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/winrm/soap/header.go: -------------------------------------------------------------------------------- 1 | package soap 2 | 3 | import ( 4 | "strconv" 5 | 6 | "github.com/masterzen/simplexml/dom" 7 | ) 8 | 9 | type HeaderOption struct { 10 | key string 11 | value string 12 | } 13 | 14 | func NewHeaderOption(name string, value string) *HeaderOption { 15 | return &HeaderOption{key: name, value: value} 16 | } 17 | 18 | type SoapHeader struct { 19 | to string 20 | replyTo string 21 | maxEnvelopeSize string 22 | timeout string 23 | locale string 24 | id string 25 | action string 26 | shellId string 27 | resourceURI string 28 | options []HeaderOption 29 | message *SoapMessage 30 | } 31 | 32 | type HeaderBuilder interface { 33 | To(string) *SoapHeader 34 | ReplyTo(string) *SoapHeader 35 | MaxEnvelopeSize(int) *SoapHeader 36 | Timeout(string) *SoapHeader 37 | Locale(string) *SoapHeader 38 | Id(string) *SoapHeader 39 | Action(string) *SoapHeader 40 | ShellId(string) *SoapHeader 41 | resourceURI(string) *SoapHeader 42 | AddOption(*HeaderOption) *SoapHeader 43 | Options([]HeaderOption) *SoapHeader 44 | Build(*SoapMessage) *SoapMessage 45 | } 46 | 47 | func (self *SoapHeader) To(uri string) *SoapHeader { 48 | self.to = uri 49 | return self 50 | } 51 | 52 | func (self *SoapHeader) ReplyTo(uri string) *SoapHeader { 53 | self.replyTo = uri 54 | return self 55 | } 56 | 57 | func (self *SoapHeader) MaxEnvelopeSize(size int) *SoapHeader { 58 | self.maxEnvelopeSize = strconv.Itoa(size) 59 | return self 60 | } 61 | 62 | func (self *SoapHeader) Timeout(timeout string) *SoapHeader { 63 | self.timeout = timeout 64 | return self 65 | } 66 | 67 | func (self *SoapHeader) Id(id string) *SoapHeader { 68 | self.id = id 69 | return self 70 | } 71 | 72 | func (self *SoapHeader) Action(action string) *SoapHeader { 73 | self.action = action 74 | return self 75 | } 76 | 77 | func (self *SoapHeader) Locale(locale string) *SoapHeader { 78 | self.locale = locale 79 | return self 80 | } 81 | 82 | func (self *SoapHeader) ShellId(shellId string) *SoapHeader { 83 | self.shellId = shellId 84 | return self 85 | } 86 | 87 | func (self *SoapHeader) ResourceURI(resourceURI string) *SoapHeader { 88 | self.resourceURI = resourceURI 89 | return self 90 | } 91 | 92 | func (self *SoapHeader) AddOption(option *HeaderOption) *SoapHeader { 93 | self.options = append(self.options, *option) 94 | return self 95 | } 96 | 97 | func (self *SoapHeader) Options(options []HeaderOption) *SoapHeader { 98 | self.options = options 99 | return self 100 | } 101 | 102 | func (self *SoapHeader) Build() *SoapMessage { 103 | header := self.createElement(self.message.envelope, "Header", DOM_NS_SOAP_ENV) 104 | 105 | if self.to != "" { 106 | to := self.createElement(header, "To", DOM_NS_ADDRESSING) 107 | to.SetContent(self.to) 108 | } 109 | 110 | if self.replyTo != "" { 111 | replyTo := self.createElement(header, "ReplyTo", DOM_NS_ADDRESSING) 112 | a := self.createMUElement(replyTo, "Address", DOM_NS_ADDRESSING, true) 113 | a.SetContent(self.replyTo) 114 | } 115 | 116 | if self.maxEnvelopeSize != "" { 117 | envelope := self.createMUElement(header, "MaxEnvelopeSize", DOM_NS_WSMAN_DMTF, true) 118 | envelope.SetContent(self.maxEnvelopeSize) 119 | } 120 | 121 | if self.timeout != "" { 122 | timeout := self.createElement(header, "OperationTimeout", DOM_NS_WSMAN_DMTF) 123 | timeout.SetContent(self.timeout) 124 | } 125 | 126 | if self.id != "" { 127 | id := self.createElement(header, "MessageID", DOM_NS_ADDRESSING) 128 | id.SetContent(self.id) 129 | } 130 | 131 | if self.locale != "" { 132 | locale := self.createMUElement(header, "Locale", DOM_NS_WSMAN_DMTF, false) 133 | locale.SetAttr("xml:lang", self.locale) 134 | datalocale := self.createMUElement(header, "DataLocale", DOM_NS_WSMAN_MSFT, false) 135 | datalocale.SetAttr("xml:lang", self.locale) 136 | } 137 | 138 | if self.action != "" { 139 | action := self.createMUElement(header, "Action", DOM_NS_ADDRESSING, true) 140 | action.SetContent(self.action) 141 | } 142 | 143 | if self.shellId != "" { 144 | selectorSet := self.createElement(header, "SelectorSet", DOM_NS_WSMAN_DMTF) 145 | selector := self.createElement(selectorSet, "Selector", DOM_NS_WSMAN_DMTF) 146 | selector.SetAttr("Name", "ShellId") 147 | selector.SetContent(self.shellId) 148 | } 149 | 150 | if self.resourceURI != "" { 151 | resource := self.createMUElement(header, "ResourceURI", DOM_NS_WSMAN_DMTF, true) 152 | resource.SetContent(self.resourceURI) 153 | } 154 | 155 | if len(self.options) > 0 { 156 | set := self.createElement(header, "OptionSet", DOM_NS_WSMAN_DMTF) 157 | for _, option := range self.options { 158 | e := self.createElement(set, "Option", DOM_NS_WSMAN_DMTF) 159 | e.SetAttr("Name", option.key) 160 | e.SetContent(option.value) 161 | } 162 | } 163 | 164 | return self.message 165 | } 166 | 167 | func (self *SoapHeader) createElement(parent *dom.Element, name string, ns dom.Namespace) (element *dom.Element) { 168 | element = dom.CreateElement(name) 169 | parent.AddChild(element) 170 | ns.SetTo(element) 171 | return 172 | } 173 | 174 | func (self *SoapHeader) createMUElement(parent *dom.Element, name string, ns dom.Namespace, mustUnderstand bool) (element *dom.Element) { 175 | element = self.createElement(parent, name, ns) 176 | value := "false" 177 | if mustUnderstand { 178 | value = "true" 179 | } 180 | element.SetAttr("mustUnderstand", value) 181 | return 182 | } 183 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/uuid.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Google Inc. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package uuid 6 | 7 | import ( 8 | "bytes" 9 | "crypto/rand" 10 | "encoding/hex" 11 | "fmt" 12 | "io" 13 | "strings" 14 | ) 15 | 16 | // Array is a pass-by-value UUID that can be used as an effecient key in a map. 17 | type Array [16]byte 18 | 19 | // UUID converts uuid into a slice. 20 | func (uuid Array) UUID() UUID { 21 | return uuid[:] 22 | } 23 | 24 | // String returns the string representation of uuid, 25 | // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx. 26 | func (uuid Array) String() string { 27 | return uuid.UUID().String() 28 | } 29 | 30 | // A UUID is a 128 bit (16 byte) Universal Unique IDentifier as defined in RFC 31 | // 4122. 32 | type UUID []byte 33 | 34 | // A Version represents a UUIDs version. 35 | type Version byte 36 | 37 | // A Variant represents a UUIDs variant. 38 | type Variant byte 39 | 40 | // Constants returned by Variant. 41 | const ( 42 | Invalid = Variant(iota) // Invalid UUID 43 | RFC4122 // The variant specified in RFC4122 44 | Reserved // Reserved, NCS backward compatibility. 45 | Microsoft // Reserved, Microsoft Corporation backward compatibility. 46 | Future // Reserved for future definition. 47 | ) 48 | 49 | var rander = rand.Reader // random function 50 | 51 | // New returns a new random (version 4) UUID as a string. It is a convenience 52 | // function for NewRandom().String(). 53 | func New() string { 54 | return NewRandom().String() 55 | } 56 | 57 | // Parse decodes s into a UUID or returns nil. Both the UUID form of 58 | // xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx and 59 | // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx are decoded. 60 | func Parse(s string) UUID { 61 | if len(s) == 36+9 { 62 | if strings.ToLower(s[:9]) != "urn:uuid:" { 63 | return nil 64 | } 65 | s = s[9:] 66 | } else if len(s) != 36 { 67 | return nil 68 | } 69 | if s[8] != '-' || s[13] != '-' || s[18] != '-' || s[23] != '-' { 70 | return nil 71 | } 72 | var uuid [16]byte 73 | for i, x := range [16]int{ 74 | 0, 2, 4, 6, 75 | 9, 11, 76 | 14, 16, 77 | 19, 21, 78 | 24, 26, 28, 30, 32, 34} { 79 | if v, ok := xtob(s[x:]); !ok { 80 | return nil 81 | } else { 82 | uuid[i] = v 83 | } 84 | } 85 | return uuid[:] 86 | } 87 | 88 | // Equal returns true if uuid1 and uuid2 are equal. 89 | func Equal(uuid1, uuid2 UUID) bool { 90 | return bytes.Equal(uuid1, uuid2) 91 | } 92 | 93 | // Array returns an array representation of uuid that can be used as a map key. 94 | // Array panics if uuid is not valid. 95 | func (uuid UUID) Array() Array { 96 | if len(uuid) != 16 { 97 | panic("invalid uuid") 98 | } 99 | var a Array 100 | copy(a[:], uuid) 101 | return a 102 | } 103 | 104 | // String returns the string form of uuid, xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx 105 | // , or "" if uuid is invalid. 106 | func (uuid UUID) String() string { 107 | if len(uuid) != 16 { 108 | return "" 109 | } 110 | var buf [36]byte 111 | encodeHex(buf[:], uuid) 112 | return string(buf[:]) 113 | } 114 | 115 | // URN returns the RFC 2141 URN form of uuid, 116 | // urn:uuid:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx, or "" if uuid is invalid. 117 | func (uuid UUID) URN() string { 118 | if len(uuid) != 16 { 119 | return "" 120 | } 121 | var buf [36 + 9]byte 122 | copy(buf[:], "urn:uuid:") 123 | encodeHex(buf[9:], uuid) 124 | return string(buf[:]) 125 | } 126 | 127 | func encodeHex(dst []byte, uuid UUID) { 128 | hex.Encode(dst[:], uuid[:4]) 129 | dst[8] = '-' 130 | hex.Encode(dst[9:13], uuid[4:6]) 131 | dst[13] = '-' 132 | hex.Encode(dst[14:18], uuid[6:8]) 133 | dst[18] = '-' 134 | hex.Encode(dst[19:23], uuid[8:10]) 135 | dst[23] = '-' 136 | hex.Encode(dst[24:], uuid[10:]) 137 | } 138 | 139 | // Variant returns the variant encoded in uuid. It returns Invalid if 140 | // uuid is invalid. 141 | func (uuid UUID) Variant() Variant { 142 | if len(uuid) != 16 { 143 | return Invalid 144 | } 145 | switch { 146 | case (uuid[8] & 0xc0) == 0x80: 147 | return RFC4122 148 | case (uuid[8] & 0xe0) == 0xc0: 149 | return Microsoft 150 | case (uuid[8] & 0xe0) == 0xe0: 151 | return Future 152 | default: 153 | return Reserved 154 | } 155 | } 156 | 157 | // Version returns the version of uuid. It returns false if uuid is not 158 | // valid. 159 | func (uuid UUID) Version() (Version, bool) { 160 | if len(uuid) != 16 { 161 | return 0, false 162 | } 163 | return Version(uuid[6] >> 4), true 164 | } 165 | 166 | func (v Version) String() string { 167 | if v > 15 { 168 | return fmt.Sprintf("BAD_VERSION_%d", v) 169 | } 170 | return fmt.Sprintf("VERSION_%d", v) 171 | } 172 | 173 | func (v Variant) String() string { 174 | switch v { 175 | case RFC4122: 176 | return "RFC4122" 177 | case Reserved: 178 | return "Reserved" 179 | case Microsoft: 180 | return "Microsoft" 181 | case Future: 182 | return "Future" 183 | case Invalid: 184 | return "Invalid" 185 | } 186 | return fmt.Sprintf("BadVariant%d", int(v)) 187 | } 188 | 189 | // SetRand sets the random number generator to r, which implements io.Reader. 190 | // If r.Read returns an error when the package requests random data then 191 | // a panic will be issued. 192 | // 193 | // Calling SetRand with nil sets the random number generator to the default 194 | // generator. 195 | func SetRand(r io.Reader) { 196 | if r == nil { 197 | rander = rand.Reader 198 | return 199 | } 200 | rander = r 201 | } 202 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/simplexml/dom/element.go: -------------------------------------------------------------------------------- 1 | package dom 2 | 3 | import ( 4 | "encoding/xml" 5 | "fmt" 6 | "bytes" 7 | ) 8 | 9 | type Attr struct { 10 | Name xml.Name // Attribute namespace and name. 11 | Value string // Attribute value. 12 | } 13 | 14 | type Element struct { 15 | name xml.Name 16 | children []*Element 17 | parent *Element 18 | content string 19 | attributes []*Attr 20 | namespaces []*Namespace 21 | document *Document 22 | } 23 | 24 | func CreateElement(n string) *Element { 25 | element := &Element { name: xml.Name { Local: n } } 26 | element.children = make([]*Element, 0, 5) 27 | element.attributes = make([]*Attr, 0, 10) 28 | element.namespaces = make([]*Namespace, 0, 10) 29 | return element 30 | } 31 | 32 | func (node *Element) AddChild(child *Element) *Element { 33 | if child.parent != nil { 34 | child.parent.RemoveChild(child) 35 | } 36 | child.SetParent(node) 37 | node.children = append(node.children, child) 38 | return node 39 | } 40 | 41 | func (node *Element) RemoveChild(child *Element) *Element { 42 | p := -1 43 | for i, v := range node.children { 44 | if v == child { 45 | p = i 46 | break 47 | } 48 | } 49 | 50 | if p == -1 { 51 | return node 52 | } 53 | 54 | copy(node.children[p:], node.children[p+1:]) 55 | node.children = node.children[0 : len(node.children)-1] 56 | child.parent = nil 57 | return node 58 | } 59 | 60 | func (node *Element) SetAttr(name string, value string) *Element { 61 | // namespaces? 62 | attr := &Attr{ Name: xml.Name { Local: name }, Value: value } 63 | node.attributes = append(node.attributes, attr) 64 | return node 65 | } 66 | 67 | func (node *Element) SetParent(parent *Element) *Element { 68 | node.parent = parent 69 | return node 70 | } 71 | 72 | func (node *Element) SetContent(content string) *Element { 73 | node.content = content 74 | return node 75 | } 76 | 77 | // Add a namespace declaration to this node 78 | func (node *Element) DeclareNamespace(ns Namespace) *Element { 79 | // check if we already have it 80 | prefix := node.namespacePrefix(ns.Uri) 81 | if prefix == ns.Prefix { 82 | return node 83 | } 84 | // add it 85 | node.namespaces = append(node.namespaces, &ns) 86 | return node 87 | } 88 | 89 | func (node *Element) DeclaredNamespaces() []*Namespace { 90 | return node.namespaces 91 | } 92 | 93 | func (node *Element) SetNamespace(prefix string, uri string) { 94 | resolved := node.namespacePrefix(uri) 95 | if resolved == "" { 96 | // we couldn't find the namespace, let's declare it at this node 97 | node.namespaces = append(node.namespaces, &Namespace { Prefix: prefix, Uri: uri }) 98 | } 99 | node.name.Space = uri 100 | } 101 | 102 | func (node *Element) Bytes(out *bytes.Buffer, indent bool, indentType string, level int) { 103 | empty := len(node.children) == 0 && node.content == "" 104 | content := node.content != "" 105 | // children := len(node.children) > 0 106 | // ns := len(node.namespaces) > 0 107 | // attrs := len(node.attributes) > 0 108 | 109 | indentStr := "" 110 | nextLine := "" 111 | if indent { 112 | nextLine = "\n" 113 | for i := 0; i < level; i++ { 114 | indentStr += indentType 115 | } 116 | } 117 | 118 | if node.name.Local != "" { 119 | if len(node.name.Space) > 0 { 120 | // first find if ns has been declared, otherwise 121 | prefix := node.namespacePrefix(node.name.Space) 122 | fmt.Fprintf(out, "%s<%s:%s", indentStr, prefix, node.name.Local) 123 | } else { 124 | fmt.Fprintf(out, "%s<%s", indentStr, node.name.Local) 125 | } 126 | } 127 | 128 | // declared namespaces 129 | for _, v := range node.namespaces { 130 | prefix := node.namespacePrefix(v.Uri) 131 | fmt.Fprintf(out, ` xmlns:%s="%s"`, prefix, v.Uri) 132 | } 133 | 134 | // attributes 135 | for _, v := range node.attributes { 136 | if len(v.Name.Space) > 0 { 137 | prefix := node.namespacePrefix(v.Name.Space) 138 | fmt.Fprintf(out, ` %s:%s="%s"`, prefix, v.Name.Local, v.Value) 139 | } else { 140 | fmt.Fprintf(out, ` %s="%s"`, v.Name.Local, v.Value) 141 | } 142 | } 143 | 144 | // close tag 145 | if empty { 146 | fmt.Fprintf(out, "/>%s", nextLine) 147 | } else { 148 | if content { 149 | out.WriteRune('>') 150 | } else { 151 | fmt.Fprintf(out, ">%s", nextLine) 152 | } 153 | } 154 | 155 | if len(node.children) > 0 { 156 | for _, child := range node.children { 157 | child.Bytes(out, indent, indentType, level + 1) 158 | } 159 | } else if node.content != "" { 160 | //val := []byte(node.content) 161 | //xml.EscapeText(out, val) 162 | out.WriteString(node.content) 163 | } 164 | 165 | if !empty && len(node.name.Local) > 0 { 166 | var indentation string 167 | if content { 168 | indentation = "" 169 | } else { 170 | indentation = indentStr 171 | } 172 | if len(node.name.Space) > 0 { 173 | prefix := node.namespacePrefix(node.name.Space) 174 | fmt.Fprintf(out, "%s\n", indentation, prefix, node.name.Local) 175 | } else { 176 | fmt.Fprintf(out, "%s\n", indentation, node.name.Local) 177 | } 178 | } 179 | } 180 | 181 | // Finds the prefix of the given namespace if it has been declared 182 | // in this node or in one of its parent 183 | func (node *Element) namespacePrefix(uri string) string { 184 | for _, ns := range node.namespaces { 185 | if ns.Uri == uri { 186 | return ns.Prefix 187 | } 188 | } 189 | if node.parent == nil { 190 | return "" 191 | } 192 | return node.parent.namespacePrefix(uri) 193 | } 194 | 195 | 196 | func (node *Element) String() string { 197 | var b bytes.Buffer 198 | node.Bytes(&b, false, "", 0) 199 | return string(b.Bytes()) 200 | } -------------------------------------------------------------------------------- /vendor/github.com/masterzen/winrm/client.go: -------------------------------------------------------------------------------- 1 | package winrm 2 | 3 | import ( 4 | "bytes" 5 | "crypto/x509" 6 | "fmt" 7 | "io" 8 | "sync" 9 | 10 | "github.com/masterzen/winrm/soap" 11 | ) 12 | 13 | // Client struct 14 | type Client struct { 15 | Parameters 16 | username string 17 | password string 18 | useHTTPS bool 19 | url string 20 | http Transporter 21 | } 22 | 23 | // Transporter does different transporters 24 | // and init a Post request based on them 25 | type Transporter interface { 26 | // init request baset on the transport configurations 27 | Post(*Client, *soap.SoapMessage) (string, error) 28 | Transport(*Endpoint) error 29 | } 30 | 31 | // NewClient will create a new remote client on url, connecting with user and password 32 | // This function doesn't connect (connection happens only when CreateShell is called) 33 | func NewClient(endpoint *Endpoint, user, password string) (*Client, error) { 34 | return NewClientWithParameters(endpoint, user, password, DefaultParameters) 35 | } 36 | 37 | // NewClientWithParameters will create a new remote client on url, connecting with user and password 38 | // This function doesn't connect (connection happens only when CreateShell is called) 39 | func NewClientWithParameters(endpoint *Endpoint, user, password string, params *Parameters) (*Client, error) { 40 | 41 | // alloc a new client 42 | client := &Client{ 43 | Parameters: *params, 44 | username: user, 45 | password: password, 46 | url: endpoint.url(), 47 | useHTTPS: endpoint.HTTPS, 48 | // default transport 49 | http: &clientRequest{}, 50 | } 51 | 52 | // switch to other transport if provided 53 | if params.TransportDecorator != nil { 54 | client.http = params.TransportDecorator() 55 | } 56 | 57 | // set the transport to some endpoint configuration 58 | if err := client.http.Transport(endpoint); err != nil { 59 | return nil, fmt.Errorf("Can't parse this key and certs: %s", err) 60 | } 61 | 62 | return client, nil 63 | } 64 | 65 | func readCACerts(certs []byte) (*x509.CertPool, error) { 66 | certPool := x509.NewCertPool() 67 | 68 | if !certPool.AppendCertsFromPEM(certs) { 69 | return nil, fmt.Errorf("Unable to read certificates") 70 | } 71 | 72 | return certPool, nil 73 | } 74 | 75 | // CreateShell will create a WinRM Shell, 76 | // which is the prealable for running commands. 77 | func (c *Client) CreateShell() (*Shell, error) { 78 | request := NewOpenShellRequest(c.url, &c.Parameters) 79 | defer request.Free() 80 | 81 | response, err := c.sendRequest(request) 82 | if err != nil { 83 | return nil, err 84 | } 85 | 86 | shellID, err := ParseOpenShellResponse(response) 87 | if err != nil { 88 | return nil, err 89 | } 90 | 91 | return c.NewShell(shellID), nil 92 | 93 | } 94 | 95 | // NewShell will create a new WinRM Shell for the given shellID 96 | func (c *Client) NewShell(id string) *Shell { 97 | return &Shell{client: c, id: id} 98 | } 99 | 100 | // sendRequest exec the custom http func from the client 101 | func (c *Client) sendRequest(request *soap.SoapMessage) (string, error) { 102 | return c.http.Post(c, request) 103 | } 104 | 105 | // Run will run command on the the remote host, writing the process stdout and stderr to 106 | // the given writers. Note with this method it isn't possible to inject stdin. 107 | func (c *Client) Run(command string, stdout io.Writer, stderr io.Writer) (int, error) { 108 | shell, err := c.CreateShell() 109 | if err != nil { 110 | return 1, err 111 | } 112 | defer shell.Close() 113 | cmd, err := shell.Execute(command) 114 | if err != nil { 115 | return 1, err 116 | } 117 | 118 | var wg sync.WaitGroup 119 | wg.Add(2) 120 | 121 | go func() { 122 | defer wg.Done() 123 | io.Copy(stdout, cmd.Stdout) 124 | }() 125 | 126 | go func() { 127 | defer wg.Done() 128 | io.Copy(stderr, cmd.Stderr) 129 | }() 130 | 131 | cmd.Wait() 132 | wg.Wait() 133 | 134 | return cmd.ExitCode(), cmd.err 135 | } 136 | 137 | // RunWithString will run command on the the remote host, returning the process stdout and stderr 138 | // as strings, and using the input stdin string as the process input 139 | func (c *Client) RunWithString(command string, stdin string) (string, string, int, error) { 140 | shell, err := c.CreateShell() 141 | if err != nil { 142 | return "", "", 1, err 143 | } 144 | defer shell.Close() 145 | 146 | cmd, err := shell.Execute(command) 147 | if err != nil { 148 | return "", "", 1, err 149 | } 150 | if len(stdin) > 0 { 151 | cmd.Stdin.Write([]byte(stdin)) 152 | } 153 | 154 | var outWriter, errWriter bytes.Buffer 155 | go io.Copy(&outWriter, cmd.Stdout) 156 | go io.Copy(&errWriter, cmd.Stderr) 157 | 158 | cmd.Wait() 159 | 160 | return outWriter.String(), errWriter.String(), cmd.ExitCode(), cmd.err 161 | } 162 | 163 | // RunWithInput will run command on the the remote host, writing the process stdout and stderr to 164 | // the given writers, and injecting the process stdin with the stdin reader. 165 | // Warning stdin (not stdout/stderr) are bufferized, which means reading only one byte in stdin will 166 | // send a winrm http packet to the remote host. If stdin is a pipe, it might be better for 167 | // performance reasons to buffer it. 168 | func (c Client) RunWithInput(command string, stdout, stderr io.Writer, stdin io.Reader) (int, error) { 169 | shell, err := c.CreateShell() 170 | if err != nil { 171 | return 1, err 172 | } 173 | defer shell.Close() 174 | cmd, err := shell.Execute(command) 175 | if err != nil { 176 | return 1, err 177 | } 178 | 179 | go io.Copy(cmd.Stdin, stdin) 180 | go io.Copy(stdout, cmd.Stdout) 181 | go io.Copy(stderr, cmd.Stderr) 182 | 183 | cmd.Wait() 184 | 185 | return cmd.ExitCode(), cmd.err 186 | 187 | } 188 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Terraform Microsoft SCVMM Provider 2 | 3 | This is the repository for the Terraform [Microsoft SCVMM][1] Provider, which one can use 4 | with Terraform to work with Microsoft SCVMM. 5 | 6 | [1]: https://docs.microsoft.com/en-us/system-center/vmm/ 7 | 8 | Coverage is currently only limited to Virtual Machine, Virtual Disk and Checkpoint but in the coming months we are planning release coverage for most essential Microsoft SCVMM workflows. 9 | Watch this space! 10 | 11 | For general information about Terraform, visit the [official website][3] and the 12 | [GitHub project page][4]. 13 | 14 | [3]: https://terraform.io/ 15 | [4]: https://github.com/hashicorp/terraform 16 | 17 | # Using the Provider 18 | 19 | The current version of this provider requires Terraform v0.10.2 or higher to 20 | run. 21 | 22 | Note that you need to run `terraform init` to fetch the provider before 23 | deploying. Read about the provider split and other changes to TF v0.10.0 in the 24 | official release announcement found [here][4]. 25 | 26 | [4]: https://www.hashicorp.com/blog/hashicorp-terraform-0-10/ 27 | 28 | ## Full Provider Documentation 29 | 30 | The provider is usefull in adding Virtual Machine, Virtual Disk and Checkpoint using Microsoft SCVMM. 31 | 32 | ### Example 33 | ```hcl 34 | # Configure the Microsoft SCVMM Provider 35 | provider "scvmm" { 36 | server_ip = "${var.scvmm_server_ip}" 37 | port = ${var.scvmm_server_port} 38 | user_name = "${var.scvmm_server_user}" 39 | user_password = "${var.scvmm_server_password}" 40 | } 41 | 42 | # Add a Virtual Machine 43 | resource "scvmm_virtual_machine" "CreateVM" { 44 | timeout = "10000" 45 | vmm_server = "WIN-2F929KU8HIU" 46 | vm_name = "Test_VM_demo01" 47 | template_name = "TestVMTemplate" 48 | cloud_name = "GSL Cloud" 49 | } 50 | 51 | #Add a Virtual Disk 52 | resource "scvmm_virtual_disk" "demoDisk" { 53 | timeout = 10000 54 | vmm_server = "${scvmm_virtual_machine.CreateVM.vmm_server}" 55 | vm_name = "${scvmm_virtual_machine.CreateVM.vm_name}" 56 | virtual_disk_name = "demo_disk" 57 | virtual_disk_size = 10000 58 | } 59 | 60 | resource "scvmm_checkpoint" "demoCheck" { 61 | timeout=1000 62 | vmm_server="${scvmm_virtual_disk.demoDisk.vmm_server}" 63 | vm_name="${scvmm_virtual_machine.CreateVM.vm_name}" 64 | checkpoint_name="demo_checkpoint" 65 | } 66 | ``` 67 | 68 | # Building The Provider 69 | 70 | **NOTE:** Unless you are [developing][7] or require a pre-release bugfix or feature, 71 | you will want to use the officially released version of the provider (see [the 72 | section above][8]). 73 | 74 | [7]: #developing-the-provider 75 | [8]: #using-the-provider 76 | 77 | 78 | ## Cloning the Project 79 | 80 | First, you will want to clone the repository to 81 | `$GOPATH/src/github.com/GSLabDev/terraform-provider-scvmm`: 82 | 83 | ```sh 84 | mkdir -p $GOPATH/src/github.com/GSLabDev/ 85 | cd $GOPATH/src/github.com/GSLabDev/ 86 | git clone git@github.com:terraform-providers/terraform-provider-scvmm 87 | ``` 88 | 89 | ## Running the Build 90 | 91 | After the clone has been completed, you can enter the provider directory and 92 | build the provider. 93 | 94 | ```sh 95 | cd $GOPATH/src/github.com/GSLabDev/terraform-provider-scvmm 96 | make 97 | ``` 98 | 99 | ## Installing the Local Plugin 100 | 101 | After the build is complete, copy the `terraform-provider-scvmm` binary into 102 | the same path as your `terraform` binary, and re-run `terraform init`. 103 | 104 | After this, your project-local `.terraform/plugins/ARCH/lock.json` (where `ARCH` 105 | matches the architecture of your machine) file should contain a SHA256 sum that 106 | matches the local plugin. Run `shasum -a 256` on the binary to verify the values 107 | match. 108 | 109 | # Developing the Provider 110 | 111 | If you wish to work on the provider, you'll first need [Go][9] installed on your 112 | machine (version 1.9+ is **required**). You'll also need to correctly setup a 113 | [GOPATH][10], as well as adding `$GOPATH/bin` to your `$PATH`. 114 | 115 | [9]: https://golang.org/ 116 | [10]: http://golang.org/doc/code.html#GOPATH 117 | 118 | See [Building the Provider][11] for details on building the provider. 119 | 120 | [11]: #building-the-provider 121 | 122 | # Testing the Provider 123 | 124 | **NOTE:** Testing the Microsoft SCVMM provider is currently a complex operation as it 125 | requires having a Microsoft SCVMM Server to test against. 126 | 127 | ## Configuring Environment Variables 128 | 129 | Most of the tests in this provider require a comprehensive list of environment 130 | variables to run. See the individual `*_test.go` files in the 131 | [`scvmm/`](scvmm/) directory for more details. The next section also 132 | describes how you can manage a configuration file of the test environment 133 | variables. 134 | 135 | ### Using the `.tf-scvmm-devrc.mk` file 136 | 137 | The [`tf-scvmm-devrc.mk.example`](tf-scvmm-devrc.mk.example) file contains 138 | an up-to-date list of environment variables required to run the acceptance 139 | tests. Copy this to `$HOME/.tf-scvmm-devrc.mk` and change the permissions to 140 | something more secure (ie: `chmod 600 $HOME/.tf-scvmm-devrc.mk`), and 141 | configure the variables accordingly. 142 | 143 | ## Running the Acceptance Tests 144 | 145 | After this is done, you can run the acceptance tests by running: 146 | 147 | ```sh 148 | $ make testacc 149 | ``` 150 | 151 | If you want to run against a specific set of tests, run `make testacc` with the 152 | `TESTARGS` parameter containing the run mask as per below: 153 | 154 | ```sh 155 | make testacc TESTARGS="-run=TestAccSCVMM" 156 | ``` 157 | 158 | This following example would run all of the acceptance tests matching 159 | `TestAccSCVMM`. Change this for the specific tests you want to 160 | run. 161 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/winrm/request.go: -------------------------------------------------------------------------------- 1 | package winrm 2 | 3 | import ( 4 | "encoding/base64" 5 | 6 | "github.com/masterzen/winrm/soap" 7 | "github.com/nu7hatch/gouuid" 8 | ) 9 | 10 | func genUUID() string { 11 | id, _ := uuid.NewV4() 12 | return "uuid:" + id.String() 13 | } 14 | 15 | func defaultHeaders(message *soap.SoapMessage, url string, params *Parameters) *soap.SoapHeader { 16 | return message. 17 | Header(). 18 | To(url). 19 | ReplyTo("http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous"). 20 | MaxEnvelopeSize(params.EnvelopeSize). 21 | Id(genUUID()). 22 | Locale(params.Locale). 23 | Timeout(params.Timeout) 24 | } 25 | 26 | //NewOpenShellRequest makes a new soap request 27 | func NewOpenShellRequest(uri string, params *Parameters) *soap.SoapMessage { 28 | if params == nil { 29 | params = DefaultParameters 30 | } 31 | 32 | message := soap.NewMessage() 33 | defaultHeaders(message, uri, params). 34 | Action("http://schemas.xmlsoap.org/ws/2004/09/transfer/Create"). 35 | ResourceURI("http://schemas.microsoft.com/wbem/wsman/1/windows/shell/cmd"). 36 | AddOption(soap.NewHeaderOption("WINRS_NOPROFILE", "FALSE")). 37 | AddOption(soap.NewHeaderOption("WINRS_CODEPAGE", "65001")). 38 | Build() 39 | 40 | body := message.CreateBodyElement("Shell", soap.DOM_NS_WIN_SHELL) 41 | input := message.CreateElement(body, "InputStreams", soap.DOM_NS_WIN_SHELL) 42 | input.SetContent("stdin") 43 | output := message.CreateElement(body, "OutputStreams", soap.DOM_NS_WIN_SHELL) 44 | output.SetContent("stdout stderr") 45 | 46 | return message 47 | } 48 | 49 | // NewDeleteShellRequest ... 50 | func NewDeleteShellRequest(uri, shellId string, params *Parameters) *soap.SoapMessage { 51 | if params == nil { 52 | params = DefaultParameters 53 | } 54 | message := soap.NewMessage() 55 | defaultHeaders(message, uri, params). 56 | Action("http://schemas.xmlsoap.org/ws/2004/09/transfer/Delete"). 57 | ShellId(shellId). 58 | ResourceURI("http://schemas.microsoft.com/wbem/wsman/1/windows/shell/cmd"). 59 | Build() 60 | 61 | message.NewBody() 62 | 63 | return message 64 | } 65 | 66 | // NewExecuteCommandRequest exec command on specific shellID 67 | func NewExecuteCommandRequest(uri, shellId, command string, arguments []string, params *Parameters) *soap.SoapMessage { 68 | if params == nil { 69 | params = DefaultParameters 70 | } 71 | message := soap.NewMessage() 72 | defaultHeaders(message, uri, params). 73 | Action("http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Command"). 74 | ResourceURI("http://schemas.microsoft.com/wbem/wsman/1/windows/shell/cmd"). 75 | ShellId(shellId). 76 | AddOption(soap.NewHeaderOption("WINRS_CONSOLEMODE_STDIN", "TRUE")). 77 | AddOption(soap.NewHeaderOption("WINRS_SKIP_CMD_SHELL", "FALSE")). 78 | Build() 79 | 80 | body := message.CreateBodyElement("CommandLine", soap.DOM_NS_WIN_SHELL) 81 | 82 | // ensure special characters like & don't mangle the request XML 83 | command = "" 84 | commandElement := message.CreateElement(body, "Command", soap.DOM_NS_WIN_SHELL) 85 | commandElement.SetContent(command) 86 | 87 | for _, arg := range arguments { 88 | arg = "" 89 | argumentsElement := message.CreateElement(body, "Arguments", soap.DOM_NS_WIN_SHELL) 90 | argumentsElement.SetContent(arg) 91 | } 92 | 93 | return message 94 | } 95 | 96 | func NewGetOutputRequest(uri, shellId, commandId, streams string, params *Parameters) *soap.SoapMessage { 97 | if params == nil { 98 | params = DefaultParameters 99 | } 100 | message := soap.NewMessage() 101 | defaultHeaders(message, uri, params). 102 | Action("http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Receive"). 103 | ResourceURI("http://schemas.microsoft.com/wbem/wsman/1/windows/shell/cmd"). 104 | ShellId(shellId). 105 | Build() 106 | 107 | receive := message.CreateBodyElement("Receive", soap.DOM_NS_WIN_SHELL) 108 | desiredStreams := message.CreateElement(receive, "DesiredStream", soap.DOM_NS_WIN_SHELL) 109 | desiredStreams.SetAttr("CommandId", commandId) 110 | desiredStreams.SetContent(streams) 111 | 112 | return message 113 | } 114 | 115 | func NewSendInputRequest(uri, shellId, commandId string, input []byte, params *Parameters) *soap.SoapMessage { 116 | if params == nil { 117 | params = DefaultParameters 118 | } 119 | message := soap.NewMessage() 120 | 121 | defaultHeaders(message, uri, params). 122 | Action("http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Send"). 123 | ResourceURI("http://schemas.microsoft.com/wbem/wsman/1/windows/shell/cmd"). 124 | ShellId(shellId). 125 | Build() 126 | 127 | content := base64.StdEncoding.EncodeToString(input) 128 | 129 | send := message.CreateBodyElement("Send", soap.DOM_NS_WIN_SHELL) 130 | streams := message.CreateElement(send, "Stream", soap.DOM_NS_WIN_SHELL) 131 | streams.SetAttr("Name", "stdin") 132 | streams.SetAttr("CommandId", commandId) 133 | streams.SetContent(content) 134 | return message 135 | } 136 | 137 | func NewSignalRequest(uri string, shellId string, commandId string, params *Parameters) *soap.SoapMessage { 138 | if params == nil { 139 | params = DefaultParameters 140 | } 141 | message := soap.NewMessage() 142 | 143 | defaultHeaders(message, uri, params). 144 | Action("http://schemas.microsoft.com/wbem/wsman/1/windows/shell/Signal"). 145 | ResourceURI("http://schemas.microsoft.com/wbem/wsman/1/windows/shell/cmd"). 146 | ShellId(shellId). 147 | Build() 148 | 149 | signal := message.CreateBodyElement("Signal", soap.DOM_NS_WIN_SHELL) 150 | signal.SetAttr("CommandId", commandId) 151 | code := message.CreateElement(signal, "Code", soap.DOM_NS_WIN_SHELL) 152 | code.SetContent("http://schemas.microsoft.com/wbem/wsman/1/windows/shell/signal/terminate") 153 | 154 | return message 155 | } 156 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/winrm/command.go: -------------------------------------------------------------------------------- 1 | package winrm 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "io" 7 | "strings" 8 | ) 9 | 10 | type commandWriter struct { 11 | *Command 12 | eof bool 13 | } 14 | 15 | type commandReader struct { 16 | *Command 17 | write *io.PipeWriter 18 | read *io.PipeReader 19 | stream string 20 | } 21 | 22 | // Command represents a given command running on a Shell. This structure allows to get access 23 | // to the various stdout, stderr and stdin pipes. 24 | type Command struct { 25 | client *Client 26 | shell *Shell 27 | id string 28 | exitCode int 29 | finished bool 30 | err error 31 | 32 | Stdin *commandWriter 33 | Stdout *commandReader 34 | Stderr *commandReader 35 | 36 | done chan struct{} 37 | cancel chan struct{} 38 | } 39 | 40 | func newCommand(shell *Shell, ids string) *Command { 41 | command := &Command{ 42 | shell: shell, 43 | client: shell.client, 44 | id: ids, 45 | exitCode: 0, 46 | err: nil, 47 | done: make(chan struct{}), 48 | cancel: make(chan struct{}), 49 | } 50 | 51 | command.Stdout = newCommandReader("stdout", command) 52 | command.Stdin = &commandWriter{ 53 | Command: command, 54 | eof: false, 55 | } 56 | command.Stderr = newCommandReader("stderr", command) 57 | 58 | go fetchOutput(command) 59 | 60 | return command 61 | } 62 | 63 | func newCommandReader(stream string, command *Command) *commandReader { 64 | read, write := io.Pipe() 65 | return &commandReader{ 66 | Command: command, 67 | stream: stream, 68 | write: write, 69 | read: read, 70 | } 71 | } 72 | 73 | func fetchOutput(command *Command) { 74 | for { 75 | select { 76 | case <-command.cancel: 77 | close(command.done) 78 | return 79 | default: 80 | finished, err := command.slurpAllOutput() 81 | if finished { 82 | command.err = err 83 | close(command.done) 84 | return 85 | } 86 | } 87 | } 88 | } 89 | 90 | func (c *Command) check() error { 91 | if c.id == "" { 92 | return errors.New("Command has already been closed") 93 | } 94 | if c.shell == nil { 95 | return errors.New("Command has no associated shell") 96 | } 97 | if c.client == nil { 98 | return errors.New("Command has no associated client") 99 | } 100 | return nil 101 | } 102 | 103 | // Close will terminate the running command 104 | func (c *Command) Close() error { 105 | if err := c.check(); err != nil { 106 | return err 107 | } 108 | 109 | select { // close cancel channel if it's still open 110 | case <-c.cancel: 111 | default: 112 | close(c.cancel) 113 | } 114 | 115 | request := NewSignalRequest(c.client.url, c.shell.id, c.id, &c.client.Parameters) 116 | defer request.Free() 117 | 118 | _, err := c.client.sendRequest(request) 119 | return err 120 | } 121 | 122 | func (c *Command) slurpAllOutput() (bool, error) { 123 | if err := c.check(); err != nil { 124 | c.Stderr.write.CloseWithError(err) 125 | c.Stdout.write.CloseWithError(err) 126 | return true, err 127 | } 128 | 129 | request := NewGetOutputRequest(c.client.url, c.shell.id, c.id, "stdout stderr", &c.client.Parameters) 130 | defer request.Free() 131 | 132 | response, err := c.client.sendRequest(request) 133 | if err != nil { 134 | if strings.Contains(err.Error(), "OperationTimeout") { 135 | // Operation timeout because there was no command output 136 | return false, err 137 | } 138 | if strings.Contains(err.Error(), "EOF") { 139 | c.exitCode = 16001 140 | } 141 | 142 | c.Stderr.write.CloseWithError(err) 143 | c.Stdout.write.CloseWithError(err) 144 | return true, err 145 | } 146 | 147 | var exitCode int 148 | var stdout, stderr bytes.Buffer 149 | finished, exitCode, err := ParseSlurpOutputErrResponse(response, &stdout, &stderr) 150 | if err != nil { 151 | c.Stderr.write.CloseWithError(err) 152 | c.Stdout.write.CloseWithError(err) 153 | return true, err 154 | } 155 | if stdout.Len() > 0 { 156 | c.Stdout.write.Write(stdout.Bytes()) 157 | } 158 | if stderr.Len() > 0 { 159 | c.Stderr.write.Write(stderr.Bytes()) 160 | } 161 | if finished { 162 | c.exitCode = exitCode 163 | c.Stderr.write.Close() 164 | c.Stdout.write.Close() 165 | } 166 | 167 | return finished, nil 168 | } 169 | 170 | func (c *Command) sendInput(data []byte) error { 171 | if err := c.check(); err != nil { 172 | return err 173 | } 174 | 175 | request := NewSendInputRequest(c.client.url, c.shell.id, c.id, data, &c.client.Parameters) 176 | defer request.Free() 177 | 178 | _, err := c.client.sendRequest(request) 179 | return err 180 | } 181 | 182 | // ExitCode returns command exit code when it is finished. Before that the result is always 0. 183 | func (c *Command) ExitCode() int { 184 | return c.exitCode 185 | } 186 | 187 | // Wait function will block the current goroutine until the remote command terminates. 188 | func (c *Command) Wait() { 189 | // block until finished 190 | <-c.done 191 | } 192 | 193 | // Write data to this Pipe 194 | // commandWriter implements io.Writer interface 195 | func (w *commandWriter) Write(data []byte) (int, error) { 196 | 197 | var ( 198 | written int 199 | err error 200 | ) 201 | 202 | for len(data) > 0 { 203 | if w.eof { 204 | return written, io.EOF 205 | } 206 | // never send more data than our EnvelopeSize. 207 | n := min(w.client.Parameters.EnvelopeSize-1000, len(data)) 208 | if err := w.sendInput(data[:n]); err != nil { 209 | break 210 | } 211 | data = data[n:] 212 | written += n 213 | } 214 | 215 | return written, err 216 | } 217 | 218 | func min(a int, b int) int { 219 | if a < b { 220 | return a 221 | } 222 | return b 223 | } 224 | 225 | // Close method wrapper 226 | // commandWriter implements io.Closer interface 227 | func (w *commandWriter) Close() error { 228 | w.eof = true 229 | return w.Close() 230 | } 231 | 232 | // Read data from this Pipe 233 | func (r *commandReader) Read(buf []byte) (int, error) { 234 | n, err := r.read.Read(buf) 235 | if err != nil && err != io.EOF { 236 | return 0, err 237 | } 238 | return n, err 239 | } 240 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/azure-sdk-for-go/core/http/chunked.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // The wire protocol for HTTP's "chunked" Transfer-Encoding. 6 | 7 | // This code is duplicated in net/http and net/http/httputil. 8 | // Please make any changes in both files. 9 | 10 | package http 11 | 12 | import ( 13 | "bufio" 14 | "bytes" 15 | "errors" 16 | "fmt" 17 | "io" 18 | ) 19 | 20 | const maxLineLength = 4096 // assumed <= bufio.defaultBufSize 21 | 22 | var ErrLineTooLong = errors.New("header line too long") 23 | 24 | // newChunkedReader returns a new chunkedReader that translates the data read from r 25 | // out of HTTP "chunked" format before returning it. 26 | // The chunkedReader returns io.EOF when the final 0-length chunk is read. 27 | // 28 | // newChunkedReader is not needed by normal applications. The http package 29 | // automatically decodes chunking when reading response bodies. 30 | func newChunkedReader(r io.Reader) io.Reader { 31 | br, ok := r.(*bufio.Reader) 32 | if !ok { 33 | br = bufio.NewReader(r) 34 | } 35 | return &chunkedReader{r: br} 36 | } 37 | 38 | type chunkedReader struct { 39 | r *bufio.Reader 40 | n uint64 // unread bytes in chunk 41 | err error 42 | buf [2]byte 43 | } 44 | 45 | func (cr *chunkedReader) beginChunk() { 46 | // chunk-size CRLF 47 | var line []byte 48 | line, cr.err = readLine(cr.r) 49 | if cr.err != nil { 50 | return 51 | } 52 | cr.n, cr.err = parseHexUint(line) 53 | if cr.err != nil { 54 | return 55 | } 56 | if cr.n == 0 { 57 | cr.err = io.EOF 58 | } 59 | } 60 | 61 | func (cr *chunkedReader) chunkHeaderAvailable() bool { 62 | n := cr.r.Buffered() 63 | if n > 0 { 64 | peek, _ := cr.r.Peek(n) 65 | return bytes.IndexByte(peek, '\n') >= 0 66 | } 67 | return false 68 | } 69 | 70 | func (cr *chunkedReader) Read(b []uint8) (n int, err error) { 71 | for cr.err == nil { 72 | if cr.n == 0 { 73 | if n > 0 && !cr.chunkHeaderAvailable() { 74 | // We've read enough. Don't potentially block 75 | // reading a new chunk header. 76 | break 77 | } 78 | cr.beginChunk() 79 | continue 80 | } 81 | if len(b) == 0 { 82 | break 83 | } 84 | rbuf := b 85 | if uint64(len(rbuf)) > cr.n { 86 | rbuf = rbuf[:cr.n] 87 | } 88 | var n0 int 89 | n0, cr.err = cr.r.Read(rbuf) 90 | n += n0 91 | b = b[n0:] 92 | cr.n -= uint64(n0) 93 | // If we're at the end of a chunk, read the next two 94 | // bytes to verify they are "\r\n". 95 | if cr.n == 0 && cr.err == nil { 96 | if _, cr.err = io.ReadFull(cr.r, cr.buf[:2]); cr.err == nil { 97 | if cr.buf[0] != '\r' || cr.buf[1] != '\n' { 98 | cr.err = errors.New("malformed chunked encoding") 99 | } 100 | } 101 | } 102 | } 103 | return n, cr.err 104 | } 105 | 106 | // Read a line of bytes (up to \n) from b. 107 | // Give up if the line exceeds maxLineLength. 108 | // The returned bytes are a pointer into storage in 109 | // the bufio, so they are only valid until the next bufio read. 110 | func readLine(b *bufio.Reader) (p []byte, err error) { 111 | if p, err = b.ReadSlice('\n'); err != nil { 112 | // We always know when EOF is coming. 113 | // If the caller asked for a line, there should be a line. 114 | if err == io.EOF { 115 | err = io.ErrUnexpectedEOF 116 | } else if err == bufio.ErrBufferFull { 117 | err = ErrLineTooLong 118 | } 119 | return nil, err 120 | } 121 | if len(p) >= maxLineLength { 122 | return nil, ErrLineTooLong 123 | } 124 | return trimTrailingWhitespace(p), nil 125 | } 126 | 127 | func trimTrailingWhitespace(b []byte) []byte { 128 | for len(b) > 0 && isASCIISpace(b[len(b)-1]) { 129 | b = b[:len(b)-1] 130 | } 131 | return b 132 | } 133 | 134 | func isASCIISpace(b byte) bool { 135 | return b == ' ' || b == '\t' || b == '\n' || b == '\r' 136 | } 137 | 138 | // newChunkedWriter returns a new chunkedWriter that translates writes into HTTP 139 | // "chunked" format before writing them to w. Closing the returned chunkedWriter 140 | // sends the final 0-length chunk that marks the end of the stream. 141 | // 142 | // newChunkedWriter is not needed by normal applications. The http 143 | // package adds chunking automatically if handlers don't set a 144 | // Content-Length header. Using newChunkedWriter inside a handler 145 | // would result in double chunking or chunking with a Content-Length 146 | // length, both of which are wrong. 147 | func newChunkedWriter(w io.Writer) io.WriteCloser { 148 | return &chunkedWriter{w} 149 | } 150 | 151 | // Writing to chunkedWriter translates to writing in HTTP chunked Transfer 152 | // Encoding wire format to the underlying Wire chunkedWriter. 153 | type chunkedWriter struct { 154 | Wire io.Writer 155 | } 156 | 157 | // Write the contents of data as one chunk to Wire. 158 | // NOTE: Note that the corresponding chunk-writing procedure in Conn.Write has 159 | // a bug since it does not check for success of io.WriteString 160 | func (cw *chunkedWriter) Write(data []byte) (n int, err error) { 161 | 162 | // Don't send 0-length data. It looks like EOF for chunked encoding. 163 | if len(data) == 0 { 164 | return 0, nil 165 | } 166 | 167 | if _, err = fmt.Fprintf(cw.Wire, "%x\r\n", len(data)); err != nil { 168 | return 0, err 169 | } 170 | if n, err = cw.Wire.Write(data); err != nil { 171 | return 172 | } 173 | if n != len(data) { 174 | err = io.ErrShortWrite 175 | return 176 | } 177 | _, err = io.WriteString(cw.Wire, "\r\n") 178 | 179 | return 180 | } 181 | 182 | func (cw *chunkedWriter) Close() error { 183 | _, err := io.WriteString(cw.Wire, "0\r\n") 184 | return err 185 | } 186 | 187 | func parseHexUint(v []byte) (n uint64, err error) { 188 | for _, b := range v { 189 | n <<= 4 190 | switch { 191 | case '0' <= b && b <= '9': 192 | b = b - '0' 193 | case 'a' <= b && b <= 'f': 194 | b = b - 'a' + 10 195 | case 'A' <= b && b <= 'F': 196 | b = b - 'A' + 10 197 | default: 198 | return 0, errors.New("invalid byte in chunk length") 199 | } 200 | n |= uint64(b) 201 | } 202 | return 203 | } 204 | -------------------------------------------------------------------------------- /scvmm/resource_scvmm_virtual_machine_test.go: -------------------------------------------------------------------------------- 1 | package scvmm 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "testing" 7 | 8 | "github.com/hashicorp/terraform/helper/resource" 9 | "github.com/hashicorp/terraform/terraform" 10 | "github.com/masterzen/winrm" 11 | ) 12 | 13 | func testBasicPreCheckVirtualMachine(t *testing.T) { 14 | if v := os.Getenv("SCVMM_VMM_SERVER"); v == "" { 15 | t.Fatal("SCVMM_VMM_SERVER must be set for acceptance tests") 16 | } 17 | if v := os.Getenv("SCVMM_TEMPLATE_NAME"); v == "" { 18 | t.Fatal("SCVMM_TEMPLATE_NAME must be set for acceptance tests") 19 | } 20 | if v := os.Getenv("SCVMM_CLOUD_NAME"); v == "" { 21 | t.Fatal("SCVMM_CLOUD_NAME must be set for acceptance tests") 22 | } 23 | } 24 | 25 | func TestAccVirtualMachineCreate_Basic(t *testing.T) { 26 | resourceName := "scvmm_virtual_machine.CreateVM" 27 | resource.Test(t, resource.TestCase{ 28 | PreCheck: func() { 29 | testAccPreCheck(t) 30 | testBasicPreCheckVirtualMachine(t) 31 | }, 32 | Providers: testAccProviders, 33 | CheckDestroy: testAccCheckVirtualMachineDestroy(resourceName), 34 | Steps: []resource.TestStep{ 35 | resource.TestStep{ 36 | Config: testAccCheckVirtualMachineConfigBasic(), 37 | Check: resource.ComposeTestCheckFunc( 38 | testAccCheckVirtualMachineExists(resourceName), 39 | resource.TestCheckResourceAttr( 40 | resourceName, "vm_name", "terraformVM"), 41 | resource.TestCheckResourceAttr( 42 | resourceName, "vmm_server", os.Getenv("SCVMM_VMM_SERVER")), 43 | ), 44 | }, 45 | }, 46 | }) 47 | } 48 | 49 | func testAccCheckVirtualMachineDestroy(n string) resource.TestCheckFunc { 50 | return func(s *terraform.State) error { 51 | rs, ok := s.RootModule().Resources[n] 52 | if !ok { 53 | return fmt.Errorf("Not found: %s", n) 54 | } 55 | org := testAccProvider.Meta().(*winrm.Client) 56 | script := "[CmdletBinding(SupportsShouldProcess=$true)]\nparam (\n \n [Parameter(Mandatory=$true,HelpMessage=\"Enter VmmServer\")]\n [string]$vmmServer,\n [Parameter(Mandatory=$true,HelpMessage=\"Enter VM Name\")]\n [string]$vmName\n)\n\nBegin\n{\n If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] \"Administrator\"))\n { \n $arguments = \"\" + $myinvocation.mycommand.definition + \" \"\n $myinvocation.BoundParameters.Values | foreach{$arguments += \"'$_' \" }\n echo $arguments\n Start-Process powershell -Verb runAs -ArgumentList $arguments\n Break\n }\n\u0009 try\n\u0009 {\n if($vmName -eq $null) \n {\n echo \"VM Name not entered\"\n exit\n } \n #gets virtual machine objects from the Virtual Machine Manager database\n Set-SCVMMServer -VMMServer $vmmServer > $null\n\u0009\u0009 $VM = Get-SCVirtualMachine | Where-Object {$_.Name -Eq $vmName } \n #check if VM Exists\n if($VM -eq $null)\n { \n Write-Error \"VM does not exists\"\n exit\n }\n \n }\n\u0009 catch [Exception]\n {\n Write-Error $_.Exception.Message\n\u0009 }\n \n \n}\n" 57 | arguments := rs.Primary.Attributes["vmm_server"] + " " + rs.Primary.Attributes["vm_name"] 58 | filename := "DeleteVM_Test" 59 | result, err := execScript(org, script, filename, arguments) 60 | if err == "" { 61 | return fmt.Errorf("Virtual Machine still exists: %v", result) 62 | } 63 | return nil 64 | } 65 | } 66 | 67 | func testAccCheckVirtualMachineExists(n string) resource.TestCheckFunc { 68 | return func(s *terraform.State) error { 69 | rs, ok := s.RootModule().Resources[n] 70 | if !ok { 71 | return fmt.Errorf("Not found: %s", n) 72 | } 73 | if rs.Primary.ID == "" { 74 | return fmt.Errorf("No Vm ID is set") 75 | } 76 | org := testAccProvider.Meta().(*winrm.Client) 77 | 78 | script := "[CmdletBinding(SupportsShouldProcess=$true)]\nparam (\n \n [Parameter(Mandatory=$true,HelpMessage=\"Enter VmmServer\")]\n [string]$vmmServer,\n [Parameter(Mandatory=$true,HelpMessage=\"Enter VM Name\")]\n [string]$vmName\n)\n\nBegin\n{\n If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] \"Administrator\"))\n { \n $arguments = \"\" + $myinvocation.mycommand.definition + \" \"\n $myinvocation.BoundParameters.Values | foreach{$arguments += \"'$_' \" }\n echo $arguments\n Start-Process powershell -Verb runAs -ArgumentList $arguments\n Break\n }\n\u0009 try\n\u0009 {\n if($vmName -eq $null) \n {\n echo \"VM Name not entered\"\n exit\n } \n #gets virtual machine objects from the Virtual Machine Manager database\n Set-SCVMMServer -VMMServer $vmmServer > $null\n\u0009\u0009 $VM = Get-SCVirtualMachine | Where-Object {$_.Name -Eq $vmName } \n #check if VM Exists\n if($VM -eq $null)\n { \n Write-Error \"VM does not exists\"\n exit\n }\n \n }\n\u0009 catch [Exception]\n {\n Write-Error $_.Exception.Message\n\u0009 }\n \n \n}\n" 79 | arguments := os.Getenv("SCVMM_VMM_SERVER") + " terraformVM" 80 | filename := "CreateVM_Test" 81 | result, err := execScript(org, script, filename, arguments) 82 | if err != "" { 83 | return fmt.Errorf("Error while getting the VM %v", result) 84 | } 85 | return nil 86 | } 87 | } 88 | 89 | func testAccCheckVirtualMachineConfigBasic() string { 90 | return fmt.Sprintf(` 91 | resource "scvmm_virtual_machine" "CreateVM" { 92 | timeout = "1000" 93 | vmm_server = "%s" 94 | vm_name = "terraformVM" 95 | template_name = "%s" 96 | cloud_name = "%s" 97 | }`, os.Getenv("SCVMM_VMM_SERVER"), 98 | os.Getenv("SCVMM_TEMPLATE_NAME"), 99 | os.Getenv("SCVMM_CLOUD_NAME")) 100 | } 101 | -------------------------------------------------------------------------------- /scvmm/resource_scvmm_checkpoint_test.go: -------------------------------------------------------------------------------- 1 | package scvmm 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "testing" 7 | 8 | "github.com/hashicorp/terraform/helper/resource" 9 | "github.com/hashicorp/terraform/terraform" 10 | "github.com/masterzen/winrm" 11 | ) 12 | 13 | func testBasicPreCheckSP(t *testing.T) { 14 | if v := os.Getenv("SCVMM_VMM_SERVER"); v == "" { 15 | t.Fatal("SCVMM_VMM_SERVER must be set for acceptance tests") 16 | } 17 | if v := os.Getenv("SCVMM_TEMPLATE_NAME"); v == "" { 18 | t.Fatal("SCVMM_TEMPLATE_NAME must be set for acceptance tests") 19 | } 20 | if v := os.Getenv("SCVMM_CLOUD_NAME"); v == "" { 21 | t.Fatal("SCVMM_CLOUD_NAME must be set for acceptance tests") 22 | } 23 | } 24 | 25 | func TestAccsp_Basic(t *testing.T) { 26 | 27 | resourceName := "scvmm_checkpoint.CreateCheckpoint" 28 | resource.Test(t, resource.TestCase{ 29 | PreCheck: func() { 30 | testAccPreCheck(t) 31 | testBasicPreCheckSP(t) 32 | }, 33 | Providers: testAccProviders, 34 | CheckDestroy: testAccCheckCheckpointDestroy(resourceName), 35 | Steps: []resource.TestStep{ 36 | resource.TestStep{ 37 | Config: testAccCheckCheckpointConfigBasic(), 38 | Check: resource.ComposeTestCheckFunc( 39 | testAccCheckCheckpointExists(resourceName), 40 | resource.TestCheckResourceAttr( 41 | resourceName, "vm_name", "terraformVM"), 42 | resource.TestCheckResourceAttr( 43 | resourceName, "checkpoint_name", "terraformCheckpoint"), 44 | ), 45 | }, 46 | }, 47 | }) 48 | } 49 | 50 | func testAccCheckCheckpointDestroy(n string) resource.TestCheckFunc { 51 | return func(s *terraform.State) error { 52 | rs, ok := s.RootModule().Resources[n] 53 | 54 | if !ok { 55 | return fmt.Errorf("Not found: %s", n) 56 | } 57 | org := testAccProvider.Meta().(*winrm.Client) 58 | 59 | script := "[CmdletBinding(SupportsShouldProcess=$true)]\nparam(\n [parameter(Mandatory=$true,HelpMessage=\"Enter VMMServer\")]\n [string]$vmmServer,\n\n [parameter(Mandatory=$true,HelpMessage=\"Enter Virtual Machine Name\")]\n [string]$vmName,\n\n [parameter(Mandatory=$true,HelpMessage=\"Enter Checkpoint Name\")]\n [string]$checkpointName\n)\nBegin\n{ \n If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] \"Administrator\"))\n { $arguments = \"\" + $myinvocation.mycommand.definition + \" \"\n $myinvocation.BoundParameters.Values | foreach{\n $arguments += \"'$_' \"\n }\n echo $arguments\n Start-Process powershell -Verb runAs -ArgumentList $arguments\n Break\n } \n \n try\n\u0009 {\n\u0009\u0009 Set-SCVMMServer -VMMServer $vmmServer > $null\n \n $checkpoint = Get-SCVMCheckpoint -VM $vmName | Where-Object {$_.Name -eq $checkpointName}\n if($checkpoint-eq $null)\n {\n Write-Error \"No Checkpoint found\"\n } \n }catch [Exception]\n\u0009 {\n\u0009\u0009 echo $_.Exception.Message\n } \n}" 60 | arguments := rs.Primary.Attributes["vmm_server"] + " " + rs.Primary.Attributes["vm_name"] + " " + rs.Primary.Attributes["checkpoint_name"] 61 | filename := "deletecp" 62 | result, err := execScript(org, script, filename, arguments) 63 | 64 | if err == "" { 65 | return fmt.Errorf("Checkpoint still exists: %v", result) 66 | } 67 | return nil 68 | } 69 | 70 | } 71 | 72 | func testAccCheckCheckpointExists(n string) resource.TestCheckFunc { 73 | return func(s *terraform.State) error { 74 | rs, ok := s.RootModule().Resources[n] 75 | 76 | if !ok { 77 | return fmt.Errorf("Not found: %s", n) 78 | } 79 | 80 | if rs.Primary.ID == "" { 81 | return fmt.Errorf("No Vm ID is set") 82 | } 83 | 84 | org := testAccProvider.Meta().(*winrm.Client) 85 | 86 | script := "[CmdletBinding(SupportsShouldProcess=$true)]\nparam(\n [parameter(Mandatory=$true,HelpMessage=\"Enter VMMServer\")]\n [string]$vmmServer,\n\n [parameter(Mandatory=$true,HelpMessage=\"Enter Virtual Machine Name\")]\n [string]$vmName,\n\n [parameter(Mandatory=$true,HelpMessage=\"Enter Checkpoint Name\")]\n [string]$checkpointName\n)\nBegin\n{ \n If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] \"Administrator\"))\n { $arguments = \"\" + $myinvocation.mycommand.definition + \" \"\n $myinvocation.BoundParameters.Values | foreach{\n $arguments += \"'$_' \"\n }\n echo $arguments\n Start-Process powershell -Verb runAs -ArgumentList $arguments\n Break\n } \n \n try\n\u0009 {\n\u0009\u0009 Set-SCVMMServer -VMMServer $vmmServer > $null\n \n $checkpoint = Get-SCVMCheckpoint -VM $vmName | Where-Object {$_.Name -eq $checkpointName}\n if($checkpoint-eq $null)\n {\n Write-Error \"No Checkpoint found\"\n } \n }catch [Exception]\n\u0009 {\n\u0009\u0009 echo $_.Exception.Message\n } \n}" 87 | arguments := rs.Primary.Attributes["vmm_server"] + " " + rs.Primary.Attributes["vm_name"] + " " + rs.Primary.Attributes["checkpoint_name"] 88 | filename := "createcp" 89 | result, err := execScript(org, script, filename, arguments) 90 | 91 | if err != "" { 92 | return fmt.Errorf("Error while getting the checkpoint %v", result) 93 | } 94 | 95 | return nil 96 | } 97 | } 98 | 99 | func testAccCheckCheckpointConfigBasic() string { 100 | return fmt.Sprintf(` 101 | resource "scvmm_virtual_machine" "CreateVM" { 102 | timeout = "1000" 103 | vmm_server = "%s" 104 | vm_name = "terraformVM" 105 | template_name = "%s" 106 | cloud_name = "%s" 107 | } 108 | resource "scvmm_checkpoint" "CreateCheckpoint" { 109 | timeout = "1000" 110 | vmm_server = "${scvmm_virtual_machine.CreateVM.vmm_server}" 111 | vm_name = "${scvmm_virtual_machine.CreateVM.vm_name}" 112 | checkpoint_name= "terraformCheckpoint" 113 | }`, os.Getenv("SCVMM_VMM_SERVER"), 114 | os.Getenv("SCVMM_TEMPLATE_NAME"), 115 | os.Getenv("SCVMM_CLOUD_NAME")) 116 | 117 | } 118 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/azure-sdk-for-go/core/http/sniff.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package http 6 | 7 | import ( 8 | "bytes" 9 | "encoding/binary" 10 | ) 11 | 12 | // The algorithm uses at most sniffLen bytes to make its decision. 13 | const sniffLen = 512 14 | 15 | // DetectContentType implements the algorithm described 16 | // at http://mimesniff.spec.whatwg.org/ to determine the 17 | // Content-Type of the given data. It considers at most the 18 | // first 512 bytes of data. DetectContentType always returns 19 | // a valid MIME type: if it cannot determine a more specific one, it 20 | // returns "application/octet-stream". 21 | func DetectContentType(data []byte) string { 22 | if len(data) > sniffLen { 23 | data = data[:sniffLen] 24 | } 25 | 26 | // Index of the first non-whitespace byte in data. 27 | firstNonWS := 0 28 | for ; firstNonWS < len(data) && isWS(data[firstNonWS]); firstNonWS++ { 29 | } 30 | 31 | for _, sig := range sniffSignatures { 32 | if ct := sig.match(data, firstNonWS); ct != "" { 33 | return ct 34 | } 35 | } 36 | 37 | return "application/octet-stream" // fallback 38 | } 39 | 40 | func isWS(b byte) bool { 41 | return bytes.IndexByte([]byte("\t\n\x0C\r "), b) != -1 42 | } 43 | 44 | type sniffSig interface { 45 | // match returns the MIME type of the data, or "" if unknown. 46 | match(data []byte, firstNonWS int) string 47 | } 48 | 49 | // Data matching the table in section 6. 50 | var sniffSignatures = []sniffSig{ 51 | htmlSig("' { 159 | return "" 160 | } 161 | return "text/html; charset=utf-8" 162 | } 163 | 164 | type mp4Sig int 165 | 166 | func (mp4Sig) match(data []byte, firstNonWS int) string { 167 | // c.f. section 6.1. 168 | if len(data) < 8 { 169 | return "" 170 | } 171 | boxSize := int(binary.BigEndian.Uint32(data[:4])) 172 | if boxSize%4 != 0 || len(data) < boxSize { 173 | return "" 174 | } 175 | if !bytes.Equal(data[4:8], []byte("ftyp")) { 176 | return "" 177 | } 178 | for st := 8; st < boxSize; st += 4 { 179 | if st == 12 { 180 | // minor version number 181 | continue 182 | } 183 | seg := string(data[st : st+3]) 184 | switch seg { 185 | case "mp4", "iso", "M4V", "M4P", "M4B": 186 | return "video/mp4" 187 | /* The remainder are not in the spec. 188 | case "M4A": 189 | return "audio/mp4" 190 | case "3gp": 191 | return "video/3gpp" 192 | case "jp2": 193 | return "image/jp2" // JPEG 2000 194 | */ 195 | } 196 | } 197 | return "" 198 | } 199 | 200 | type textSig int 201 | 202 | func (textSig) match(data []byte, firstNonWS int) string { 203 | // c.f. section 5, step 4. 204 | for _, b := range data[firstNonWS:] { 205 | switch { 206 | case 0x00 <= b && b <= 0x08, 207 | b == 0x0B, 208 | 0x0E <= b && b <= 0x1A, 209 | 0x1C <= b && b <= 0x1F: 210 | return "" 211 | } 212 | } 213 | return "text/plain; charset=utf-8" 214 | } 215 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/azure-sdk-for-go/core/http/header.go: -------------------------------------------------------------------------------- 1 | // Copyright 2010 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package http 6 | 7 | import ( 8 | "io" 9 | "net/textproto" 10 | "sort" 11 | "strings" 12 | "sync" 13 | "time" 14 | ) 15 | 16 | var raceEnabled = false // set by race.go 17 | 18 | // A Header represents the key-value pairs in an HTTP header. 19 | type Header map[string][]string 20 | 21 | // Add adds the key, value pair to the header. 22 | // It appends to any existing values associated with key. 23 | func (h Header) Add(key, value string) { 24 | textproto.MIMEHeader(h).Add(key, value) 25 | } 26 | 27 | // Set sets the header entries associated with key to 28 | // the single element value. It replaces any existing 29 | // values associated with key. 30 | func (h Header) Set(key, value string) { 31 | textproto.MIMEHeader(h).Set(key, value) 32 | } 33 | 34 | // Get gets the first value associated with the given key. 35 | // If there are no values associated with the key, Get returns "". 36 | // To access multiple values of a key, access the map directly 37 | // with CanonicalHeaderKey. 38 | func (h Header) Get(key string) string { 39 | return textproto.MIMEHeader(h).Get(key) 40 | } 41 | 42 | // get is like Get, but key must already be in CanonicalHeaderKey form. 43 | func (h Header) get(key string) string { 44 | if v := h[key]; len(v) > 0 { 45 | return v[0] 46 | } 47 | return "" 48 | } 49 | 50 | // Del deletes the values associated with key. 51 | func (h Header) Del(key string) { 52 | textproto.MIMEHeader(h).Del(key) 53 | } 54 | 55 | // Write writes a header in wire format. 56 | func (h Header) Write(w io.Writer) error { 57 | return h.WriteSubset(w, nil) 58 | } 59 | 60 | func (h Header) clone() Header { 61 | h2 := make(Header, len(h)) 62 | for k, vv := range h { 63 | vv2 := make([]string, len(vv)) 64 | copy(vv2, vv) 65 | h2[k] = vv2 66 | } 67 | return h2 68 | } 69 | 70 | var timeFormats = []string{ 71 | TimeFormat, 72 | time.RFC850, 73 | time.ANSIC, 74 | } 75 | 76 | // ParseTime parses a time header (such as the Date: header), 77 | // trying each of the three formats allowed by HTTP/1.1: 78 | // TimeFormat, time.RFC850, and time.ANSIC. 79 | func ParseTime(text string) (t time.Time, err error) { 80 | for _, layout := range timeFormats { 81 | t, err = time.Parse(layout, text) 82 | if err == nil { 83 | return 84 | } 85 | } 86 | return 87 | } 88 | 89 | var headerNewlineToSpace = strings.NewReplacer("\n", " ", "\r", " ") 90 | 91 | type writeStringer interface { 92 | WriteString(string) (int, error) 93 | } 94 | 95 | // stringWriter implements WriteString on a Writer. 96 | type stringWriter struct { 97 | w io.Writer 98 | } 99 | 100 | func (w stringWriter) WriteString(s string) (n int, err error) { 101 | return w.w.Write([]byte(s)) 102 | } 103 | 104 | type keyValues struct { 105 | key string 106 | values []string 107 | } 108 | 109 | // A headerSorter implements sort.Interface by sorting a []keyValues 110 | // by key. It's used as a pointer, so it can fit in a sort.Interface 111 | // interface value without allocation. 112 | type headerSorter struct { 113 | kvs []keyValues 114 | } 115 | 116 | func (s *headerSorter) Len() int { return len(s.kvs) } 117 | func (s *headerSorter) Swap(i, j int) { s.kvs[i], s.kvs[j] = s.kvs[j], s.kvs[i] } 118 | func (s *headerSorter) Less(i, j int) bool { return s.kvs[i].key < s.kvs[j].key } 119 | 120 | var headerSorterPool = sync.Pool{ 121 | New: func() interface{} { return new(headerSorter) }, 122 | } 123 | 124 | // sortedKeyValues returns h's keys sorted in the returned kvs 125 | // slice. The headerSorter used to sort is also returned, for possible 126 | // return to headerSorterCache. 127 | func (h Header) sortedKeyValues(exclude map[string]bool) (kvs []keyValues, hs *headerSorter) { 128 | hs = headerSorterPool.Get().(*headerSorter) 129 | if cap(hs.kvs) < len(h) { 130 | hs.kvs = make([]keyValues, 0, len(h)) 131 | } 132 | kvs = hs.kvs[:0] 133 | for k, vv := range h { 134 | if !exclude[k] { 135 | kvs = append(kvs, keyValues{k, vv}) 136 | } 137 | } 138 | hs.kvs = kvs 139 | sort.Sort(hs) 140 | return kvs, hs 141 | } 142 | 143 | // WriteSubset writes a header in wire format. 144 | // If exclude is not nil, keys where exclude[key] == true are not written. 145 | func (h Header) WriteSubset(w io.Writer, exclude map[string]bool) error { 146 | ws, ok := w.(writeStringer) 147 | if !ok { 148 | ws = stringWriter{w} 149 | } 150 | kvs, sorter := h.sortedKeyValues(exclude) 151 | for _, kv := range kvs { 152 | for _, v := range kv.values { 153 | v = headerNewlineToSpace.Replace(v) 154 | v = textproto.TrimString(v) 155 | for _, s := range []string{kv.key, ": ", v, "\r\n"} { 156 | if _, err := ws.WriteString(s); err != nil { 157 | return err 158 | } 159 | } 160 | } 161 | } 162 | headerSorterPool.Put(sorter) 163 | return nil 164 | } 165 | 166 | // CanonicalHeaderKey returns the canonical format of the 167 | // header key s. The canonicalization converts the first 168 | // letter and any letter following a hyphen to upper case; 169 | // the rest are converted to lowercase. For example, the 170 | // canonical key for "accept-encoding" is "Accept-Encoding". 171 | func CanonicalHeaderKey(s string) string { return textproto.CanonicalMIMEHeaderKey(s) } 172 | 173 | // hasToken reports whether token appears with v, ASCII 174 | // case-insensitive, with space or comma boundaries. 175 | // token must be all lowercase. 176 | // v may contain mixed cased. 177 | func hasToken(v, token string) bool { 178 | if len(token) > len(v) || token == "" { 179 | return false 180 | } 181 | if v == token { 182 | return true 183 | } 184 | for sp := 0; sp <= len(v)-len(token); sp++ { 185 | // Check that first character is good. 186 | // The token is ASCII, so checking only a single byte 187 | // is sufficient. We skip this potential starting 188 | // position if both the first byte and its potential 189 | // ASCII uppercase equivalent (b|0x20) don't match. 190 | // False positives ('^' => '~') are caught by EqualFold. 191 | if b := v[sp]; b != token[0] && b|0x20 != token[0] { 192 | continue 193 | } 194 | // Check that start pos is on a valid token boundary. 195 | if sp > 0 && !isTokenBoundary(v[sp-1]) { 196 | continue 197 | } 198 | // Check that end pos is on a valid token boundary. 199 | if endPos := sp + len(token); endPos != len(v) && !isTokenBoundary(v[endPos]) { 200 | continue 201 | } 202 | if strings.EqualFold(v[sp:sp+len(token)], token) { 203 | return true 204 | } 205 | } 206 | return false 207 | } 208 | 209 | func isTokenBoundary(b byte) bool { 210 | return b == ' ' || b == ',' || b == '\t' 211 | } 212 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/azure-sdk-for-go/core/tls/tls.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // Package tls partially implements TLS 1.2, as specified in RFC 5246. 6 | package tls 7 | 8 | import ( 9 | "crypto" 10 | "crypto/ecdsa" 11 | "crypto/rsa" 12 | "crypto/x509" 13 | "encoding/pem" 14 | "errors" 15 | "io/ioutil" 16 | "net" 17 | "strings" 18 | ) 19 | 20 | // Server returns a new TLS server side connection 21 | // using conn as the underlying transport. 22 | // The configuration config must be non-nil and must have 23 | // at least one certificate. 24 | func Server(conn net.Conn, config *Config) *Conn { 25 | return &Conn{conn: conn, config: config} 26 | } 27 | 28 | // Client returns a new TLS client side connection 29 | // using conn as the underlying transport. 30 | // Client interprets a nil configuration as equivalent to 31 | // the zero configuration; see the documentation of Config 32 | // for the defaults. 33 | func Client(conn net.Conn, config *Config) *Conn { 34 | return &Conn{conn: conn, config: config, isClient: true} 35 | } 36 | 37 | // A listener implements a network listener (net.Listener) for TLS connections. 38 | type listener struct { 39 | net.Listener 40 | config *Config 41 | } 42 | 43 | // Accept waits for and returns the next incoming TLS connection. 44 | // The returned connection c is a *tls.Conn. 45 | func (l *listener) Accept() (c net.Conn, err error) { 46 | c, err = l.Listener.Accept() 47 | if err != nil { 48 | return 49 | } 50 | c = Server(c, l.config) 51 | return 52 | } 53 | 54 | // NewListener creates a Listener which accepts connections from an inner 55 | // Listener and wraps each connection with Server. 56 | // The configuration config must be non-nil and must have 57 | // at least one certificate. 58 | func NewListener(inner net.Listener, config *Config) net.Listener { 59 | l := new(listener) 60 | l.Listener = inner 61 | l.config = config 62 | return l 63 | } 64 | 65 | // Listen creates a TLS listener accepting connections on the 66 | // given network address using net.Listen. 67 | // The configuration config must be non-nil and must have 68 | // at least one certificate. 69 | func Listen(network, laddr string, config *Config) (net.Listener, error) { 70 | if config == nil || len(config.Certificates) == 0 { 71 | return nil, errors.New("tls.Listen: no certificates in configuration") 72 | } 73 | l, err := net.Listen(network, laddr) 74 | if err != nil { 75 | return nil, err 76 | } 77 | return NewListener(l, config), nil 78 | } 79 | 80 | // Dial connects to the given network address using net.Dial 81 | // and then initiates a TLS handshake, returning the resulting 82 | // TLS connection. 83 | // Dial interprets a nil configuration as equivalent to 84 | // the zero configuration; see the documentation of Config 85 | // for the defaults. 86 | func Dial(network, addr string, config *Config) (*Conn, error) { 87 | raddr := addr 88 | c, err := net.Dial(network, raddr) 89 | if err != nil { 90 | return nil, err 91 | } 92 | 93 | colonPos := strings.LastIndex(raddr, ":") 94 | if colonPos == -1 { 95 | colonPos = len(raddr) 96 | } 97 | hostname := raddr[:colonPos] 98 | 99 | if config == nil { 100 | config = defaultConfig() 101 | } 102 | // If no ServerName is set, infer the ServerName 103 | // from the hostname we're connecting to. 104 | if config.ServerName == "" { 105 | // Make a copy to avoid polluting argument or default. 106 | c := *config 107 | c.ServerName = hostname 108 | config = &c 109 | } 110 | conn := Client(c, config) 111 | if err = conn.Handshake(); err != nil { 112 | c.Close() 113 | return nil, err 114 | } 115 | return conn, nil 116 | } 117 | 118 | // LoadX509KeyPair reads and parses a public/private key pair from a pair of 119 | // files. The files must contain PEM encoded data. 120 | func LoadX509KeyPair(certFile, keyFile string) (cert Certificate, err error) { 121 | certPEMBlock, err := ioutil.ReadFile(certFile) 122 | if err != nil { 123 | return 124 | } 125 | keyPEMBlock, err := ioutil.ReadFile(keyFile) 126 | if err != nil { 127 | return 128 | } 129 | return X509KeyPair(certPEMBlock, keyPEMBlock) 130 | } 131 | 132 | // X509KeyPair parses a public/private key pair from a pair of 133 | // PEM encoded data. 134 | func X509KeyPair(certPEMBlock, keyPEMBlock []byte) (cert Certificate, err error) { 135 | var certDERBlock *pem.Block 136 | for { 137 | certDERBlock, certPEMBlock = pem.Decode(certPEMBlock) 138 | if certDERBlock == nil { 139 | break 140 | } 141 | if certDERBlock.Type == "CERTIFICATE" { 142 | cert.Certificate = append(cert.Certificate, certDERBlock.Bytes) 143 | } 144 | } 145 | 146 | if len(cert.Certificate) == 0 { 147 | err = errors.New("crypto/tls: failed to parse certificate PEM data") 148 | return 149 | } 150 | 151 | var keyDERBlock *pem.Block 152 | for { 153 | keyDERBlock, keyPEMBlock = pem.Decode(keyPEMBlock) 154 | if keyDERBlock == nil { 155 | err = errors.New("crypto/tls: failed to parse key PEM data") 156 | return 157 | } 158 | if keyDERBlock.Type == "PRIVATE KEY" || strings.HasSuffix(keyDERBlock.Type, " PRIVATE KEY") { 159 | break 160 | } 161 | } 162 | 163 | cert.PrivateKey, err = parsePrivateKey(keyDERBlock.Bytes) 164 | if err != nil { 165 | return 166 | } 167 | 168 | // We don't need to parse the public key for TLS, but we so do anyway 169 | // to check that it looks sane and matches the private key. 170 | x509Cert, err := x509.ParseCertificate(cert.Certificate[0]) 171 | if err != nil { 172 | return 173 | } 174 | 175 | switch pub := x509Cert.PublicKey.(type) { 176 | case *rsa.PublicKey: 177 | priv, ok := cert.PrivateKey.(*rsa.PrivateKey) 178 | if !ok { 179 | err = errors.New("crypto/tls: private key type does not match public key type") 180 | return 181 | } 182 | if pub.N.Cmp(priv.N) != 0 { 183 | err = errors.New("crypto/tls: private key does not match public key") 184 | return 185 | } 186 | case *ecdsa.PublicKey: 187 | priv, ok := cert.PrivateKey.(*ecdsa.PrivateKey) 188 | if !ok { 189 | err = errors.New("crypto/tls: private key type does not match public key type") 190 | return 191 | 192 | } 193 | if pub.X.Cmp(priv.X) != 0 || pub.Y.Cmp(priv.Y) != 0 { 194 | err = errors.New("crypto/tls: private key does not match public key") 195 | return 196 | } 197 | default: 198 | err = errors.New("crypto/tls: unknown public key algorithm") 199 | return 200 | } 201 | 202 | return 203 | } 204 | 205 | // Attempt to parse the given private key DER block. OpenSSL 0.9.8 generates 206 | // PKCS#1 private keys by default, while OpenSSL 1.0.0 generates PKCS#8 keys. 207 | // OpenSSL ecparam generates SEC1 EC private keys for ECDSA. We try all three. 208 | func parsePrivateKey(der []byte) (crypto.PrivateKey, error) { 209 | if key, err := x509.ParsePKCS1PrivateKey(der); err == nil { 210 | return key, nil 211 | } 212 | if key, err := x509.ParsePKCS8PrivateKey(der); err == nil { 213 | switch key := key.(type) { 214 | case *rsa.PrivateKey, *ecdsa.PrivateKey: 215 | return key, nil 216 | default: 217 | return nil, errors.New("crypto/tls: found unknown private key type in PKCS#8 wrapping") 218 | } 219 | } 220 | if key, err := x509.ParseECPrivateKey(der); err == nil { 221 | return key, nil 222 | } 223 | 224 | return nil, errors.New("crypto/tls: failed to parse private key") 225 | } 226 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/winrm/README.md: -------------------------------------------------------------------------------- 1 | # WinRM for Go 2 | 3 | _Note_: if you're looking for the `winrm` command-line tool, this has been splitted from this project and is available at [winrm-cli](https://github.com/masterzen/winrm-cli) 4 | 5 | This is a Go library to execute remote commands on Windows machines through 6 | the use of WinRM/WinRS. 7 | 8 | _Note_: this library doesn't support domain users (it doesn't support GSSAPI nor Kerberos). It's primary target is to execute remote commands on EC2 windows machines. 9 | 10 | [![Build Status](https://travis-ci.org/masterzen/winrm.svg?branch=master)](https://travis-ci.org/masterzen/winrm) 11 | [![Coverage Status](https://coveralls.io/repos/masterzen/winrm/badge.png)](https://coveralls.io/r/masterzen/winrm) 12 | 13 | ## Contact 14 | 15 | - Bugs: https://github.com/masterzen/winrm/issues 16 | 17 | 18 | ## Getting Started 19 | WinRM is available on Windows Server 2008 and up. This project natively supports basic authentication for local accounts, see the steps in the next section on how to prepare the remote Windows machine for this scenario. The authentication model is pluggable, see below for an example on using Negotiate/NTLM authentication (e.g. for connecting to vanilla Azure VMs). 20 | 21 | ### Preparing the remote Windows machine for Basic authentication 22 | This project supports only basic authentication for local accounts (domain users are not supported). The remote windows system must be prepared for winrm: 23 | 24 | _For a PowerShell script to do what is described below in one go, check [Richard Downer's blog](http://www.frontiertown.co.uk/2011/12/overthere-control-windows-from-java/)_ 25 | 26 | On the remote host, a PowerShell prompt, using the __Run as Administrator__ option and paste in the following lines: 27 | 28 | winrm quickconfig 29 | y 30 | winrm set winrm/config/service/Auth '@{Basic="true"}' 31 | winrm set winrm/config/service '@{AllowUnencrypted="true"}' 32 | winrm set winrm/config/winrs '@{MaxMemoryPerShellMB="1024"}' 33 | 34 | __N.B.:__ The Windows Firewall needs to be running to run this command. See [Microsoft Knowledge Base article #2004640](http://support.microsoft.com/kb/2004640). 35 | 36 | __N.B.:__ Do not disable Negotiate authentication as the `winrm` command itself uses this for internal authentication, and you risk getting a system where `winrm` doesn't work anymore. 37 | 38 | __N.B.:__ The `MaxMemoryPerShellMB` option has no effects on some Windows 2008R2 systems because of a WinRM bug. Make sure to install the hotfix described [Microsoft Knowledge Base article #2842230](http://support.microsoft.com/kb/2842230) if you need to run commands that uses more than 150MB of memory. 39 | 40 | For more information on WinRM, please refer to the online documentation at Microsoft's DevCenter. 41 | 42 | ### Building the winrm go and executable 43 | 44 | You can build winrm from source: 45 | 46 | ```sh 47 | git clone https://github.com/masterzen/winrm 48 | cd winrm 49 | make 50 | ``` 51 | 52 | _Note_: this winrm code doesn't depend anymore on [Gokogiri](https://github.com/moovweb/gokogiri) which means it is now in pure Go. 53 | 54 | _Note_: you need go 1.5+. Please check your installation with 55 | 56 | ``` 57 | go version 58 | ``` 59 | 60 | ## Command-line usage 61 | 62 | For command-line usage check the [winrm-cli project](https://github.com/masterzen/winrm-cli) 63 | 64 | ## Library Usage 65 | 66 | **Warning the API might be subject to change.** 67 | 68 | For the fast version (this doesn't allow to send input to the command) and it's using HTTP as the transport: 69 | 70 | ```go 71 | package main 72 | 73 | import ( 74 | "github.com/masterzen/winrm" 75 | "os" 76 | ) 77 | 78 | endpoint := winrm.NewEndpoint(host, 5986, false, false, nil, nil, nil, 0) 79 | client, err := winrm.NewClient(endpoint, "Administrator", "secret") 80 | if err != nil { 81 | panic(err) 82 | } 83 | client.Run("ipconfig /all", os.Stdout, os.Stderr) 84 | ``` 85 | 86 | or 87 | ```go 88 | package main 89 | import ( 90 | "github.com/masterzen/winrm" 91 | "fmt" 92 | "os" 93 | ) 94 | 95 | endpoint := winrm.NewEndpoint("localhost", 5985, false, false, nil, nil, nil, 0) 96 | client, err := winrm.NewClient(endpoint,"Administrator", "secret") 97 | if err != nil { 98 | panic(err) 99 | } 100 | 101 | _, err := client.RunWithInput("ipconfig", os.Stdout, os.Stderr, os.Stdin) 102 | if err != nil { 103 | panic(err) 104 | } 105 | 106 | ``` 107 | 108 | By passing a TransportDecorator in the Parameters struct it is possible to use different Transports (e.g. NTLM) 109 | 110 | ```go 111 | package main 112 | import ( 113 | "github.com/masterzen/winrm" 114 | "fmt" 115 | "os" 116 | ) 117 | 118 | endpoint := winrm.NewEndpoint("localhost", 5985, false, false, nil, nil, nil, 0) 119 | 120 | params := DefaultParameters 121 | params.TransportDecorator = func() Transporter { return &ClientNTLM{} } 122 | 123 | client, err := NewClientWithParameters(endpoint, "test", "test", params) 124 | if err != nil { 125 | panic(err) 126 | } 127 | 128 | _, err := client.RunWithInput("ipconfig", os.Stdout, os.Stderr, os.Stdin) 129 | if err != nil { 130 | panic(err) 131 | } 132 | 133 | ``` 134 | 135 | For a more complex example, it is possible to call the various functions directly: 136 | 137 | ```go 138 | package main 139 | 140 | import ( 141 | "github.com/masterzen/winrm" 142 | "fmt" 143 | "bytes" 144 | "os" 145 | ) 146 | 147 | stdin := bytes.NewBufferString("ipconfig /all") 148 | endpoint := winrm.NewEndpoint("localhost", 5985, false, false,nil, nil, nil, 0) 149 | client , err := winrm.NewClient(endpoint, "Administrator", "secret") 150 | if err != nil { 151 | panic(err) 152 | } 153 | shell, err := client.CreateShell() 154 | if err != nil { 155 | panic(err) 156 | } 157 | var cmd *winrm.Command 158 | cmd, err = shell.Execute("cmd.exe") 159 | if err != nil { 160 | panic(err) 161 | } 162 | 163 | go io.Copy(cmd.Stdin, stdin) 164 | go io.Copy(os.Stdout, cmd.Stdout) 165 | go io.Copy(os.Stderr, cmd.Stderr) 166 | 167 | cmd.Wait() 168 | shell.Close() 169 | ``` 170 | 171 | For using HTTPS authentication with x 509 cert without checking the CA 172 | ```go 173 | package main 174 | 175 | import ( 176 | "github.com/masterzen/winrm" 177 | "os" 178 | "io/ioutil" 179 | ) 180 | 181 | clientCert, err := ioutil.ReadFile("path/to/cert") 182 | if err != nil { 183 | panic(err) 184 | } 185 | 186 | clientKey, err := ioutil.ReadFile("path/to/key") 187 | if err != nil { 188 | panic(err) 189 | } 190 | 191 | winrm.DefaultParameters.TransportDecorator = func() winrm.Transporter { 192 | // winrm https module 193 | return &winrm.ClientAuthRequest{} 194 | } 195 | 196 | endpoint := winrm.NewEndpoint(host, 5986, false, false, clientCert, clientKey, nil, 0) 197 | client, err := winrm.NewClient(endpoint, "Administrator", "" 198 | if err != nil { 199 | panic(err) 200 | } 201 | client.Run("ipconfig /all", os.Stdout, os.Stderr) 202 | ``` 203 | 204 | ## Developing on WinRM 205 | 206 | If you wish to work on `winrm` itself, you'll first need [Go](http://golang.org) 207 | installed (version 1.5+ is _required_). Make sure you have Go properly installed, 208 | including setting up your [GOPATH](http://golang.org/doc/code.html#GOPATH). 209 | 210 | For some additional dependencies, Go needs [Mercurial](http://mercurial.selenic.com/) 211 | and [Bazaar](http://bazaar.canonical.com/en/) to be installed. 212 | Winrm itself doesn't require these, but a dependency of a dependency does. 213 | 214 | Next, clone this repository into `$GOPATH/src/github.com/masterzen/winrm` and 215 | then just type `make`. 216 | 217 | You can run tests by typing `make test`. 218 | 219 | If you make any changes to the code, run `make format` in order to automatically 220 | format the code according to Go standards. 221 | 222 | When new dependencies are added to winrm you can use `make updatedeps` to 223 | get the latest and subsequently use `make` to compile. 224 | -------------------------------------------------------------------------------- /scvmm/resource_scvmm_virtual_disk_test.go: -------------------------------------------------------------------------------- 1 | package scvmm 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | "testing" 7 | 8 | "github.com/hashicorp/terraform/helper/resource" 9 | "github.com/hashicorp/terraform/terraform" 10 | "github.com/masterzen/winrm" 11 | ) 12 | 13 | func testBasicPreCheckVolume(t *testing.T) { 14 | if v := os.Getenv("SCVMM_VMM_SERVER"); v == "" { 15 | t.Fatal("SCVMM_VMM_SERVER must be set for acceptance tests") 16 | } 17 | if v := os.Getenv("SCVMM_TEMPLATE_NAME"); v == "" { 18 | t.Fatal("SCVMM_TEMPLATE_NAME must be set for acceptance tests") 19 | } 20 | if v := os.Getenv("SCVMM_CLOUD_NAME"); v == "" { 21 | t.Fatal("SCVMM_CLOUD_NAME must be set for acceptance tests") 22 | } 23 | } 24 | 25 | func TestAccVolume_Basic(t *testing.T) { 26 | resourceName := "scvmm_virtual_disk.CreateDiskDrive" 27 | resource.Test(t, resource.TestCase{ 28 | PreCheck: func() { 29 | testAccPreCheck(t) 30 | testBasicPreCheckVolume(t) 31 | }, 32 | Providers: testAccProviders, 33 | CheckDestroy: testAccCheckDiskDestroy(resourceName), 34 | Steps: []resource.TestStep{ 35 | resource.TestStep{ 36 | Config: testAccCheckVDConfigBasic(), 37 | Check: resource.ComposeTestCheckFunc( 38 | testAccCheckDiskExists(resourceName), 39 | resource.TestCheckResourceAttr( 40 | resourceName, "vm_name", "terraformVM"), 41 | resource.TestCheckResourceAttr( 42 | resourceName, "vmm_server", os.Getenv("SCVMM_VMM_SERVER")), 43 | resource.TestCheckResourceAttr( 44 | resourceName, "virtual_disk_name", "terraformDisk"), 45 | ), 46 | }, 47 | }, 48 | }) 49 | } 50 | 51 | func testAccCheckDiskDestroy(n string) resource.TestCheckFunc { 52 | return func(s *terraform.State) error { 53 | rs, ok := s.RootModule().Resources[n] 54 | if !ok { 55 | return fmt.Errorf("Not found: %s", n) 56 | } 57 | org := testAccProvider.Meta().(*winrm.Client) 58 | 59 | script := "\n[CmdletBinding(SupportsShouldProcess=$true)]\nparam (\n \n [Parameter(Mandatory=$true,HelpMessage=\"Enter VM Name\")]\n [string]$vmName,\n\n [Parameter(Mandatory=$true,HelpMessage=\"Enter VmmServer\")]\n [string]$vmmServer,\n\n [Parameter(Mandatory=$true,HelpMessage=\"Enter Volume Name\")]\n [string]$diskdriveName\n)\n\nBegin\n{ \n If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] \"Administrator\"))\n { \n $arguments = \"\" + $myinvocation.mycommand.definition + \" \"\n $myinvocation.BoundParameters.Values | foreach{$arguments += \"'$_' \" }\n echo $arguments\n Start-Process powershell -Verb runAs -ArgumentList $arguments\n Break\n }\n\u0009 try\n\u0009 { if($vmName -eq $null) \n {\n echo \"VM Name not entered\"\n exit\n } \n #gets virtual machine objects from the Virtual Machine Manager database\n Set-SCVMMServer -VMMServer $vmmServer\n\u0009\u0009$VM = Get-SCVirtualMachine | Where-Object {$_.Name -Eq $vmName } \n #check if VM Exists\n \n \n if($diskdriveName -ne $null)\n {\n #gets the specified volume object\n $diskdrive=Get-SCVirtualDiskDrive -VM $VM | Where-Object { $_.VirtualHardDisk.Name -Eq $diskdriveName} \n if($diskdrive -eq $null)\n {\n #This will delete specified volume attached which is to that vm \n Write-Error \"Virtual Disk Not Found\"\n }\n\n } \n else\n {\n echo \"Name of the disk drive is not entered\"\n } \n }\n\u0009 catch [Exception]\n\u0009 {\n\u0009\u0009 echo $_.Exception.Message\n\u0009 }\n}\n" 60 | 61 | arguments := rs.Primary.Attributes["vm_name"] + " " + rs.Primary.Attributes["vmm_server"] + " " + rs.Primary.Attributes["virtual_disk_name"] 62 | filename := "deletediskdrive" 63 | result, err := execScript(org, script, filename, arguments) 64 | 65 | if err == "" { 66 | return fmt.Errorf("Error, Volume is still exist %v", result) 67 | } 68 | return nil 69 | } 70 | } 71 | 72 | func testAccCheckDiskExists(n string) resource.TestCheckFunc { 73 | return func(s *terraform.State) error { 74 | rs, ok := s.RootModule().Resources[n] 75 | 76 | if !ok { 77 | return fmt.Errorf("Not found: %s", n) 78 | } 79 | 80 | if rs.Primary.ID == "" { 81 | return fmt.Errorf("No Vm ID is set") 82 | } 83 | org := testAccProvider.Meta().(*winrm.Client) 84 | 85 | script := "\n[CmdletBinding(SupportsShouldProcess=$true)]\nparam (\n \n [Parameter(Mandatory=$true,HelpMessage=\"Enter VM Name\")]\n [string]$vmName,\n\n [Parameter(Mandatory=$true,HelpMessage=\"Enter VmmServer\")]\n [string]$vmmServer,\n\n [Parameter(Mandatory=$true,HelpMessage=\"Enter Volume Name\")]\n [string]$diskdriveName\n)\n\nBegin\n{ \n If (-NOT ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] \"Administrator\"))\n { \n $arguments = \"\" + $myinvocation.mycommand.definition + \" \"\n $myinvocation.BoundParameters.Values | foreach{$arguments += \"'$_' \" }\n echo $arguments\n Start-Process powershell -Verb runAs -ArgumentList $arguments\n Break\n }\n\u0009 try\n\u0009 { if($vmName -eq $null) \n {\n echo \"VM Name not entered\"\n exit\n } \n #gets virtual machine objects from the Virtual Machine Manager database\n Set-SCVMMServer -VMMServer $vmmServer\n\u0009\u0009$VM = Get-SCVirtualMachine | Where-Object {$_.Name -Eq $vmName } \n #check if VM Exists\n \n \n if($diskdriveName -ne $null)\n {\n #gets the specified volume object\n $diskdrive=Get-SCVirtualDiskDrive -VM $VM | Where-Object { $_.VirtualHardDisk.Name -Eq $diskdriveName} \n if($diskdrive -eq $null)\n {\n #This will delete specified volume attached which is to that vm \n Write-Error \"Virtual Disk Not Found\"\n }\n\n } \n else\n {\n echo \"Name of the disk drive is not entered\"\n } \n }\n\u0009 catch [Exception]\n\u0009 {\n\u0009\u0009 echo $_.Exception.Message\n\u0009 }\n}\n" 86 | arguments := "terraformVM " + os.Getenv("SCVMM_VMM_SERVER") + " terraformDisk" 87 | filename := "creatediskdrive" 88 | result1, err := execScript(org, script, filename, arguments) 89 | if err != "" { 90 | return fmt.Errorf("Error, Volume is not created %v", result1) 91 | } 92 | return nil 93 | } 94 | } 95 | 96 | func testAccCheckVDConfigBasic() string { 97 | return fmt.Sprintf(` 98 | resource "scvmm_virtual_machine" "CreateVM" { 99 | timeout = "1000" 100 | vmm_server = "%s" 101 | vm_name = "terraformVM" 102 | template_name = "%s" 103 | cloud_name = "%s" 104 | } 105 | 106 | resource "scvmm_virtual_disk" "CreateDiskDrive" { 107 | timeout = 1000 108 | vmm_server = "${scvmm_virtual_machine.CreateVM.vmm_server}" 109 | vm_name = "${scvmm_virtual_machine.CreateVM.vm_name}" 110 | virtual_disk_name = "terraformDisk" 111 | virtual_disk_size = "1000" 112 | } 113 | `, os.Getenv("SCVMM_VMM_SERVER"), 114 | os.Getenv("SCVMM_TEMPLATE_NAME"), 115 | os.Getenv("SCVMM_CLOUD_NAME")) 116 | } 117 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/azure-sdk-for-go/core/http/response.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | // HTTP Response reading and parsing. 6 | 7 | package http 8 | 9 | import ( 10 | "bufio" 11 | "bytes" 12 | "errors" 13 | "github.com/masterzen/azure-sdk-for-go/core/tls" 14 | "io" 15 | "net/textproto" 16 | "net/url" 17 | "strconv" 18 | "strings" 19 | ) 20 | 21 | var respExcludeHeader = map[string]bool{ 22 | "Content-Length": true, 23 | "Transfer-Encoding": true, 24 | "Trailer": true, 25 | } 26 | 27 | // Response represents the response from an HTTP request. 28 | // 29 | type Response struct { 30 | Status string // e.g. "200 OK" 31 | StatusCode int // e.g. 200 32 | Proto string // e.g. "HTTP/1.0" 33 | ProtoMajor int // e.g. 1 34 | ProtoMinor int // e.g. 0 35 | 36 | // Header maps header keys to values. If the response had multiple 37 | // headers with the same key, they may be concatenated, with comma 38 | // delimiters. (Section 4.2 of RFC 2616 requires that multiple headers 39 | // be semantically equivalent to a comma-delimited sequence.) Values 40 | // duplicated by other fields in this struct (e.g., ContentLength) are 41 | // omitted from Header. 42 | // 43 | // Keys in the map are canonicalized (see CanonicalHeaderKey). 44 | Header Header 45 | 46 | // Body represents the response body. 47 | // 48 | // The http Client and Transport guarantee that Body is always 49 | // non-nil, even on responses without a body or responses with 50 | // a zero-length body. It is the caller's responsibility to 51 | // close Body. 52 | // 53 | // The Body is automatically dechunked if the server replied 54 | // with a "chunked" Transfer-Encoding. 55 | Body io.ReadCloser 56 | 57 | // ContentLength records the length of the associated content. The 58 | // value -1 indicates that the length is unknown. Unless Request.Method 59 | // is "HEAD", values >= 0 indicate that the given number of bytes may 60 | // be read from Body. 61 | ContentLength int64 62 | 63 | // Contains transfer encodings from outer-most to inner-most. Value is 64 | // nil, means that "identity" encoding is used. 65 | TransferEncoding []string 66 | 67 | // Close records whether the header directed that the connection be 68 | // closed after reading Body. The value is advice for clients: neither 69 | // ReadResponse nor Response.Write ever closes a connection. 70 | Close bool 71 | 72 | // Trailer maps trailer keys to values, in the same 73 | // format as the header. 74 | Trailer Header 75 | 76 | // The Request that was sent to obtain this Response. 77 | // Request's Body is nil (having already been consumed). 78 | // This is only populated for Client requests. 79 | Request *Request 80 | 81 | // TLS contains information about the TLS connection on which the 82 | // response was received. It is nil for unencrypted responses. 83 | // The pointer is shared between responses and should not be 84 | // modified. 85 | TLS *tls.ConnectionState 86 | } 87 | 88 | // Cookies parses and returns the cookies set in the Set-Cookie headers. 89 | func (r *Response) Cookies() []*Cookie { 90 | return readSetCookies(r.Header) 91 | } 92 | 93 | var ErrNoLocation = errors.New("http: no Location header in response") 94 | 95 | // Location returns the URL of the response's "Location" header, 96 | // if present. Relative redirects are resolved relative to 97 | // the Response's Request. ErrNoLocation is returned if no 98 | // Location header is present. 99 | func (r *Response) Location() (*url.URL, error) { 100 | lv := r.Header.Get("Location") 101 | if lv == "" { 102 | return nil, ErrNoLocation 103 | } 104 | if r.Request != nil && r.Request.URL != nil { 105 | return r.Request.URL.Parse(lv) 106 | } 107 | return url.Parse(lv) 108 | } 109 | 110 | // ReadResponse reads and returns an HTTP response from r. 111 | // The req parameter optionally specifies the Request that corresponds 112 | // to this Response. If nil, a GET request is assumed. 113 | // Clients must call resp.Body.Close when finished reading resp.Body. 114 | // After that call, clients can inspect resp.Trailer to find key/value 115 | // pairs included in the response trailer. 116 | func ReadResponse(r *bufio.Reader, req *Request) (*Response, error) { 117 | tp := textproto.NewReader(r) 118 | resp := &Response{ 119 | Request: req, 120 | } 121 | 122 | // Parse the first line of the response. 123 | line, err := tp.ReadLine() 124 | if err != nil { 125 | if err == io.EOF { 126 | err = io.ErrUnexpectedEOF 127 | } 128 | return nil, err 129 | } 130 | f := strings.SplitN(line, " ", 3) 131 | if len(f) < 2 { 132 | return nil, &badStringError{"malformed HTTP response", line} 133 | } 134 | reasonPhrase := "" 135 | if len(f) > 2 { 136 | reasonPhrase = f[2] 137 | } 138 | resp.Status = f[1] + " " + reasonPhrase 139 | resp.StatusCode, err = strconv.Atoi(f[1]) 140 | if err != nil { 141 | return nil, &badStringError{"malformed HTTP status code", f[1]} 142 | } 143 | 144 | resp.Proto = f[0] 145 | var ok bool 146 | if resp.ProtoMajor, resp.ProtoMinor, ok = ParseHTTPVersion(resp.Proto); !ok { 147 | return nil, &badStringError{"malformed HTTP version", resp.Proto} 148 | } 149 | 150 | // Parse the response headers. 151 | mimeHeader, err := tp.ReadMIMEHeader() 152 | if err != nil { 153 | if err == io.EOF { 154 | err = io.ErrUnexpectedEOF 155 | } 156 | return nil, err 157 | } 158 | resp.Header = Header(mimeHeader) 159 | 160 | fixPragmaCacheControl(resp.Header) 161 | 162 | err = readTransfer(resp, r) 163 | if err != nil { 164 | return nil, err 165 | } 166 | 167 | return resp, nil 168 | } 169 | 170 | // RFC2616: Should treat 171 | // Pragma: no-cache 172 | // like 173 | // Cache-Control: no-cache 174 | func fixPragmaCacheControl(header Header) { 175 | if hp, ok := header["Pragma"]; ok && len(hp) > 0 && hp[0] == "no-cache" { 176 | if _, presentcc := header["Cache-Control"]; !presentcc { 177 | header["Cache-Control"] = []string{"no-cache"} 178 | } 179 | } 180 | } 181 | 182 | // ProtoAtLeast reports whether the HTTP protocol used 183 | // in the response is at least major.minor. 184 | func (r *Response) ProtoAtLeast(major, minor int) bool { 185 | return r.ProtoMajor > major || 186 | r.ProtoMajor == major && r.ProtoMinor >= minor 187 | } 188 | 189 | // Writes the response (header, body and trailer) in wire format. This method 190 | // consults the following fields of the response: 191 | // 192 | // StatusCode 193 | // ProtoMajor 194 | // ProtoMinor 195 | // Request.Method 196 | // TransferEncoding 197 | // Trailer 198 | // Body 199 | // ContentLength 200 | // Header, values for non-canonical keys will have unpredictable behavior 201 | // 202 | // Body is closed after it is sent. 203 | func (r *Response) Write(w io.Writer) error { 204 | // Status line 205 | text := r.Status 206 | if text == "" { 207 | var ok bool 208 | text, ok = statusText[r.StatusCode] 209 | if !ok { 210 | text = "status code " + strconv.Itoa(r.StatusCode) 211 | } 212 | } 213 | protoMajor, protoMinor := strconv.Itoa(r.ProtoMajor), strconv.Itoa(r.ProtoMinor) 214 | statusCode := strconv.Itoa(r.StatusCode) + " " 215 | text = strings.TrimPrefix(text, statusCode) 216 | if _, err := io.WriteString(w, "HTTP/"+protoMajor+"."+protoMinor+" "+statusCode+text+"\r\n"); err != nil { 217 | return err 218 | } 219 | 220 | // Clone it, so we can modify r1 as needed. 221 | r1 := new(Response) 222 | *r1 = *r 223 | if r1.ContentLength == 0 && r1.Body != nil { 224 | // Is it actually 0 length? Or just unknown? 225 | var buf [1]byte 226 | n, err := r1.Body.Read(buf[:]) 227 | if err != nil && err != io.EOF { 228 | return err 229 | } 230 | if n == 0 { 231 | // Reset it to a known zero reader, in case underlying one 232 | // is unhappy being read repeatedly. 233 | r1.Body = eofReader 234 | } else { 235 | r1.ContentLength = -1 236 | r1.Body = struct { 237 | io.Reader 238 | io.Closer 239 | }{ 240 | io.MultiReader(bytes.NewReader(buf[:1]), r.Body), 241 | r.Body, 242 | } 243 | } 244 | } 245 | // If we're sending a non-chunked HTTP/1.1 response without a 246 | // content-length, the only way to do that is the old HTTP/1.0 247 | // way, by noting the EOF with a connection close, so we need 248 | // to set Close. 249 | if r1.ContentLength == -1 && !r1.Close && r1.ProtoAtLeast(1, 1) && !chunked(r1.TransferEncoding) { 250 | r1.Close = true 251 | } 252 | 253 | // Process Body,ContentLength,Close,Trailer 254 | tw, err := newTransferWriter(r1) 255 | if err != nil { 256 | return err 257 | } 258 | err = tw.WriteHeader(w) 259 | if err != nil { 260 | return err 261 | } 262 | 263 | // Rest of header 264 | err = r.Header.WriteSubset(w, respExcludeHeader) 265 | if err != nil { 266 | return err 267 | } 268 | 269 | // contentLengthAlreadySent may have been already sent for 270 | // POST/PUT requests, even if zero length. See Issue 8180. 271 | contentLengthAlreadySent := tw.shouldSendContentLength() 272 | if r1.ContentLength == 0 && !chunked(r1.TransferEncoding) && !contentLengthAlreadySent { 273 | if _, err := io.WriteString(w, "Content-Length: 0\r\n"); err != nil { 274 | return err 275 | } 276 | } 277 | 278 | // End-of-header 279 | if _, err := io.WriteString(w, "\r\n"); err != nil { 280 | return err 281 | } 282 | 283 | // Write body and trailer 284 | err = tw.WriteBody(w) 285 | if err != nil { 286 | return err 287 | } 288 | 289 | // Success 290 | return nil 291 | } 292 | -------------------------------------------------------------------------------- /vendor/github.com/masterzen/azure-sdk-for-go/core/tls/prf.go: -------------------------------------------------------------------------------- 1 | // Copyright 2009 The Go Authors. All rights reserved. 2 | // Use of this source code is governed by a BSD-style 3 | // license that can be found in the LICENSE file. 4 | 5 | package tls 6 | 7 | import ( 8 | "crypto" 9 | "crypto/hmac" 10 | "crypto/md5" 11 | "crypto/sha1" 12 | "crypto/sha256" 13 | "hash" 14 | ) 15 | 16 | // Split a premaster secret in two as specified in RFC 4346, section 5. 17 | func splitPreMasterSecret(secret []byte) (s1, s2 []byte) { 18 | s1 = secret[0 : (len(secret)+1)/2] 19 | s2 = secret[len(secret)/2:] 20 | return 21 | } 22 | 23 | // pHash implements the P_hash function, as defined in RFC 4346, section 5. 24 | func pHash(result, secret, seed []byte, hash func() hash.Hash) { 25 | h := hmac.New(hash, secret) 26 | h.Write(seed) 27 | a := h.Sum(nil) 28 | 29 | j := 0 30 | for j < len(result) { 31 | h.Reset() 32 | h.Write(a) 33 | h.Write(seed) 34 | b := h.Sum(nil) 35 | todo := len(b) 36 | if j+todo > len(result) { 37 | todo = len(result) - j 38 | } 39 | copy(result[j:j+todo], b) 40 | j += todo 41 | 42 | h.Reset() 43 | h.Write(a) 44 | a = h.Sum(nil) 45 | } 46 | } 47 | 48 | // prf10 implements the TLS 1.0 pseudo-random function, as defined in RFC 2246, section 5. 49 | func prf10(result, secret, label, seed []byte) { 50 | hashSHA1 := sha1.New 51 | hashMD5 := md5.New 52 | 53 | labelAndSeed := make([]byte, len(label)+len(seed)) 54 | copy(labelAndSeed, label) 55 | copy(labelAndSeed[len(label):], seed) 56 | 57 | s1, s2 := splitPreMasterSecret(secret) 58 | pHash(result, s1, labelAndSeed, hashMD5) 59 | result2 := make([]byte, len(result)) 60 | pHash(result2, s2, labelAndSeed, hashSHA1) 61 | 62 | for i, b := range result2 { 63 | result[i] ^= b 64 | } 65 | } 66 | 67 | // prf12 implements the TLS 1.2 pseudo-random function, as defined in RFC 5246, section 5. 68 | func prf12(result, secret, label, seed []byte) { 69 | labelAndSeed := make([]byte, len(label)+len(seed)) 70 | copy(labelAndSeed, label) 71 | copy(labelAndSeed[len(label):], seed) 72 | 73 | pHash(result, secret, labelAndSeed, sha256.New) 74 | } 75 | 76 | // prf30 implements the SSL 3.0 pseudo-random function, as defined in 77 | // www.mozilla.org/projects/security/pki/nss/ssl/draft302.txt section 6. 78 | func prf30(result, secret, label, seed []byte) { 79 | hashSHA1 := sha1.New() 80 | hashMD5 := md5.New() 81 | 82 | done := 0 83 | i := 0 84 | // RFC5246 section 6.3 says that the largest PRF output needed is 128 85 | // bytes. Since no more ciphersuites will be added to SSLv3, this will 86 | // remain true. Each iteration gives us 16 bytes so 10 iterations will 87 | // be sufficient. 88 | var b [11]byte 89 | for done < len(result) { 90 | for j := 0; j <= i; j++ { 91 | b[j] = 'A' + byte(i) 92 | } 93 | 94 | hashSHA1.Reset() 95 | hashSHA1.Write(b[:i+1]) 96 | hashSHA1.Write(secret) 97 | hashSHA1.Write(seed) 98 | digest := hashSHA1.Sum(nil) 99 | 100 | hashMD5.Reset() 101 | hashMD5.Write(secret) 102 | hashMD5.Write(digest) 103 | 104 | done += copy(result[done:], hashMD5.Sum(nil)) 105 | i++ 106 | } 107 | } 108 | 109 | const ( 110 | tlsRandomLength = 32 // Length of a random nonce in TLS 1.1. 111 | masterSecretLength = 48 // Length of a master secret in TLS 1.1. 112 | finishedVerifyLength = 12 // Length of verify_data in a Finished message. 113 | ) 114 | 115 | var masterSecretLabel = []byte("master secret") 116 | var keyExpansionLabel = []byte("key expansion") 117 | var clientFinishedLabel = []byte("client finished") 118 | var serverFinishedLabel = []byte("server finished") 119 | 120 | func prfForVersion(version uint16) func(result, secret, label, seed []byte) { 121 | switch version { 122 | case VersionSSL30: 123 | return prf30 124 | case VersionTLS10, VersionTLS11: 125 | return prf10 126 | case VersionTLS12: 127 | return prf12 128 | default: 129 | panic("unknown version") 130 | } 131 | } 132 | 133 | // masterFromPreMasterSecret generates the master secret from the pre-master 134 | // secret. See http://tools.ietf.org/html/rfc5246#section-8.1 135 | func masterFromPreMasterSecret(version uint16, preMasterSecret, clientRandom, serverRandom []byte) []byte { 136 | var seed [tlsRandomLength * 2]byte 137 | copy(seed[0:len(clientRandom)], clientRandom) 138 | copy(seed[len(clientRandom):], serverRandom) 139 | masterSecret := make([]byte, masterSecretLength) 140 | prfForVersion(version)(masterSecret, preMasterSecret, masterSecretLabel, seed[0:]) 141 | return masterSecret 142 | } 143 | 144 | // keysFromMasterSecret generates the connection keys from the master 145 | // secret, given the lengths of the MAC key, cipher key and IV, as defined in 146 | // RFC 2246, section 6.3. 147 | func keysFromMasterSecret(version uint16, masterSecret, clientRandom, serverRandom []byte, macLen, keyLen, ivLen int) (clientMAC, serverMAC, clientKey, serverKey, clientIV, serverIV []byte) { 148 | var seed [tlsRandomLength * 2]byte 149 | copy(seed[0:len(clientRandom)], serverRandom) 150 | copy(seed[len(serverRandom):], clientRandom) 151 | 152 | n := 2*macLen + 2*keyLen + 2*ivLen 153 | keyMaterial := make([]byte, n) 154 | prfForVersion(version)(keyMaterial, masterSecret, keyExpansionLabel, seed[0:]) 155 | clientMAC = keyMaterial[:macLen] 156 | keyMaterial = keyMaterial[macLen:] 157 | serverMAC = keyMaterial[:macLen] 158 | keyMaterial = keyMaterial[macLen:] 159 | clientKey = keyMaterial[:keyLen] 160 | keyMaterial = keyMaterial[keyLen:] 161 | serverKey = keyMaterial[:keyLen] 162 | keyMaterial = keyMaterial[keyLen:] 163 | clientIV = keyMaterial[:ivLen] 164 | keyMaterial = keyMaterial[ivLen:] 165 | serverIV = keyMaterial[:ivLen] 166 | return 167 | } 168 | 169 | func newFinishedHash(version uint16) finishedHash { 170 | if version >= VersionTLS12 { 171 | return finishedHash{sha256.New(), sha256.New(), nil, nil, version} 172 | } 173 | return finishedHash{sha1.New(), sha1.New(), md5.New(), md5.New(), version} 174 | } 175 | 176 | // A finishedHash calculates the hash of a set of handshake messages suitable 177 | // for including in a Finished message. 178 | type finishedHash struct { 179 | client hash.Hash 180 | server hash.Hash 181 | 182 | // Prior to TLS 1.2, an additional MD5 hash is required. 183 | clientMD5 hash.Hash 184 | serverMD5 hash.Hash 185 | 186 | version uint16 187 | } 188 | 189 | func (h finishedHash) Write(msg []byte) (n int, err error) { 190 | h.client.Write(msg) 191 | h.server.Write(msg) 192 | 193 | if h.version < VersionTLS12 { 194 | h.clientMD5.Write(msg) 195 | h.serverMD5.Write(msg) 196 | } 197 | return len(msg), nil 198 | } 199 | 200 | // finishedSum30 calculates the contents of the verify_data member of a SSLv3 201 | // Finished message given the MD5 and SHA1 hashes of a set of handshake 202 | // messages. 203 | func finishedSum30(md5, sha1 hash.Hash, masterSecret []byte, magic [4]byte) []byte { 204 | md5.Write(magic[:]) 205 | md5.Write(masterSecret) 206 | md5.Write(ssl30Pad1[:]) 207 | md5Digest := md5.Sum(nil) 208 | 209 | md5.Reset() 210 | md5.Write(masterSecret) 211 | md5.Write(ssl30Pad2[:]) 212 | md5.Write(md5Digest) 213 | md5Digest = md5.Sum(nil) 214 | 215 | sha1.Write(magic[:]) 216 | sha1.Write(masterSecret) 217 | sha1.Write(ssl30Pad1[:40]) 218 | sha1Digest := sha1.Sum(nil) 219 | 220 | sha1.Reset() 221 | sha1.Write(masterSecret) 222 | sha1.Write(ssl30Pad2[:40]) 223 | sha1.Write(sha1Digest) 224 | sha1Digest = sha1.Sum(nil) 225 | 226 | ret := make([]byte, len(md5Digest)+len(sha1Digest)) 227 | copy(ret, md5Digest) 228 | copy(ret[len(md5Digest):], sha1Digest) 229 | return ret 230 | } 231 | 232 | var ssl3ClientFinishedMagic = [4]byte{0x43, 0x4c, 0x4e, 0x54} 233 | var ssl3ServerFinishedMagic = [4]byte{0x53, 0x52, 0x56, 0x52} 234 | 235 | // clientSum returns the contents of the verify_data member of a client's 236 | // Finished message. 237 | func (h finishedHash) clientSum(masterSecret []byte) []byte { 238 | if h.version == VersionSSL30 { 239 | return finishedSum30(h.clientMD5, h.client, masterSecret, ssl3ClientFinishedMagic) 240 | } 241 | 242 | out := make([]byte, finishedVerifyLength) 243 | if h.version >= VersionTLS12 { 244 | seed := h.client.Sum(nil) 245 | prf12(out, masterSecret, clientFinishedLabel, seed) 246 | } else { 247 | seed := make([]byte, 0, md5.Size+sha1.Size) 248 | seed = h.clientMD5.Sum(seed) 249 | seed = h.client.Sum(seed) 250 | prf10(out, masterSecret, clientFinishedLabel, seed) 251 | } 252 | return out 253 | } 254 | 255 | // serverSum returns the contents of the verify_data member of a server's 256 | // Finished message. 257 | func (h finishedHash) serverSum(masterSecret []byte) []byte { 258 | if h.version == VersionSSL30 { 259 | return finishedSum30(h.serverMD5, h.server, masterSecret, ssl3ServerFinishedMagic) 260 | } 261 | 262 | out := make([]byte, finishedVerifyLength) 263 | if h.version >= VersionTLS12 { 264 | seed := h.server.Sum(nil) 265 | prf12(out, masterSecret, serverFinishedLabel, seed) 266 | } else { 267 | seed := make([]byte, 0, md5.Size+sha1.Size) 268 | seed = h.serverMD5.Sum(seed) 269 | seed = h.server.Sum(seed) 270 | prf10(out, masterSecret, serverFinishedLabel, seed) 271 | } 272 | return out 273 | } 274 | 275 | // hashForClientCertificate returns a digest, hash function, and TLS 1.2 hash 276 | // id suitable for signing by a TLS client certificate. 277 | func (h finishedHash) hashForClientCertificate(sigType uint8) ([]byte, crypto.Hash, uint8) { 278 | if h.version >= VersionTLS12 { 279 | digest := h.server.Sum(nil) 280 | return digest, crypto.SHA256, hashSHA256 281 | } 282 | if sigType == signatureECDSA { 283 | digest := h.server.Sum(nil) 284 | return digest, crypto.SHA1, hashSHA1 285 | } 286 | 287 | digest := make([]byte, 0, 36) 288 | digest = h.serverMD5.Sum(digest) 289 | digest = h.server.Sum(digest) 290 | return digest, crypto.MD5SHA1, 0 /* not specified in TLS 1.2. */ 291 | } 292 | --------------------------------------------------------------------------------