├── .gitignore ├── Godeps ├── Godeps.json └── Readme ├── LICENSE ├── README.md ├── circle.yml ├── coverage.out ├── generateModuleBinaries.py ├── henchman ├── config.go ├── errors.go ├── errors_test.go ├── global_vars.go ├── helpers.go ├── inventory.go ├── inventory_test.go ├── local.go ├── local_test.go ├── log.go ├── machine.go ├── module.go ├── module_test.go ├── plan.go ├── plan_test.go ├── preprocessor.go ├── preprocessor_test.go ├── print.go ├── ssh.go ├── ssh_test.go ├── task.go ├── task_test.go ├── test │ ├── fail.yaml │ ├── inventory │ │ ├── invalidInventory.yaml │ │ ├── missingGroupsInventory.yaml │ │ ├── missingHostsInventory.yaml │ │ ├── sample.yaml │ │ ├── testInventory.yaml │ │ └── validInventory.yaml │ ├── plan │ │ ├── curlTest.yaml │ │ ├── debugAtPlanAndTaskLevel.yaml │ │ ├── filtersTest.yaml │ │ ├── ignoreErrsAtPlanLevel.yaml │ │ ├── ignoreErrsAtTaskLevel.yaml │ │ ├── ignoreErrsOverrideAtTaskLevel.yaml │ │ ├── incTaskWithVar │ │ │ ├── plan.yaml │ │ │ ├── tasks1.yaml │ │ │ └── tasks2.yaml │ │ ├── includeAndVarsAtTaskLevel.yaml │ │ ├── includeAndWhenAtTaskLevel.yaml │ │ ├── includeAtTaskLevel.yaml │ │ ├── includeAtVarsLevel.yaml │ │ ├── includeWithSudoAtTaskLevel.yaml │ │ ├── invalid │ │ │ ├── invalidDoubleIncludeAtTaskLevel.yaml │ │ │ ├── invalidDoubleIncludeAtVarsLevel.yaml │ │ │ ├── invalidIncludeFileAtVarsLevel.yaml │ │ │ ├── invalidIncludeFormatAtVarsLevel.yaml │ │ │ ├── invalidPongo2.yaml │ │ │ ├── invalidPongo2AtWhen.yaml │ │ │ ├── invalidRegisterKeyword.yaml │ │ │ ├── invalidRegisterVariable.yaml │ │ │ ├── invalidTask.yaml │ │ │ └── invalidTaskNoName.yaml │ │ ├── inventoryAtHostLevel.yaml │ │ ├── localModules.yaml │ │ ├── localTest.yaml │ │ ├── localWithCopy.yaml │ │ ├── localhostInPlan.yaml │ │ ├── nestedIncludeAtTaskLevel.yaml │ │ ├── planWithComments.yaml │ │ ├── planWithPongo2.yaml │ │ ├── registersAndWhen.yaml │ │ ├── retryAtTaskLevel.yaml │ │ ├── retryTest.yaml │ │ ├── sandboxPongo2.yaml │ │ ├── shellTest.yaml │ │ ├── sudoAtPlanLevel.yaml │ │ ├── sudoAtTaskLevel.yaml │ │ ├── sudoOverrideAtTaskLevel.yaml │ │ ├── tarModules.yaml │ │ ├── templateTest.yaml │ │ ├── withItemsAtTaskLevel.yaml │ │ ├── withItemsAtTaskLevelWithHenchmanitem.yaml │ │ └── withItemsTest.yaml │ ├── tasks │ │ ├── modulesTest.yaml │ │ ├── noInclude.yaml │ │ ├── withInclude.yaml │ │ ├── withIncludeAndVars.yaml │ │ ├── withIncludeAndWhen.yaml │ │ ├── withPongo2.yaml │ │ └── withSudo.yaml │ ├── templates │ │ ├── bad.sh │ │ ├── bad.zip │ │ ├── temp1 │ │ ├── temp2 │ │ ├── templates2 │ │ │ ├── temp3 │ │ │ └── temp4 │ │ └── templates3 │ │ │ ├── temp3 │ │ │ ├── temp4 │ │ │ ├── temp5 │ │ │ └── temp6 │ └── vars │ │ ├── vars.yaml │ │ └── vars2.yaml ├── transport.go └── transport_test.go ├── main.go ├── modules ├── append │ └── append ├── apt │ └── apt_module.go ├── copy │ ├── copy │ └── copy_module.go ├── curl │ └── curl │ │ ├── exec │ │ ├── requests │ │ ├── .gitignore │ │ ├── LICENSE │ │ ├── MANIFEST.in │ │ ├── NOTICE │ │ └── requests │ │ │ ├── __init__.py │ │ │ ├── adapters.py │ │ │ ├── api.py │ │ │ ├── auth.py │ │ │ ├── cacert.pem │ │ │ ├── certs.py │ │ │ ├── compat.py │ │ │ ├── cookies.py │ │ │ ├── exceptions.py │ │ │ ├── hooks.py │ │ │ ├── models.py │ │ │ ├── packages │ │ │ ├── README.rst │ │ │ ├── __init__.py │ │ │ ├── chardet │ │ │ │ ├── __init__.py │ │ │ │ ├── big5freq.py │ │ │ │ ├── big5prober.py │ │ │ │ ├── chardetect.py │ │ │ │ ├── chardistribution.py │ │ │ │ ├── charsetgroupprober.py │ │ │ │ ├── charsetprober.py │ │ │ │ ├── codingstatemachine.py │ │ │ │ ├── compat.py │ │ │ │ ├── constants.py │ │ │ │ ├── cp949prober.py │ │ │ │ ├── escprober.py │ │ │ │ ├── escsm.py │ │ │ │ ├── eucjpprober.py │ │ │ │ ├── euckrfreq.py │ │ │ │ ├── euckrprober.py │ │ │ │ ├── euctwfreq.py │ │ │ │ ├── euctwprober.py │ │ │ │ ├── gb2312freq.py │ │ │ │ ├── gb2312prober.py │ │ │ │ ├── hebrewprober.py │ │ │ │ ├── jisfreq.py │ │ │ │ ├── jpcntx.py │ │ │ │ ├── langbulgarianmodel.py │ │ │ │ ├── langcyrillicmodel.py │ │ │ │ ├── langgreekmodel.py │ │ │ │ ├── langhebrewmodel.py │ │ │ │ ├── langhungarianmodel.py │ │ │ │ ├── langthaimodel.py │ │ │ │ ├── latin1prober.py │ │ │ │ ├── mbcharsetprober.py │ │ │ │ ├── mbcsgroupprober.py │ │ │ │ ├── mbcssm.py │ │ │ │ ├── sbcharsetprober.py │ │ │ │ ├── sbcsgroupprober.py │ │ │ │ ├── sjisprober.py │ │ │ │ ├── universaldetector.py │ │ │ │ └── utf8prober.py │ │ │ └── urllib3 │ │ │ │ ├── __init__.py │ │ │ │ ├── _collections.py │ │ │ │ ├── connection.py │ │ │ │ ├── connectionpool.py │ │ │ │ ├── contrib │ │ │ │ ├── __init__.py │ │ │ │ ├── appengine.py │ │ │ │ ├── ntlmpool.py │ │ │ │ └── pyopenssl.py │ │ │ │ ├── exceptions.py │ │ │ │ ├── fields.py │ │ │ │ ├── filepost.py │ │ │ │ ├── packages │ │ │ │ ├── __init__.py │ │ │ │ ├── ordered_dict.py │ │ │ │ ├── six.py │ │ │ │ └── ssl_match_hostname │ │ │ │ │ ├── __init__.py │ │ │ │ │ └── _implementation.py │ │ │ │ ├── poolmanager.py │ │ │ │ ├── request.py │ │ │ │ ├── response.py │ │ │ │ └── util │ │ │ │ ├── __init__.py │ │ │ │ ├── connection.py │ │ │ │ ├── request.py │ │ │ │ ├── response.py │ │ │ │ ├── retry.py │ │ │ │ ├── ssl_.py │ │ │ │ ├── timeout.py │ │ │ │ └── url.py │ │ │ ├── sessions.py │ │ │ ├── status_codes.py │ │ │ ├── structures.py │ │ │ └── utils.py │ │ └── xmltodict │ │ ├── LICENSE │ │ └── xmltodict.py ├── rpm │ ├── rpm │ └── rpm_module.go ├── shell │ ├── shell │ └── shell_module.go ├── template │ ├── template │ └── template_module.go └── yum │ ├── yum │ └── yum_module.go ├── package.sh └── vendor ├── github.com ├── codegangsta │ └── cli │ │ ├── .travis.yml │ │ ├── LICENSE │ │ ├── README.md │ │ ├── app.go │ │ ├── cli.go │ │ ├── command.go │ │ ├── context.go │ │ ├── flag.go │ │ └── help.go ├── flosch │ └── pongo2 │ │ ├── .gitignore │ │ ├── .travis.yml │ │ ├── AUTHORS │ │ ├── LICENSE │ │ ├── README.md │ │ ├── context.go │ │ ├── doc.go │ │ ├── error.go │ │ ├── filters.go │ │ ├── filters_builtin.go │ │ ├── helpers.go │ │ ├── lexer.go │ │ ├── nodes.go │ │ ├── nodes_html.go │ │ ├── nodes_wrapper.go │ │ ├── parser.go │ │ ├── parser_document.go │ │ ├── parser_expression.go │ │ ├── pongo2.go │ │ ├── tags.go │ │ ├── tags_autoescape.go │ │ ├── tags_block.go │ │ ├── tags_comment.go │ │ ├── tags_cycle.go │ │ ├── tags_extends.go │ │ ├── tags_filter.go │ │ ├── tags_firstof.go │ │ ├── tags_for.go │ │ ├── tags_if.go │ │ ├── tags_ifchanged.go │ │ ├── tags_ifequal.go │ │ ├── tags_ifnotequal.go │ │ ├── tags_import.go │ │ ├── tags_include.go │ │ ├── tags_lorem.go │ │ ├── tags_macro.go │ │ ├── tags_now.go │ │ ├── tags_set.go │ │ ├── tags_spaceless.go │ │ ├── tags_ssi.go │ │ ├── tags_templatetag.go │ │ ├── tags_widthratio.go │ │ ├── tags_with.go │ │ ├── template.go │ │ ├── template_loader.go │ │ ├── template_sets.go │ │ ├── value.go │ │ └── variable.go ├── flynn │ └── go-shlex │ │ ├── COPYING │ │ ├── Makefile │ │ ├── README.md │ │ └── shlex.go ├── kr │ └── fs │ │ ├── LICENSE │ │ ├── Readme │ │ ├── filesystem.go │ │ └── walk.go ├── mgutz │ └── ansi │ │ ├── .gitignore │ │ ├── LICENSE │ │ ├── README.md │ │ ├── ansi.go │ │ ├── doc.go │ │ └── print.go ├── pborman │ └── uuid │ │ ├── CONTRIBUTORS │ │ ├── LICENSE │ │ ├── dce.go │ │ ├── doc.go │ │ ├── hash.go │ │ ├── json.go │ │ ├── node.go │ │ ├── sql.go │ │ ├── time.go │ │ ├── util.go │ │ ├── uuid.go │ │ ├── version1.go │ │ └── version4.go └── pkg │ └── sftp │ ├── .gitignore │ ├── CONTRIBUTORS │ ├── LICENSE │ ├── README.md │ ├── attrs.go │ ├── attrs_stubs.go │ ├── attrs_unix.go │ ├── client.go │ ├── debug.go │ ├── packet.go │ ├── release.go │ ├── server.go │ ├── server_stubs.go │ ├── server_unix.go │ ├── sftp.go │ └── wercker.yml ├── golang.org └── x │ └── crypto │ ├── AUTHORS │ ├── CONTRIBUTORS │ ├── LICENSE │ ├── PATENTS │ ├── curve25519 │ ├── const_amd64.s │ ├── cswap_amd64.s │ ├── curve25519.go │ ├── doc.go │ ├── freeze_amd64.s │ ├── ladderstep_amd64.s │ ├── mont25519_amd64.go │ ├── mul_amd64.s │ └── square_amd64.s │ └── ssh │ ├── buffer.go │ ├── certs.go │ ├── channel.go │ ├── cipher.go │ ├── client.go │ ├── client_auth.go │ ├── common.go │ ├── connection.go │ ├── doc.go │ ├── handshake.go │ ├── kex.go │ ├── keys.go │ ├── mac.go │ ├── messages.go │ ├── mux.go │ ├── server.go │ ├── session.go │ ├── tcpip.go │ └── transport.go └── gopkg.in ├── Sirupsen └── logrus.v0 │ ├── .gitignore │ ├── .travis.yml │ ├── CHANGELOG.md │ ├── LICENSE │ ├── README.md │ ├── doc.go │ ├── entry.go │ ├── exported.go │ ├── formatter.go │ ├── hooks.go │ ├── json_formatter.go │ ├── logger.go │ ├── logrus.go │ ├── terminal_bsd.go │ ├── terminal_linux.go │ ├── terminal_notwindows.go │ ├── terminal_windows.go │ ├── text_formatter.go │ └── writer.go └── yaml.v2 ├── LICENSE ├── LICENSE.libyaml ├── README.md ├── apic.go ├── decode.go ├── emitterc.go ├── encode.go ├── parserc.go ├── readerc.go ├── resolve.go ├── scannerc.go ├── sorter.go ├── writerc.go ├── yaml.go ├── yamlh.go └── yamlprivateh.go /.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | 10 | # Architecture specific extensions/prefixes 11 | *.[568vq] 12 | [568vq].out 13 | 14 | *.cgo1.go 15 | *.cgo2.c 16 | _cgo_defun.c 17 | _cgo_gotypes.go 18 | _cgo_export.* 19 | 20 | _testmain.go 21 | 22 | *.exe 23 | *.test 24 | *.prof 25 | *.swp 26 | 27 | bin 28 | modules/*/*.darwin 29 | modules/*/*.linux 30 | *.pem 31 | .DS_Store 32 | .idea 33 | -------------------------------------------------------------------------------- /Godeps/Godeps.json: -------------------------------------------------------------------------------- 1 | { 2 | "ImportPath": "github.com/apigee/henchman", 3 | "GoVersion": "go1.7", 4 | "GodepVersion": "v75", 5 | "Deps": [ 6 | { 7 | "ImportPath": "github.com/codegangsta/cli", 8 | "Comment": "v1.3.1-1-gfbda1ce", 9 | "Rev": "fbda1ce02d5dabcee952040e5f4025753b6c9ce0" 10 | }, 11 | { 12 | "ImportPath": "github.com/flosch/pongo2", 13 | "Comment": "v1.0-rc1-174-gf5d79aa", 14 | "Rev": "f5d79aa0a914c08eb7f51a96cd7b2dbbe46fca46" 15 | }, 16 | { 17 | "ImportPath": "github.com/flynn/go-shlex", 18 | "Rev": "3f9db97f856818214da2e1057f8ad84803971cff" 19 | }, 20 | { 21 | "ImportPath": "github.com/kr/fs", 22 | "Rev": "2788f0dbd16903de03cb8186e5c7d97b69ad387b" 23 | }, 24 | { 25 | "ImportPath": "github.com/mgutz/ansi", 26 | "Rev": "c286dcecd19ff979eeb73ea444e479b903f2cfcb" 27 | }, 28 | { 29 | "ImportPath": "github.com/pborman/uuid", 30 | "Rev": "cccd189d45f7ac3368a0d127efb7f4d08ae0b655" 31 | }, 32 | { 33 | "ImportPath": "github.com/pkg/sftp", 34 | "Rev": "e09e01e6e10971840f7639df3dd747e6fd2dff3a" 35 | }, 36 | { 37 | "ImportPath": "golang.org/x/crypto/curve25519", 38 | "Rev": "c8b9e6388ef638d5a8a9d865c634befdc46a6784" 39 | }, 40 | { 41 | "ImportPath": "golang.org/x/crypto/ssh", 42 | "Rev": "c8b9e6388ef638d5a8a9d865c634befdc46a6784" 43 | }, 44 | { 45 | "ImportPath": "gopkg.in/Sirupsen/logrus.v0", 46 | "Comment": "v0.8.7", 47 | "Rev": "418b41d23a1bf978c06faea5313ba194650ac088" 48 | }, 49 | { 50 | "ImportPath": "gopkg.in/yaml.v2", 51 | "Rev": "7ad95dd0798a40da1ccdff6dff35fd177b5edf40" 52 | } 53 | ] 54 | } 55 | -------------------------------------------------------------------------------- /Godeps/Readme: -------------------------------------------------------------------------------- 1 | This directory tree is generated automatically by godep. 2 | 3 | Please do not edit. 4 | 5 | See https://github.com/tools/godep for more information. 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015, Apigee 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | * Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 10 | * Redistributions in binary form must reproduce the above copyright notice, 11 | this list of conditions and the following disclaimer in the documentation 12 | and/or other materials provided with the distribution. 13 | 14 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 15 | AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16 | IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 17 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 18 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 20 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 21 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 22 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 23 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 24 | 25 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | 2 | 3 | # henchman [![Circle CI](https://circleci.com/gh/apigee/henchman/tree/master.svg?style=svg)](https://circleci.com/gh/apigee/henchman/tree/master) 4 | 5 | ## What is Henchman 6 | Henchman is an orchestration and automation tool written in Golang, inspired by Ansible with support for custom transports and inventories. 7 | 8 | Check out the [wiki](https://github.com/apigee/henchman/wiki) to learn more. 9 | 10 | ## How Henchman Works 11 | Henchman executes a plan (a collection of tasks) on a given set of machines. Currently henchman uses SSH as a transport to execute a plan on hosts specified in an inventory. It will be possible to use custom transports and custom inventory scripts in the future. 12 | 13 | ## Building Henchman 14 | * Install go [here](https://golang.org/doc/install) 15 | * Clone this repo to `$GOPATH/src/github.com/apigee` 16 | * If you have not done so, set `export $PATH=$PATH:$GOPATH/bin` 17 | * `go get github.com/tools/godep` 18 | * `godep restore` 19 | * `godep go build -o bin/henchman` 20 | * If you are developing use `godep go build -race -o bin/henchman` 21 | * Build modules `find modules -name '*.go' | awk -F/ '{print "-o bin/modules/"$2"/"$2" "$0}' | xargs -l1 go build` 22 | 23 | ## Contributing 24 | Just clone or fork from [https://github.com/apigee/henchman](https://github.com/apigee/henchman) and off you go! Fixing issues marked `easy` in the issue tracker is a great way to get started. Or you can help by creating more modules. Look at the modules section for more details. 25 | 26 | ### Creating HenchmanErrors 27 | HenchmanErrors can be created using the `HenchErr(err, map[string]interface{}, "extension message")` call. Creating a HenchmanError as opposed to a standard error allows the user to pass in extra information for logrus. Here are a few key things to note when creating a HenchErr: 28 | * `err` - place any `error` in here 29 | * `map[string]interface{}` - Place any information about the CURRENT function it's in. For example, plan information, task information, what machine it's on 30 | * `extension message` - Is a string that is prefixed onto the base error message. This extension message should contain information about the function that produced the error. For example, if an err occurred while unmarshalling, the extension message would contain "While unmarshalling". 31 | -------------------------------------------------------------------------------- /circle.yml: -------------------------------------------------------------------------------- 1 | machine: 2 | environment: 3 | IMPORT_PATH: "github.com/$CIRCLE_PROJECT_USERNAME/$CIRCLE_PROJECT_REPONAME" 4 | 5 | general: 6 | artifacts: 7 | - "artifacts/*.tar.gz" 8 | branches: 9 | only: 10 | - master 11 | 12 | dependencies: 13 | pre: 14 | - go get github.com/tools/godep 15 | - go get github.com/stretchr/testify/assert 16 | - go get github.com/stretchr/testify/require 17 | override: 18 | - mkdir -p "$GOPATH/src/$IMPORT_PATH" 19 | - rsync -azC --delete ./ "$GOPATH/src/$IMPORT_PATH/" 20 | 21 | test: 22 | pre: 23 | # Getting import errors in circleci 24 | - go get github.com/apigee/henchman 25 | - godep restore 26 | - go vet -x ./henchman 27 | override: 28 | - go test -v ./... 29 | - go test ./henchman -covermode=count -coverprofile=coverage.out -coverpkg=./... 30 | post: 31 | - sh ./package.sh 32 | 33 | 34 | -------------------------------------------------------------------------------- /generateModuleBinaries.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import subprocess 4 | import traceback 5 | import glob 6 | import os.path 7 | 8 | def create_binary_name(source, os_name): 9 | binary_name = source.split("/") 10 | binary_name[2] = binary_name[1]+"."+os_name 11 | return "/".join(binary_name) 12 | 13 | def create_binary(os_name, binary_name, go_file): 14 | cmd = "GOOS=%s godep go build -o %s %s" % (os_name, binary_name, go_file) 15 | print 'Executing => "%s"' % cmd 16 | p = subprocess.Popen(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 17 | stdout, stderr = p.communicate() 18 | if p.returncode > 0: 19 | raise Exception(stderr) 20 | print "Successfully created %s" % binary_name 21 | 22 | # pass 1 to recompile all 23 | # pass 2 to recompile one module 24 | try: 25 | recompile = False 26 | compile_file = "" 27 | if len(sys.argv) > 1: 28 | if sys.argv[1] == "2": 29 | compile_file = sys.argv[2] 30 | recompile = True 31 | 32 | for go_file in glob.glob("modules/*/*.go"): 33 | if compile_file == "" or compile_file == go_file.split("/")[-1]: 34 | for os_name in ["linux", "darwin"]: 35 | binary_name = create_binary_name(go_file, os_name) 36 | if recompile or not os.path.isfile(binary_name): 37 | create_binary(os_name, binary_name, go_file) 38 | else: 39 | print "'%s' already present. Pass in 1 as the first parameter to recompile all go modules" % binary_name 40 | except Exception as e: 41 | if e: 42 | print "Error - %s" % e 43 | else: 44 | traceback.print_exec 45 | -------------------------------------------------------------------------------- /henchman/config.go: -------------------------------------------------------------------------------- 1 | package henchman 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "io/ioutil" 7 | "os" 8 | ) 9 | 10 | type Configuration struct { 11 | Log string 12 | ExecOrder map[string][]string 13 | } 14 | 15 | // Global config object for henchman to use 16 | var Config Configuration 17 | 18 | const DEFAULT_CONFIGURATION = ` 19 | { 20 | "log": "~/.henchman/system.log", 21 | "execOrder": { 22 | "default": ["exec_module"], 23 | "copy": ["stage", "exec_module"], 24 | "template": ["process_template", "stage", "reset_src", "exec_module"] 25 | } 26 | } 27 | ` 28 | 29 | // FIXME: If a custom configuration is given, it should be merged with DEFAULT configuration 30 | func InitConfiguration(filename string) error { 31 | var buf []byte 32 | if _, err := os.Stat(filename); os.IsNotExist(err) { 33 | fmt.Printf("conf.json is not present. Applying default configuration\n") 34 | buf = []byte(DEFAULT_CONFIGURATION) 35 | } else { 36 | buf, err = ioutil.ReadFile(filename) 37 | if err != nil { 38 | return fmt.Errorf("Error reading conf.json :: " + err.Error()) 39 | } 40 | } 41 | 42 | err := json.Unmarshal(buf, &Config) 43 | if err != nil { 44 | return fmt.Errorf("Error unmarshalling conf.json :: " + err.Error()) 45 | } 46 | 47 | return nil 48 | } 49 | -------------------------------------------------------------------------------- /henchman/errors.go: -------------------------------------------------------------------------------- 1 | package henchman 2 | 3 | import ( 4 | "fmt" 5 | "reflect" 6 | ) 7 | 8 | type HenchmanError struct { 9 | Err error 10 | Fields map[string]interface{} 11 | msg string 12 | } 13 | 14 | func (henchError *HenchmanError) Error() string { 15 | return henchError.msg 16 | } 17 | 18 | func HenchErr(err error, fields map[string]interface{}, extMsg string) error { 19 | switch val := err.(type) { 20 | case *HenchmanError: 21 | if fields != nil { 22 | MergeMap(fields, val.Fields, false) 23 | } 24 | if extMsg != "" { 25 | val.msg = (extMsg + " :: " + val.msg) 26 | } 27 | return err 28 | default: 29 | newFields := fields 30 | msg := err.Error() 31 | 32 | if newFields == nil { 33 | newFields = make(map[string]interface{}) 34 | } 35 | if extMsg != "" { 36 | msg = (extMsg + " :: " + msg) 37 | } 38 | return &HenchmanError{ 39 | Err: err, 40 | Fields: newFields, 41 | msg: msg, 42 | } 43 | } 44 | } 45 | 46 | func ErrWrongType(field interface{}, val interface{}, _type string) error { 47 | return fmt.Errorf("For field '%v', '%v' is of typ '%v' not of type %v", field, val, reflect.TypeOf(val), _type) 48 | } 49 | 50 | func ErrNotValidVariable(val interface{}) error { 51 | return fmt.Errorf("'%v' is not a valid variable name", val) 52 | } 53 | 54 | func ErrKeyword(val interface{}) error { 55 | return fmt.Errorf("'%v' is a keyword", val) 56 | } 57 | 58 | func isKeyword(val string) bool { 59 | switch val { 60 | case "vars": 61 | return true 62 | case "item": 63 | return true 64 | case "inv": 65 | return true 66 | case "current_hostname": 67 | return true 68 | default: 69 | return false 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /henchman/errors_test.go: -------------------------------------------------------------------------------- 1 | package henchman 2 | 3 | import ( 4 | "fmt" 5 | log "gopkg.in/Sirupsen/logrus.v0" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | _ "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func TestHenchErr(t *testing.T) { 13 | err := fmt.Errorf("Test Error") 14 | 15 | newErr := HenchErr(err, nil, "").(*HenchmanError) 16 | assert.NotNil(t, newErr.Fields) 17 | assert.NotNil(t, newErr.Err) 18 | assert.Equal(t, "Test Error", newErr.Error()) 19 | 20 | newErr = HenchErr(newErr, log.Fields{"hello": "world"}, "Message").(*HenchmanError) 21 | assert.Equal(t, "world", newErr.Fields["hello"]) 22 | assert.Equal(t, "Test Error", newErr.Err.Error()) 23 | assert.Equal(t, "Message :: Test Error", newErr.Error()) 24 | } 25 | -------------------------------------------------------------------------------- /henchman/global_vars.go: -------------------------------------------------------------------------------- 1 | package henchman 2 | 3 | var ( 4 | DebugFlag bool 5 | OsNames = []string{"darwin", "linux"} 6 | ) 7 | 8 | const ( 9 | HENCHMAN_PREFIX = "henchman_" 10 | MODULES_TARGET = "modules.tar" 11 | IGNORED_EXTS = "zip,tar,tar.gz" 12 | REMOTE_DIR = "${HOME}/.henchman/" 13 | ) 14 | -------------------------------------------------------------------------------- /henchman/local_test.go: -------------------------------------------------------------------------------- 1 | package henchman 2 | 3 | import ( 4 | "path" 5 | "strings" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func TestLocalExec(t *testing.T) { 13 | c := make(TransportConfig) 14 | local := LocalTransport{} 15 | err := local.Initialize(&c) 16 | require.NoError(t, err) 17 | buf, err := local.Exec("cat", []byte("foo"), false) 18 | require.NoError(t, err) 19 | assert.Equal(t, "foo", strings.TrimSpace(buf.String()), "Expected 'foo'") 20 | } 21 | 22 | func TestLocalPut(t *testing.T) { 23 | fname := "henchman.test.put" 24 | fpath := writeTempFile([]byte("foobar"), fname) 25 | defer rmTempFile(path.Join("/tmp", fname)) 26 | defer rmTempFile(path.Join("/tmp", fname+".cp")) 27 | c := make(TransportConfig) 28 | local := LocalTransport{} 29 | err := local.Initialize(&c) 30 | require.NoError(t, err) 31 | err = local.Put(fpath, fpath+".cp", "") 32 | require.NoError(t, err) 33 | } 34 | 35 | func TestLocalPutWithSpaces(t *testing.T) { 36 | fname := "henchman.test put" 37 | fpath := writeTempFile([]byte("foobar"), fname) 38 | defer rmTempFile(path.Join("/tmp", fname)) 39 | defer rmTempFile(path.Join("/tmp", fname+".cp")) 40 | c := make(TransportConfig) 41 | local := LocalTransport{} 42 | err := local.Initialize(&c) 43 | require.NoError(t, err) 44 | err = local.Put(fpath, fpath+".cp", "") 45 | require.NoError(t, err) 46 | } 47 | -------------------------------------------------------------------------------- /henchman/log.go: -------------------------------------------------------------------------------- 1 | package henchman 2 | 3 | import ( 4 | logrus "gopkg.in/Sirupsen/logrus.v0" 5 | "os" 6 | "path/filepath" 7 | "strings" 8 | ) 9 | 10 | var jsonLog = logrus.New() 11 | 12 | // Evaluates the home env variable in a path and converts it 13 | func evaluateHomeEnv(path string) string { 14 | sects := strings.Split(path, "/") 15 | newPath := "" 16 | 17 | for _, v := range sects { 18 | if v == "~" || v == "${HOME}" { 19 | newPath = filepath.Join(newPath, os.Getenv("HOME")) 20 | } else { 21 | newPath = filepath.Join(newPath, v) 22 | } 23 | } 24 | 25 | return newPath 26 | } 27 | 28 | func InitLog() error { 29 | jsonLog.Level = logrus.DebugLevel 30 | jsonLog.Formatter = new(logrus.JSONFormatter) 31 | 32 | // NOTE: hardcoded for now 33 | 34 | path := evaluateHomeEnv(Config.Log) 35 | dir := filepath.Dir(path) 36 | err := os.MkdirAll(dir, 0755) 37 | if err != nil { 38 | return err 39 | } 40 | 41 | f, err := os.OpenFile(path, os.O_CREATE|os.O_APPEND|os.O_RDWR, 0666) 42 | if err != nil { 43 | return err 44 | } 45 | 46 | jsonLog.Out = f 47 | 48 | return nil 49 | } 50 | 51 | // wrapper for debug 52 | func Debug(fields map[string]interface{}, msg string) { 53 | if DebugFlag { 54 | if fields == nil { 55 | jsonLog.Debug(msg) 56 | } else { 57 | jsonLog.WithFields(fields).Debug(msg) 58 | } 59 | } 60 | } 61 | 62 | // wrapper for Info 63 | func Info(fields map[string]interface{}, msg string) { 64 | if fields == nil { 65 | jsonLog.Info(msg) 66 | } else { 67 | jsonLog.WithFields(fields).Info(msg) 68 | } 69 | } 70 | 71 | // wrapper for Fatal 72 | func Fatal(fields map[string]interface{}, msg string) { 73 | if fields == nil { 74 | logrus.Error(msg) 75 | jsonLog.Fatal(msg) 76 | } else { 77 | logrus.WithFields(fields).Error(msg) 78 | jsonLog.WithFields(fields).Fatal(msg) 79 | } 80 | } 81 | 82 | // wrapper for Error 83 | func Error(fields map[string]interface{}, msg string) { 84 | if fields == nil { 85 | jsonLog.Error(msg) 86 | logrus.Error(msg) 87 | } else { 88 | jsonLog.WithFields(fields).Error(msg) 89 | logrus.WithFields(fields).Error(msg) 90 | } 91 | } 92 | 93 | func Warn(fields map[string]interface{}, msg string) { 94 | if fields == nil { 95 | jsonLog.Warn(msg) 96 | logrus.Warn(msg) 97 | } else { 98 | jsonLog.WithFields(fields).Warn(msg) 99 | logrus.WithFields(fields).Warn(msg) 100 | } 101 | } 102 | -------------------------------------------------------------------------------- /henchman/machine.go: -------------------------------------------------------------------------------- 1 | package henchman 2 | 3 | type Machine struct { 4 | Hostname string 5 | Vars VarsMap 6 | Transport TransportInterface 7 | } 8 | -------------------------------------------------------------------------------- /henchman/plan_test.go: -------------------------------------------------------------------------------- 1 | // FIXME: Can't test plan reliably till we fix #19, 2 | 3 | package henchman 4 | 5 | // import ( 6 | // "testing" 7 | 8 | // _ "github.com/stretchr/testify/assert" 9 | // "github.com/stretchr/testify/require" 10 | // ) 11 | 12 | // func TestPlanExecute(t *testing.T) { 13 | // inventory, err := loadValidInventory() 14 | // require.NoError(t, err) 15 | // // Just one task 16 | // task := Task{} 17 | // m, err := NewModule("test", "foo=bar") 18 | // require.NoError(t, err) 19 | 20 | // task.Id = "f" 21 | // task.Sudo = false 22 | // task.Name = "testTask" 23 | // task.Module = m 24 | // task.Local = false 25 | 26 | // p := Plan{} 27 | // p.Name = "Test Plan" 28 | // p.Inventory = inventory 29 | // p.Vars = make(VarsMap) 30 | // p.Tasks = append(p.Tasks, &task) 31 | 32 | // tc := make(TransportConfig) 33 | // tc["username"] = "foobar" 34 | // machines, err := inventory.GetMachines(tc) 35 | // require.NoError(t, err) 36 | 37 | // err = p.Execute(machines) 38 | // require.NoError(t, err) 39 | // } 40 | -------------------------------------------------------------------------------- /henchman/print.go: -------------------------------------------------------------------------------- 1 | package henchman 2 | 3 | import ( 4 | "fmt" 5 | "sync" 6 | ) 7 | 8 | var printLock sync.Mutex 9 | 10 | /** 11 | * These functions deal with printing 12 | * They are mainly wrappers that have locks 13 | */ 14 | // recursively print a map. Only issue is everything is out of order in a map. Still prints nicely though 15 | func printRecurse(output interface{}, padding string, retVal string) string { 16 | tmpVal := retVal 17 | switch output.(type) { 18 | /* 19 | case VarsMap: 20 | for key, val := range output.(VarsMap) { 21 | switch val.(type) { 22 | case map[string]interface{}: 23 | tmpVal += fmt.Sprintf("%s%v:\n", padding, key) 24 | tmpVal += printRecurse(val, padding+" ", "") 25 | default: 26 | //tmpVal += fmt.Sprintf("%s%v: %v (%v)\n", padding, key, val, reflect.TypeOf(val)) 27 | tmpVal += fmt.Sprintf("%s%v: %v\n", padding, key, val) 28 | } 29 | } 30 | */ 31 | case map[string]interface{}: 32 | for key, val := range output.(map[string]interface{}) { 33 | switch val.(type) { 34 | case map[string]interface{}: 35 | tmpVal += fmt.Sprintf("%s%v:\n", padding, key) 36 | tmpVal += printRecurse(val, padding+" ", "") 37 | default: 38 | //tmpVal += fmt.Sprintf("%s%v: %v (%v)\n", padding, key, val, reflect.TypeOf(val)) 39 | tmpVal += fmt.Sprintf("%s%v: %v\n", padding, key, val) 40 | } 41 | } 42 | default: 43 | //tmpVal += fmt.Sprintf("%s%v (%s)\n", padding, output, reflect.TypeOf(output)) 44 | tmpVal += fmt.Sprintf("%s%v\n", padding, output) 45 | } 46 | 47 | return tmpVal 48 | } 49 | 50 | // wrapper for Printf and Println with a lock 51 | func Printf(msg string, a ...interface{}) { 52 | printLock.Lock() 53 | defer printLock.Unlock() 54 | fmt.Printf(msg, a...) 55 | } 56 | 57 | func Println(msg string) { 58 | printLock.Lock() 59 | defer printLock.Unlock() 60 | fmt.Println(msg) 61 | } 62 | 63 | // Does a printf and fills the extra white space 64 | // Just specify the max size to fill to and the string to fill with 65 | func PrintfAndFill(size int, fill string, msg string, a ...interface{}) { 66 | printLock.Lock() 67 | defer printLock.Unlock() 68 | 69 | val := fmt.Sprintf(msg, a...) 70 | 71 | var padding string 72 | for i := 0; i < (size - len(val)); i++ { 73 | padding += fill 74 | } 75 | fmt.Println(val + padding) 76 | } 77 | 78 | // Does a Sprintf and fills the extra white space 79 | func SprintfAndFill(size int, fill string, msg string, a ...interface{}) string { 80 | val := fmt.Sprintf(msg, a...) 81 | 82 | var padding string 83 | for i := 0; i < (size - len(val)); i++ { 84 | padding += fill 85 | } 86 | 87 | return val + padding 88 | } 89 | -------------------------------------------------------------------------------- /henchman/ssh_test.go: -------------------------------------------------------------------------------- 1 | package henchman 2 | 3 | import ( 4 | _ "fmt" 5 | _ "os" 6 | "testing" 7 | 8 | //"github.com/stretchr/testify/assert" 9 | "github.com/stretchr/testify/require" 10 | ) 11 | 12 | func TestValidPasswordAuth(t *testing.T) { 13 | c := make(TransportConfig) 14 | c["username"] = "user1" 15 | c["password"] = "password" 16 | c["hostname"] = "localhost" 17 | _, err := NewSSH(&c) 18 | 19 | require.NoError(t, err) 20 | } 21 | 22 | func TestInvalidPasswordAuth(t *testing.T) { 23 | c := make(TransportConfig) 24 | c["username"] = "user1" 25 | c["hostname"] = "localhost" 26 | _, err := NewSSH(&c) 27 | require.Error(t, err, "There should have been an error since password isn't present") 28 | } 29 | 30 | // func TestSSHExec(t *testing.T) { 31 | // c := make(TransportConfig) 32 | // c["username"] = "vagrant" 33 | // c["keyfile"] = "/Users/sudharsh/.vagrant.d/insecure_private_key" 34 | // c["hostname"] = "10.224.192.11" 35 | // ssht, err := NewSSH(&c) 36 | // buf, err := ssht.Exec("ls -al") 37 | // if err != nil { 38 | // t.Errorf(err.Error()) 39 | // } 40 | // fmt.Printf("foo - %s\n", buf) 41 | // } 42 | 43 | // func TestSCP(t *testing.T) { 44 | // c := make(TransportConfig) 45 | // c["username"] = "vagrant" 46 | // c["keyfile"] = "/Users/sudharsh/.vagrant.d/insecure_private_key" 47 | // c["hostname"] = "10.224.192.11" 48 | // ssht, err := NewSSH(&c) 49 | // err = ssht.Transfer("/tmp/foo.yml", "/home/vagrant") 50 | // if err != nil { 51 | // t.Errorf(err.Error()) 52 | // } 53 | // } 54 | -------------------------------------------------------------------------------- /henchman/test/fail.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Fail plan" 3 | tasks: 4 | - name: "Bad task" 5 | shell: cmd="echo <10nc2290><*) blloper" 6 | debug: true 7 | -------------------------------------------------------------------------------- /henchman/test/inventory/invalidInventory.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | groups: 3 | nginx: 4 | - "192.168.1.1" 5 | - "192.168.1.2" 6 | db: 7 | hosts: 8 | - "1.1.1.1" 9 | - "1.1.1.2" 10 | - "1.1.1.3" 11 | vars: 12 | ulimit: 200 13 | henchman_user: "root" 14 | app: 15 | hosts: 16 | - "1.1.1.1" 17 | - "1.1.1.4" 18 | hostvars: 19 | "192.168.1.1": 20 | keyfile: "~/.ssh/another_key" 21 | henchman_user: "root" 22 | ulimit: 240 23 | files: 240 24 | "1.1.1.1": 25 | ulimit: 240 26 | files: 240 27 | -------------------------------------------------------------------------------- /henchman/test/inventory/missingGroupsInventory.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | nginx: 3 | hosts: 4 | - "192.168.1.1" 5 | - "192.168.1.2" 6 | vars: 7 | ulimit: 300 8 | henchman_keyfile: "~/.ssh/ssh_key" 9 | db: 10 | hosts: 11 | - "1.1.1.1" 12 | - "1.1.1.2" 13 | - "1.1.1.3" 14 | vars: 15 | ulimit: 200 16 | henchman_user: "root" 17 | app: 18 | hosts: 19 | - "1.1.1.1" 20 | - "1.1.1.4" 21 | hostvars: 22 | "192.168.1.1": 23 | keyfile: "~/.ssh/another_key" 24 | henchman_user: "root" 25 | ulimit: 240 26 | files: 240 27 | "1.1.1.1": 28 | ulimit: 240 29 | files: 240 30 | -------------------------------------------------------------------------------- /henchman/test/inventory/missingHostsInventory.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | groups: 3 | nginx: 4 | hosts: 5 | - "192.168.1.1" 6 | - "192.168.1.2" 7 | vars: 8 | ulimit: 300 9 | henchman_keyfile: "~/.ssh/ssh_key" 10 | db: 11 | vars: 12 | ulimit: 200 13 | henchman_user: "root" 14 | app: 15 | hosts: 16 | - "1.1.1.1" 17 | - "1.1.1.4" 18 | hostvars: 19 | "192.168.1.1": 20 | keyfile: "~/.ssh/another_key" 21 | henchman_user: "root" 22 | ulimit: 240 23 | files: 240 24 | "1.1.1.1": 25 | ulimit: 240 26 | files: 240 27 | -------------------------------------------------------------------------------- /henchman/test/inventory/sample.yaml: -------------------------------------------------------------------------------- 1 | hosts: 2 | "1.1.1.2": 3 | groups: 4 | - "org/coke" 5 | - "region/us" 6 | "1.1.1.3": 7 | groups: 8 | - "region/us" 9 | - "org/coke" 10 | groups: 11 | "org/coke": 12 | vars: 13 | version: 1 14 | "region/us": 15 | vars: 16 | version: 2 17 | heirarchy: 18 | - "org/{{ vars.org.name }}" 19 | - "region/{{ region.name }}" 20 | -------------------------------------------------------------------------------- /henchman/test/inventory/testInventory.yaml: -------------------------------------------------------------------------------- 1 | groups: 2 | test: 3 | hosts: 4 | - 192.168.33.10 5 | - 192.168.33.11 6 | vars: 7 | testVar: hello 8 | henchman_username: "vagrant" 9 | individual: 10 | hosts: 11 | - 192.168.33.10 12 | vars: 13 | testVar: hello 14 | second: 15 | hosts: 16 | - 192.168.33.11 17 | third: 18 | hosts: 19 | - 192.168.33.12 20 | global_vars: 21 | henchman_username: "vagrant" 22 | -------------------------------------------------------------------------------- /henchman/test/inventory/validInventory.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | groups: 3 | nginx: 4 | hosts: 5 | - "192.168.1.1" 6 | - "192.168.1.2" 7 | vars: 8 | ulimit: 300 9 | henchman_keyfile: "~/.ssh/ssh_key" 10 | db: 11 | hosts: 12 | - "1.1.1.1" 13 | - "1.1.1.2" 14 | - "1.1.1.3" 15 | vars: 16 | ulimit: 200 17 | henchman_user: "root" 18 | app: 19 | hosts: 20 | - "1.1.1.1" 21 | - "1.1.1.4" 22 | host_vars: 23 | "192.168.1.1": 24 | keyfile: "~/.ssh/another_key" 25 | henchman_user: "root" 26 | ulimit: 240 27 | files: 240 28 | "1.1.1.1": 29 | ulimit: 240 30 | files: 240 31 | 32 | global_vars: 33 | service: "iptables" 34 | henchman_user: "vagrant" 35 | henchman_keyfile: "~/.ssh/origin_key" 36 | 37 | 38 | -------------------------------------------------------------------------------- /henchman/test/plan/curlTest.yaml: -------------------------------------------------------------------------------- 1 | name: "Plan with curl" 2 | vars: 3 | service: iptables 4 | hosts: 5 | - test 6 | tasks: 7 | - name: "Test xml Curl" 8 | curl: url="http://ci.apigeng.com/v1/data/1k.xml" http="GET" loglevel=debug 9 | register: second 10 | - name: "Test json Curl" 11 | curl: url="http://ci.apigeng.com/v1/data/1k.json" http="GET" 12 | register: third 13 | - name: "Test Curl" 14 | curl: url="http://httpbin.org/ip" http="GET" 15 | register: first 16 | debug: true 17 | - name: "Test bad echo" 18 | shell: cmd="echo &(*&@^" 19 | debug: true 20 | when: 'vars.current_hostname == "192.168.33.11"' 21 | - name: "Test Shell" 22 | shell: cmd="echo {{ vars.current_hostname }}" 23 | debug: true 24 | -------------------------------------------------------------------------------- /henchman/test/plan/debugAtPlanAndTaskLevel.yaml: -------------------------------------------------------------------------------- 1 | name: "Plan with debug" 2 | debug: true 3 | vars: 4 | service: iptables 5 | tasks: 6 | - name: "Task One" 7 | shell: cmd="echo hello" 8 | debug: false 9 | - name: "Task Two" 10 | shell: cmd="echo goodbye" 11 | - name: "Task Three" 12 | shell: cmd="echo world" 13 | 14 | -------------------------------------------------------------------------------- /henchman/test/plan/filtersTest.yaml: -------------------------------------------------------------------------------- 1 | name: "Filter test plan" 2 | vars: 3 | service: 4 | - "iptables" 5 | - "jello" 6 | - "hello" 7 | - "ok" 8 | hosts: 9 | - individual 10 | tasks: 11 | - name: "Task One" 12 | shell: cmd="echo hello" loglevel=debug 13 | when: '"hello" not in vars.service' 14 | local: true 15 | -------------------------------------------------------------------------------- /henchman/test/plan/ignoreErrsAtPlanLevel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Sample plan" 3 | ignore_errors: true 4 | hosts: 5 | - "127.0.0.1:22" 6 | - 192.168.1.2 7 | tasks: 8 | - name: Sample task that does nothing 9 | action: cmd="ls" 10 | - name: Another task 11 | action: cmd="test" 12 | -------------------------------------------------------------------------------- /henchman/test/plan/ignoreErrsAtTaskLevel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Sample plan" 3 | tasks: 4 | - name: First task 5 | action: cmd="ls" 6 | ignore_errors: true 7 | - name: Second task 8 | action: cmd="echo" 9 | -------------------------------------------------------------------------------- /henchman/test/plan/ignoreErrsOverrideAtTaskLevel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Sample plan" 3 | ignore_errors: true 4 | tasks: 5 | - name: First task 6 | action: cmd="ls" 7 | - name: Second task 8 | action: cmd="echo" 9 | ignore_errors: false 10 | -------------------------------------------------------------------------------- /henchman/test/plan/incTaskWithVar/plan.yaml: -------------------------------------------------------------------------------- 1 | name: "Template Notation in Task Include" 2 | hosts: 3 | - individual 4 | vars: 5 | service: "iptables" 6 | key: 7 | first: "abcd1234" 8 | second: "efgh5678" 9 | tasks: 10 | - name: "Included Nested Task" 11 | include: "henchman/test/plan/incTaskWithVar/tasks1.yaml" 12 | vars: 13 | service: "notIpTables" 14 | orig_service: "{{ vars.service }}" 15 | key: "{{ vars.key.first }}" 16 | - name: "Included Nested Task" 17 | include: "henchman/test/plan/incTaskWithVar/tasks1.yaml" 18 | vars: 19 | key: "{{ vars.key.second }}" 20 | -------------------------------------------------------------------------------- /henchman/test/plan/incTaskWithVar/tasks1.yaml: -------------------------------------------------------------------------------- 1 | name: "List of Task" 2 | tasks: 3 | - name: "Include more tasks" 4 | include: "henchman/test/plan/incTaskWithVar/tasks2.yaml" 5 | vars: 6 | final: "{{ vars.original_service }}" 7 | - name: "Task 2" 8 | shell: cmd="echo {{ vars.service }}" 9 | - name: "Task 4" 10 | shell: cmd="echo {{ vars.key }}" 11 | - name: "Task 5" 12 | include: "henchman/test/plan/incTaskWithVar/tasks2.yaml" 13 | -------------------------------------------------------------------------------- /henchman/test/plan/incTaskWithVar/tasks2.yaml: -------------------------------------------------------------------------------- 1 | name: "Filler tasks" 2 | tasks: 3 | - name: "dummy" 4 | shell: cmd="echo is {{ vars.final }}" 5 | debug: true 6 | -------------------------------------------------------------------------------- /henchman/test/plan/includeAndVarsAtTaskLevel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Plan With Tasks and Vars" 3 | vars: 4 | foo: bar 5 | tasks: 6 | - name: task1 7 | action: ls=al 8 | - name: "included tasks" 9 | include: test/tasks/withIncludeAndVars.yaml 10 | vars: 11 | foo: nope 12 | bar: baz 13 | - name: task2 14 | action: hey="yoooo" 15 | -------------------------------------------------------------------------------- /henchman/test/plan/includeAndWhenAtTaskLevel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Plan with Task Includes And When" 3 | tasks: 4 | - name: "task 1" 5 | shell: cmd=echo 6 | when: test == true 7 | - name: "included tasks" 8 | include: test/tasks/withIncludeAndWhen.yaml 9 | when: test == false 10 | -------------------------------------------------------------------------------- /henchman/test/plan/includeAtTaskLevel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Plan with single Include" 3 | hosts: 4 | - nginx.* 5 | 6 | tasks: 7 | - name: task1 8 | action: cmd="ls -al" 9 | - name: "include tasks" 10 | include: test/tasks/noInclude.yaml 11 | -------------------------------------------------------------------------------- /henchman/test/plan/includeAtVarsLevel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Sample plan" 3 | vars: 4 | hello: world 5 | foo: scar 6 | include: 7 | - test/vars/vars.yaml 8 | - test/vars/vars2.yaml 9 | spam: eggs 10 | tasks: 11 | - name: Sample task that does nothing 12 | action: cmd="ls" 13 | - name: Second task 14 | action: cmd="echo" 15 | ignore_errors: true 16 | -------------------------------------------------------------------------------- /henchman/test/plan/includeWithSudoAtTaskLevel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Sample plan" 3 | tasks: 4 | - name: task1 5 | action: cmd="ls -al" 6 | - name: "included tasks" 7 | include: test/tasks/withSudo.yaml 8 | -------------------------------------------------------------------------------- /henchman/test/plan/invalid/invalidDoubleIncludeAtTaskLevel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Plan with double include at task level" 3 | tasks: 4 | - include: test/tasks/noInclude.yaml 5 | include: test/tasks/withSudo.yaml 6 | -------------------------------------------------------------------------------- /henchman/test/plan/invalid/invalidDoubleIncludeAtVarsLevel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Sample plan" 3 | vars: 4 | hello: world 5 | foo: scar 6 | include: 7 | - test/vars/vars.yaml 8 | include: 9 | - test/vars/vars2.yaml 10 | spam: eggs 11 | tasks: 12 | - name: Sample task that does nothing 13 | action: cmd="ls" 14 | - name: Second task 15 | action: cmd="echo" 16 | ignore_errors: true 17 | -------------------------------------------------------------------------------- /henchman/test/plan/invalid/invalidIncludeFileAtVarsLevel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Sample plan" 3 | vars: 4 | hello: world 5 | foo: scar 6 | include: 7 | - test/vars/cars.yaml 8 | spam: eggs 9 | tasks: 10 | - name: Sample task that does nothing 11 | action: cmd="ls" 12 | - name: Second task 13 | action: cmd="echo" 14 | ignore_errors: true 15 | -------------------------------------------------------------------------------- /henchman/test/plan/invalid/invalidIncludeFormatAtVarsLevel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Sample plan" 3 | vars: 4 | hello: world 5 | foo: scar 6 | include: test/vars/vars.yaml 7 | spam: eggs 8 | tasks: 9 | - name: Sample task that does nothing 10 | action: cmd="ls" 11 | - name: Second task 12 | action: cmd="echo" 13 | ignore_errors: true 14 | -------------------------------------------------------------------------------- /henchman/test/plan/invalid/invalidPongo2.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Plan with Pongo 2" 3 | vars: 4 | service: iptables 5 | key: abcd1234 6 | test: tmp_val 7 | flag: false 8 | tasks: 9 | - name: "{{ {{ vars.service }} }} with {{ vars.key }}" 10 | shell: cmd=echo key="{{ vars.service }}" 11 | local: true 12 | - name: "{{ name is valid" 13 | shell: cmd="{{ cmd }}" key=tmpKey 14 | when: vars.service == "iptables" 15 | - name: "name is valid }}" 16 | shell: cmd="{{ cmd }}" key=tmpKey 17 | when: vars.service == "iptables" 18 | -------------------------------------------------------------------------------- /henchman/test/plan/invalid/invalidPongo2AtWhen.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "invalid pongo2 at when" 3 | hosts: 4 | - individual 5 | vars: 6 | service: "iptables" 7 | tasks: 8 | - name: "Task 1" 9 | shell: cmd=echo 10 | when: vars.service == "iptables" 11 | - name: "Task 2" 12 | shell: cmd=touch 13 | when: '"{{ vars.service }}" == "iptables"' 14 | 15 | -------------------------------------------------------------------------------- /henchman/test/plan/invalid/invalidRegisterKeyword.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "invalid register keyword plan" 3 | tasks: 4 | - name: "First Task" 5 | shell: cmd=echo 6 | register: vars 7 | -------------------------------------------------------------------------------- /henchman/test/plan/invalid/invalidRegisterVariable.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "invalid register keyword plan" 3 | tasks: 4 | - name: "First Task" 5 | shell: cmd=echo 6 | register: vars == bad choice 7 | -------------------------------------------------------------------------------- /henchman/test/plan/invalid/invalidTask.yaml: -------------------------------------------------------------------------------- 1 | name: "Invalid Task" 2 | vars: 3 | service: iptables 4 | tasks: 5 | - name: "valid shell" 6 | shell: cmd="echo hello" 7 | - name: "invalid shell" 8 | shell: cmd "echo hello" 9 | -------------------------------------------------------------------------------- /henchman/test/plan/invalid/invalidTaskNoName.yaml: -------------------------------------------------------------------------------- 1 | name: "invalid task no name" 2 | hosts: 3 | - individual 4 | vars: 5 | service: iptables 6 | tasks: 7 | - name: "task one" 8 | shell: cmd="echo hello" 9 | - shell: cmd="echo goodbye" 10 | -------------------------------------------------------------------------------- /henchman/test/plan/inventoryAtHostLevel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Sample plan" 3 | hosts: 4 | - nginx 5 | tasks: 6 | - name: Sample task that does nothing 7 | action: cmd="ls" 8 | - name: Second task 9 | action: cmd="echo" 10 | ignore_errors: true 11 | - name: "included tasks" 12 | include: test/tasks/noInclude.yaml 13 | -------------------------------------------------------------------------------- /henchman/test/plan/localModules.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Testing local == true" 3 | hosts: 4 | - individual 5 | tasks: 6 | - name: "Task Standalone" 7 | shell: cmd="echo hello {{ vars.current_host }}" loglevel="debug" 8 | local: true 9 | - name: "Task Dependencies" 10 | curl: url="http://ci.apigeng.com/v1/data/1k.json" http="GET" 11 | local: true 12 | -------------------------------------------------------------------------------- /henchman/test/plan/localTest.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Testing local == true" 3 | hosts: 4 | - individual 5 | tasks: 6 | - name: "Task 1" 7 | shell: cmd="echo hello {{ vars.current_host }}" loglevel="debug" 8 | local: true 9 | register: second 10 | - name: "Task 2" 11 | shell: cmd="echo goodbye world" loglevel="debug" 12 | local: true 13 | register: second 14 | -------------------------------------------------------------------------------- /henchman/test/plan/localWithCopy.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Testing local == true" 3 | hosts: 4 | - individual 5 | tasks: 6 | - name: "Task Copy File" 7 | copy: src="henchman/test/plan/localTest.yaml" dest="fldr/localTest.yaml" 8 | debug: true 9 | sudo: true 10 | - name: "Task Copy Folder" 11 | copy: src="henchman/test/plan/" dest="fldr/plans" 12 | debug: true 13 | sudo: true 14 | - name: "Task Copy Folder 2" 15 | copy: src="henchman/test/plan/invalid" dest="fldr/plans/invalids/ralids" 16 | debug: true 17 | sudo: true 18 | - name: "Who am I" 19 | shell: cmd="whoami" 20 | debug: true 21 | #- name: "Local task" 22 | # copy: src="henchman/test/plan" dest="/Users/jordanlin/tmpFldr/plans" 23 | # local: true 24 | 25 | -------------------------------------------------------------------------------- /henchman/test/plan/localhostInPlan.yaml: -------------------------------------------------------------------------------- 1 | name: "Plan with debug" 2 | hosts: 3 | - localhost 4 | vars: 5 | service: iptables 6 | tasks: 7 | - name: "Task One" 8 | shell: cmd="echo hello" 9 | debug: true 10 | - name: "Task Two" 11 | shell: cmd="echo goodbye" 12 | - name: "Task Three" 13 | shell: cmd="echo world" 14 | 15 | -------------------------------------------------------------------------------- /henchman/test/plan/nestedIncludeAtTaskLevel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Sample plan" 3 | tasks: 4 | - name: task1 5 | action: cmd=ls user=foo 6 | - name: "included tasks" 7 | include: test/tasks/withInclude.yaml 8 | -------------------------------------------------------------------------------- /henchman/test/plan/planWithComments.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Sample plan" 3 | vars: 4 | foo: "hello" 5 | # bar: "world" 6 | 7 | hosts: 8 | - nginx 9 | tasks: 10 | # - name: First task 11 | # action: cmd="ls" 12 | - name: Second task 13 | action: cmd="echo" 14 | ignore_errors: true 15 | - name: Third task 16 | action: cmd="foo" 17 | -------------------------------------------------------------------------------- /henchman/test/plan/planWithPongo2.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Plan with Pongo 2" 3 | vars: 4 | service: iptables 5 | key: abcd1234 6 | test: tmp_val 7 | flag: false 8 | tasks: 9 | - name: "{{ vars.service }} with {{ vars.key }}" 10 | shell: cmd=echo key="{{ vars.service }}" 11 | local: true 12 | - name: "{{ name }} is valid" 13 | shell: cmd="{{ cmd }}" key=tmpKey 14 | when: vars.service == "iptables" 15 | - name: "included tasks" 16 | include: test/tasks/withPongo2.yaml 17 | when: vars.key == "abcd1234" 18 | - name: "When processing test" 19 | shell: cmd=ls 20 | when: vars.test 21 | - name: "Vars flag test" 22 | shell: cmd=ls 23 | when: vars.flag 24 | -------------------------------------------------------------------------------- /henchman/test/plan/registersAndWhen.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Plan with Registers and When" 3 | hosts: 4 | - individual 5 | tasks: 6 | - name: "Task 1" 7 | shell: cmd="echo hello {{ vars.current_host }}" loglevel="debug" 8 | register: first 9 | - name: "Task 2" 10 | shell: cmd="echo goodbye world" loglevel="debug" 11 | register: second 12 | - name: "Task 3" 13 | shell: cmd="echo success" loglevel="debug" 14 | when: second.State == "changed" 15 | # - include: "henchman/test/tasks/modulesTest.yaml" 16 | # when: second.State == "changed" 17 | - name: "Task 4" 18 | shell: cmd="ls" loglevel="debug" 19 | -------------------------------------------------------------------------------- /henchman/test/plan/retryAtTaskLevel.yaml: -------------------------------------------------------------------------------- 1 | name: "Retry at task level" 2 | hosts: 3 | - individual 4 | vars: 5 | service: iptables 6 | tasks: 7 | - name: "Task with retry" 8 | shell: cmd="echo hello" 9 | retry: 2 10 | - name: "Task without retry" 11 | shell: cmd="echo goodbye" 12 | -------------------------------------------------------------------------------- /henchman/test/plan/retryTest.yaml: -------------------------------------------------------------------------------- 1 | name: "Test" 2 | hosts: 3 | - individual 4 | vars: 5 | cond: true 6 | tasks: 7 | - name: "asdf" 8 | shell: cmd="echo eskjef(*&239u4()*!" 9 | retry: 3 10 | when: 'vars.cond == true' 11 | -------------------------------------------------------------------------------- /henchman/test/plan/sandboxPongo2.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Test random pongo2 templating stuff" 3 | hosts: 4 | - individual 5 | vars: 6 | service: iptables 7 | key: abcd123 8 | tasks: 9 | - name: "{{ vars.all_hosts }}" 10 | shell: cmd="echo {{ vars.test[1] }}" loglevel="debug" 11 | local: true 12 | - name: "Task 2" 13 | shell: cmd="echo {{ vars.service }}" loglevel="debug" 14 | local: true 15 | -------------------------------------------------------------------------------- /henchman/test/plan/shellTest.yaml: -------------------------------------------------------------------------------- 1 | name: "Shell Test" 2 | hosts: 3 | - individual 4 | debug: true 5 | tasks: 6 | - name: "Task 1" 7 | shell: cmd="echo hello | grep hello" 8 | - name: "Task 2" 9 | shell: cmd="echo hello >> tmp.txt" 10 | - name: "Task 3" 11 | shell: cmd="cat tmp.txt" 12 | - name: "Task 4" 13 | shell: cmd="rm tmp.txt" 14 | -------------------------------------------------------------------------------- /henchman/test/plan/sudoAtPlanLevel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Sample plan" 3 | sudo: true 4 | hosts: 5 | - "127.0.0.1:22" 6 | - 192.168.1.2 7 | tasks: 8 | - name: Sample task that does nothing 9 | action: cmd="ls" 10 | sudo: true 11 | - name: Another task 12 | action: cmd="test" 13 | -------------------------------------------------------------------------------- /henchman/test/plan/sudoAtTaskLevel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Sample plan" 3 | tasks: 4 | - name: First task 5 | action: cmd="ls" 6 | sudo: true 7 | - name: Second task 8 | action: cmd="echo" 9 | -------------------------------------------------------------------------------- /henchman/test/plan/sudoOverrideAtTaskLevel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Sample plan" 3 | sudo: true 4 | tasks: 5 | - name: First task 6 | action: cmd="ls" 7 | - name: Second task 8 | action: cmd="echo" 9 | sudo: false 10 | -------------------------------------------------------------------------------- /henchman/test/plan/tarModules.yaml: -------------------------------------------------------------------------------- 1 | name: "Just to Tar modules" 2 | vars: 3 | service: iptables 4 | hosts: 5 | - test 6 | tasks: 7 | - name: "Task One" 8 | shell: cmd="echo hello" 9 | - name: "Task Two" 10 | curl: url="http://ci.apigeng.com/v1/data/1k.json" http="GET" 11 | - name: "Task Three" 12 | yum: package="apt" 13 | - name: "Task Four" 14 | rpm: url="www.tmp.com" 15 | -------------------------------------------------------------------------------- /henchman/test/plan/templateTest.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Testing local == true" 3 | debug: true 4 | hosts: 5 | - individual 6 | vars: 7 | service: iptables 8 | tasks: 9 | # template and copy use the same src code for modules so testing one is sufficient 10 | # File/folder to folder/file should have the same result of status ok for override false 11 | - name: "Remove old files" 12 | shell: cmd="rm -rf templateTest" 13 | sudo: true 14 | - name: "Remove old files" 15 | shell: cmd="rm -rf copyTest" 16 | sudo: true 17 | - name: "Remove old files" 18 | shell: cmd="rm -rf fldr" 19 | sudo: true 20 | 21 | # File/Folder doesn't exists case 22 | - name: "Nested folder doesn't exist" 23 | template: src="henchman/test/templates" dest="fldr/fldr1/fldr2/templateTest" owner="root" group="vagrant" mode=0777 24 | sudo: true 25 | - name: "Template Folder" 26 | template: src="henchman/test/templates" dest="templateTest" 27 | - name: "Copy Folder" 28 | copy: src="henchman/test/templates" dest="copyTest" 29 | 30 | # folder tests 31 | # files temp3 and temp4 should be changed in templates3 32 | - name: "Template Folder to folder override true" 33 | template: src="henchman/test/templates/templates2" dest="templateTest/templates3/" 34 | # files temp3 and temp4 should not be changed in templates2 35 | - name: "Template Folder to folder override false" 36 | template: src="henchman/test/templates/templates3" dest="templateTest/templates2/" override="false" 37 | - name: "Template folder to file override true" 38 | template: src="henchman/test/templates" dest="templateTest/temp1" 39 | - name: "Template folder to file override false" 40 | template: src="henchman/test/templates" dest="templateTest/temp2" override="false" 41 | 42 | # file tests 43 | - name: "Copy File to File override true" 44 | copy: src="henchman/test/templates/templates3/temp3" dest="copyTest/templates2/temp3" 45 | - name: "Copy File to File override false" 46 | copy: src="henchman/test/templates/temp1" dest="copyTest/temp2" override="false" 47 | - name: "Copy File to Folder override true" 48 | copy: src="henchman/test/templates/temp1" dest="copyTest/templates3" 49 | - name: "Copy File to Folder override false" 50 | copy: src="henchman/test/templates/temp2" dest="copyTest/templates2" override="false" 51 | -------------------------------------------------------------------------------- /henchman/test/plan/withItemsAtTaskLevel.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Task With Items" 3 | vars: 4 | service: "iptables" 5 | key: "abcd1234" 6 | hosts: 7 | - localhost 8 | tasks: 9 | - name: "Task 1" 10 | shell: cmd=echo params=hi 11 | debug: true 12 | with_items: 13 | - test1 14 | - test2 15 | - test3 16 | -------------------------------------------------------------------------------- /henchman/test/plan/withItemsAtTaskLevelWithHenchmanitem.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Task With Items" 3 | vars: 4 | service: "iptables" 5 | key: "abcd1234" 6 | hosts: 7 | - localhost 8 | tasks: 9 | - name: "Task 1 {{ item }}" 10 | shell: cmd=echo params=henchman_item 11 | debug: true 12 | with_items: 13 | - test1 14 | - test2 15 | - test3 16 | -------------------------------------------------------------------------------- /henchman/test/plan/withItemsTest.yaml: -------------------------------------------------------------------------------- 1 | name: "With Items test" 2 | hosts: 3 | - individual 4 | debug: true 5 | vars: 6 | somelist: 7 | - listItemOne 8 | - listItemTwo 9 | - listItemThree 10 | obj_array: 11 | - { name: 'objOne', value: 'oOne' } 12 | - { name: 'objTwo', value: 'oTwo' } 13 | - { name: 'objThree', value: 'oThree' } 14 | bad_array: "hello" 15 | val1: "val1" 16 | val2: "val2" 17 | tasks: 18 | - name: "Task {{ item }}" 19 | shell: cmd="echo {{ item }}" 20 | with_items: 21 | - itemOne 22 | - itemTwo 23 | - itemThree 24 | 25 | - name: "Middle Task" 26 | shell: cmd="echo success" 27 | 28 | - name: "Task {{ item.name }}" 29 | shell: cmd="echo {{ item.value }}" 30 | with_items: 31 | - { name: 'itemOne', value: 'one' } 32 | - { name: 'itemTwo', value: 'two' } 33 | - { name: 'itemThree', value: 'three' } 34 | 35 | - name: "Task {{ item }}" 36 | shell: cmd="echo {{ item }}" 37 | with_items: "{{vars.somelist}}" 38 | 39 | - name: "Task {{ item.name }}" 40 | shell: cmd="echo {{ item.value }}" 41 | with_items: "{{vars.obj_array}}" 42 | 43 | - name: "Val render task {{ item }}" 44 | shell: cmd="echo {{ item }}" 45 | with_items: 46 | - "{{ vars.val1 }}" 47 | - "{{ vars.val2 }}" 48 | - "val3" 49 | 50 | # Verified this test case works for the default case in task.ProcessWithItems 51 | # - name: "Bad Task {{ item }}" 52 | # shell: cmd="echo {{ item }}" 53 | # with_items: 54 | # - "hello" 55 | # - 1.0 56 | # 57 | # Verified this test case works 58 | # - name: "Bad Task {{ item }}" 59 | # shell: cmd="echo {{ item }}" 60 | # with_items: "{{vars.bad_array}}" 61 | -------------------------------------------------------------------------------- /henchman/test/tasks/modulesTest.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Test copy" 3 | tasks: 4 | - name: "Copy module" 5 | copy: src="henchman/test/tasks/modulesTest.yaml" dest="~/temp.yaml" 6 | -------------------------------------------------------------------------------- /henchman/test/tasks/noInclude.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Tasks No Includes" 3 | hosts: 4 | - db 5 | tasks: 6 | - name: "included_task1" 7 | action: bar=baz 8 | when: jolly == santa 9 | - name: "included_task2" 10 | action: foo=bar 11 | -------------------------------------------------------------------------------- /henchman/test/tasks/withInclude.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Tasks With Includes" 3 | tasks: 4 | - name: "included_task1" 5 | shell: cmd=foo 6 | - name: "included tasks" 7 | include: test/tasks/noInclude.yaml 8 | -------------------------------------------------------------------------------- /henchman/test/tasks/withIncludeAndVars.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "To be include" 3 | tasks: 4 | - name: "included_task1" 5 | action: foo="bar" 6 | - name: "included tasks" 7 | include: test/tasks/noInclude.yaml 8 | vars: 9 | foo: thumb 10 | - name: "included_task2" 11 | action: spiz="spaz" 12 | -------------------------------------------------------------------------------- /henchman/test/tasks/withIncludeAndWhen.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Tasks with Include and When" 3 | tasks: 4 | - name: "include when 1" 5 | shell: cmd=echo 6 | when: hello == world 7 | - name: "included tasks" 8 | include: test/tasks/noInclude.yaml 9 | when: goodbye == moon 10 | -------------------------------------------------------------------------------- /henchman/test/tasks/withPongo2.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Included Task with Pongo2" 3 | tasks: 4 | - name: "iTask 1" 5 | shell: cmd=echo 6 | when: vars.service == "iptables" 7 | - name: "iTask 2" 8 | shell: cmd=touch 9 | when: name == "iTask 2" 10 | 11 | -------------------------------------------------------------------------------- /henchman/test/tasks/withSudo.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "To be include" 3 | tasks: 4 | - name: "included_task1" 5 | action: bar=baz 6 | sudo: true 7 | - name: "included_task2" 8 | action: foo=bar 9 | -------------------------------------------------------------------------------- /henchman/test/templates/bad.sh: -------------------------------------------------------------------------------- 1 | {{ won't work }} 2 | -------------------------------------------------------------------------------- /henchman/test/templates/bad.zip: -------------------------------------------------------------------------------- 1 | {{ helllo }} 2 | -------------------------------------------------------------------------------- /henchman/test/templates/temp1: -------------------------------------------------------------------------------- 1 | temp 1 2 | {{ vars.current_hostname }} 3 | {{ vars.service }} 4 | -------------------------------------------------------------------------------- /henchman/test/templates/temp2: -------------------------------------------------------------------------------- 1 | temp2 2 | hello 3 | {{ vars.service }} 4 | 5 | -------------------------------------------------------------------------------- /henchman/test/templates/templates2/temp3: -------------------------------------------------------------------------------- 1 | temp3 2 | {{ vars.current_hostname }} 3 | -------------------------------------------------------------------------------- /henchman/test/templates/templates2/temp4: -------------------------------------------------------------------------------- 1 | temp4 2 | hello 3 | {{ vars.service }} 4 | 5 | -------------------------------------------------------------------------------- /henchman/test/templates/templates3/temp3: -------------------------------------------------------------------------------- 1 | temp5 2 | {{ vars.current_hostname }} 3 | -------------------------------------------------------------------------------- /henchman/test/templates/templates3/temp4: -------------------------------------------------------------------------------- 1 | temp6 2 | hello 3 | {{ vars.service }} 4 | 5 | -------------------------------------------------------------------------------- /henchman/test/templates/templates3/temp5: -------------------------------------------------------------------------------- 1 | temp5 2 | {{ vars.current_hostname }} 3 | -------------------------------------------------------------------------------- /henchman/test/templates/templates3/temp6: -------------------------------------------------------------------------------- 1 | temp6 2 | hello 3 | {{ vars.service }} 4 | 5 | -------------------------------------------------------------------------------- /henchman/test/vars/vars.yaml: -------------------------------------------------------------------------------- 1 | --- 2 | name: "Included Vars" 3 | vars: 4 | goodbye: moon 5 | foo: bar 6 | -------------------------------------------------------------------------------- /henchman/test/vars/vars2.yaml: -------------------------------------------------------------------------------- 1 | name: "Included Vars 2" 2 | vars: 3 | goodbye: guacamole 4 | fun: times 5 | -------------------------------------------------------------------------------- /henchman/transport.go: -------------------------------------------------------------------------------- 1 | package henchman 2 | 3 | import ( 4 | "bytes" 5 | ) 6 | 7 | type TransportConfig map[string]string 8 | 9 | type TransportInterface interface { 10 | Initialize(config *TransportConfig) error 11 | Exec(cmd string, stdin []byte, sudo bool) (*bytes.Buffer, error) 12 | Put(source string, destination string, dstType string) error 13 | } 14 | -------------------------------------------------------------------------------- /henchman/transport_test.go: -------------------------------------------------------------------------------- 1 | package henchman 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "log" 7 | ) 8 | 9 | type TestTransport struct{} 10 | 11 | func (tt *TestTransport) Initialize(config *TransportConfig) error { 12 | log.Printf("Initialized test transport\n") 13 | return nil 14 | } 15 | 16 | func (tt *TestTransport) Exec(cmd string, stdin []byte, sudo bool) (*bytes.Buffer, error) { 17 | // Create a dummy map mirroring the task result. 18 | // We're not using TaskResult directly since changes in that contract 19 | // will be caught for free 20 | taskResult := map[string]string{ 21 | "status": "true", 22 | "output": "foo", 23 | "msg": "the dude abides", 24 | } 25 | jsonified, err := json.Marshal(taskResult) 26 | if err != nil { 27 | log.Fatalf(err.Error()) 28 | } 29 | return bytes.NewBuffer([]byte(jsonified)), nil 30 | } 31 | 32 | func (tt *TestTransport) Put(source, destination string, dstType string) error { 33 | log.Printf("Transfered from %s to %s for dstType %s\n", source, destination, dstType) 34 | return nil 35 | } 36 | -------------------------------------------------------------------------------- /modules/append/append: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # append modules 3 | # Appends a line to a given file 4 | # Params, 5 | # file: The file 6 | # line: The line which has to be appended to the file 7 | # unique: true/false. If set to true, doesn't append the line if it's 8 | # already present. Returns a skipped state if that's the case 9 | # Is great for property files. 10 | # default: true 11 | import sys 12 | import json 13 | import os 14 | import subprocess 15 | 16 | params = json.loads(sys.stdin.read()) 17 | 18 | def append_line(params): 19 | result = {} 20 | try: 21 | f = params.get("file","") 22 | l = params.get("line", "").strip() 23 | unique = params.get("unique", "false") 24 | if not f: 25 | raise "Missing file" 26 | if not l: 27 | raise "Missing line" 28 | if unique in ["true", "t"]: 29 | with open(f) as source: 30 | for line in source.xreadlines(): 31 | if line.strip() == l: 32 | result["status"] = "skipped" 33 | result["msg"] = "Line already present" 34 | return result 35 | with open(f, "a") as source: 36 | source.write(l + "\n") 37 | result["status"] = "ok" 38 | result["msg"] = "Appended line" 39 | except Exception as e: 40 | result["status"] = "error" 41 | result["msg"] = str(e) 42 | return result 43 | 44 | print json.dumps(append_line(params)) 45 | 46 | -------------------------------------------------------------------------------- /modules/curl/curl/exec: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | 3 | # do standard http requests 4 | # be able to show status codes for now 5 | # Currently only supported for RESTful HTTP requests 6 | # Allow for redirects 7 | # 8 | # params: 9 | # user (optional) 10 | # pswd (optional) 11 | # http (required) 12 | # url (required) 13 | # headers "key:value,key:value" 14 | # data "key:value,key:value" 15 | 16 | import sys 17 | import json 18 | import os 19 | import ast 20 | 21 | 22 | sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/requests") 23 | sys.path.append(os.path.dirname(os.path.realpath(__file__)) + "/xmltodict") 24 | import requests 25 | import xmltodict 26 | 27 | params = json.loads(sys.stdin.read()) 28 | #params = {} 29 | result = {} 30 | 31 | def convert_key_val(vals): 32 | tmp = {} 33 | if vals != "": 34 | for pair in vals.split(","): 35 | key_val = pair.split(":") 36 | if len(key_val) != 2: 37 | raise Exception("Invalid key value format") 38 | tmp[key_val[0]] = key_val[1] 39 | 40 | return tmp 41 | 42 | try: 43 | url = params.get("url", "") 44 | #url = "http://ci.apigeng.com/v1/data/1k.json" 45 | http = params.get("http", "GET").upper() 46 | headers = convert_key_val(params.get("headers", "")) 47 | data = convert_key_val(params.get("data", "")) 48 | 49 | if not url: 50 | raise Exception("Url parameter is required") 51 | 52 | if http == "POST": 53 | r = requests.post(url, data=data, headers=headers) 54 | elif http == "PUT": 55 | r = requests.put(url, data=data, headers=headers) 56 | elif http == "DELETE": 57 | r = requests.delete(url, data=data, headers=headers) 58 | elif http == "OPTIONS": 59 | r = requests.options(url, data=data, headers=headers) 60 | else: 61 | r = requests.get(url, data=data, headers=headers) 62 | 63 | result["status"] = "ok" 64 | result["msg"] = "Http request successfully processed." 65 | 66 | c_type = dict(r.headers)['Content-Type'] 67 | if "xml" in c_type: 68 | payload = xmltodict.parse(r.text) 69 | elif "json" in c_type: 70 | payload = ast.literal_eval(r.text) 71 | else: 72 | result["msg"] += "Content-Type %s is not supported. Payload stored as a string." % c_type 73 | payload = str(r.text) 74 | 75 | result["output"] = {'status': r.status_code, 'headers': dict(r.headers), 'body': payload} 76 | except Exception as e: 77 | result["status"] = "error" 78 | result["msg"] = "Http request unsuccessful." 79 | result["output"] = str(e) 80 | print json.dumps(result) 81 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/.gitignore: -------------------------------------------------------------------------------- 1 | .coverage 2 | MANIFEST 3 | coverage.xml 4 | nosetests.xml 5 | junit-report.xml 6 | pylint.txt 7 | toy.py 8 | tox.ini 9 | violations.pyflakes.txt 10 | cover/ 11 | build/ 12 | docs/_build 13 | requests.egg-info/ 14 | *.pyc 15 | *.swp 16 | *.egg 17 | env/ 18 | 19 | .workon 20 | 21 | t.py 22 | 23 | t2.py 24 | dist 25 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2015 Kenneth Reitz 2 | 3 | Licensed under the Apache License, Version 2.0 (the "License"); 4 | you may not use this file except in compliance with the License. 5 | You may obtain a copy of the License at 6 | 7 | http://www.apache.org/licenses/LICENSE-2.0 8 | 9 | Unless required by applicable law or agreed to in writing, software 10 | distributed under the License is distributed on an "AS IS" BASIS, 11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | See the License for the specific language governing permissions and 13 | limitations under the License. 14 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/MANIFEST.in: -------------------------------------------------------------------------------- 1 | include README.rst LICENSE NOTICE HISTORY.rst test_requests.py requirements.txt requests/cacert.pem 2 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/NOTICE: -------------------------------------------------------------------------------- 1 | Requests includes some vendorized python libraries to ease installation. 2 | 3 | Urllib3 License 4 | =============== 5 | 6 | This is the MIT license: http://www.opensource.org/licenses/mit-license.php 7 | 8 | Copyright 2008-2011 Andrey Petrov and contributors (see CONTRIBUTORS.txt), 9 | Modifications copyright 2012 Kenneth Reitz. 10 | 11 | Permission is hereby granted, free of charge, to any person obtaining 12 | a copy of this software and associated documentation files (the 13 | "Software"), to deal in the Software without restriction, including 14 | without limitation the rights to use, copy, modify, merge, publish, 15 | distribute, sublicense, and/or sell copies of the Software, and to 16 | permit persons to whom the Software is furnished to do so, subject to 17 | the following conditions: 18 | 19 | The above copyright notice and this permission notice shall be 20 | included in all copies or substantial portions of the Software. 21 | 22 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 23 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 24 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 25 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 26 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 27 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 28 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 29 | 30 | Chardet License 31 | =============== 32 | 33 | This library is free software; you can redistribute it and/or 34 | modify it under the terms of the GNU Lesser General Public 35 | License as published by the Free Software Foundation; either 36 | version 2.1 of the License, or (at your option) any later version. 37 | 38 | This library is distributed in the hope that it will be useful, 39 | but WITHOUT ANY WARRANTY; without even the implied warranty of 40 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 41 | Lesser General Public License for more details. 42 | 43 | You should have received a copy of the GNU Lesser General Public 44 | License along with this library; if not, write to the Free Software 45 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 46 | 02110-1301 USA 47 | 48 | 49 | CA Bundle License 50 | ================= 51 | 52 | This Source Code Form is subject to the terms of the Mozilla Public 53 | License, v. 2.0. If a copy of the MPL was not distributed with this 54 | file, You can obtain one at http://mozilla.org/MPL/2.0/. 55 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/__init__.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | # __ 4 | # /__) _ _ _ _ _/ _ 5 | # / ( (- (/ (/ (- _) / _) 6 | # / 7 | 8 | """ 9 | Requests HTTP library 10 | ~~~~~~~~~~~~~~~~~~~~~ 11 | 12 | Requests is an HTTP library, written in Python, for human beings. Basic GET 13 | usage: 14 | 15 | >>> import requests 16 | >>> r = requests.get('https://www.python.org') 17 | >>> r.status_code 18 | 200 19 | >>> 'Python is a programming language' in r.content 20 | True 21 | 22 | ... or POST: 23 | 24 | >>> payload = dict(key1='value1', key2='value2') 25 | >>> r = requests.post('http://httpbin.org/post', data=payload) 26 | >>> print(r.text) 27 | { 28 | ... 29 | "form": { 30 | "key2": "value2", 31 | "key1": "value1" 32 | }, 33 | ... 34 | } 35 | 36 | The other HTTP methods are supported - see `requests.api`. Full documentation 37 | is at . 38 | 39 | :copyright: (c) 2015 by Kenneth Reitz. 40 | :license: Apache 2.0, see LICENSE for more details. 41 | 42 | """ 43 | 44 | __title__ = 'requests' 45 | __version__ = '2.8.1' 46 | __build__ = 0x020801 47 | __author__ = 'Kenneth Reitz' 48 | __license__ = 'Apache 2.0' 49 | __copyright__ = 'Copyright 2015 Kenneth Reitz' 50 | 51 | # Attempt to enable urllib3's SNI support, if possible 52 | try: 53 | from .packages.urllib3.contrib import pyopenssl 54 | pyopenssl.inject_into_urllib3() 55 | except ImportError: 56 | pass 57 | 58 | from . import utils 59 | from .models import Request, Response, PreparedRequest 60 | from .api import request, get, head, post, patch, put, delete, options 61 | from .sessions import session, Session 62 | from .status_codes import codes 63 | from .exceptions import ( 64 | RequestException, Timeout, URLRequired, 65 | TooManyRedirects, HTTPError, ConnectionError 66 | ) 67 | 68 | # Set default logging handler to avoid "No handler found" warnings. 69 | import logging 70 | try: # Python 2.7+ 71 | from logging import NullHandler 72 | except ImportError: 73 | class NullHandler(logging.Handler): 74 | def emit(self, record): 75 | pass 76 | 77 | logging.getLogger(__name__).addHandler(NullHandler()) 78 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/certs.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | # -*- coding: utf-8 -*- 3 | 4 | """ 5 | certs.py 6 | ~~~~~~~~ 7 | 8 | This module returns the preferred default CA certificate bundle. 9 | 10 | If you are packaging Requests, e.g., for a Linux distribution or a managed 11 | environment, you can change the definition of where() to return a separately 12 | packaged CA bundle. 13 | """ 14 | import os.path 15 | 16 | try: 17 | from certifi import where 18 | except ImportError: 19 | def where(): 20 | """Return the preferred certificate bundle.""" 21 | # vendored bundle inside Requests 22 | return os.path.join(os.path.dirname(__file__), 'cacert.pem') 23 | 24 | if __name__ == '__main__': 25 | print(where()) 26 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/compat.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | pythoncompat 5 | """ 6 | 7 | from .packages import chardet 8 | 9 | import sys 10 | 11 | # ------- 12 | # Pythons 13 | # ------- 14 | 15 | # Syntax sugar. 16 | _ver = sys.version_info 17 | 18 | #: Python 2.x? 19 | is_py2 = (_ver[0] == 2) 20 | 21 | #: Python 3.x? 22 | is_py3 = (_ver[0] == 3) 23 | 24 | try: 25 | import simplejson as json 26 | except (ImportError, SyntaxError): 27 | # simplejson does not support Python 3.2, it throws a SyntaxError 28 | # because of u'...' Unicode literals. 29 | import json 30 | 31 | # --------- 32 | # Specifics 33 | # --------- 34 | 35 | if is_py2: 36 | from urllib import quote, unquote, quote_plus, unquote_plus, urlencode, getproxies, proxy_bypass 37 | from urlparse import urlparse, urlunparse, urljoin, urlsplit, urldefrag 38 | from urllib2 import parse_http_list 39 | import cookielib 40 | from Cookie import Morsel 41 | from StringIO import StringIO 42 | from .packages.urllib3.packages.ordered_dict import OrderedDict 43 | 44 | builtin_str = str 45 | bytes = str 46 | str = unicode 47 | basestring = basestring 48 | numeric_types = (int, long, float) 49 | 50 | elif is_py3: 51 | from urllib.parse import urlparse, urlunparse, urljoin, urlsplit, urlencode, quote, unquote, quote_plus, unquote_plus, urldefrag 52 | from urllib.request import parse_http_list, getproxies, proxy_bypass 53 | from http import cookiejar as cookielib 54 | from http.cookies import Morsel 55 | from io import StringIO 56 | from collections import OrderedDict 57 | 58 | builtin_str = str 59 | str = str 60 | bytes = bytes 61 | basestring = (str, bytes) 62 | numeric_types = (int, float) 63 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/hooks.py: -------------------------------------------------------------------------------- 1 | # -*- coding: utf-8 -*- 2 | 3 | """ 4 | requests.hooks 5 | ~~~~~~~~~~~~~~ 6 | 7 | This module provides the capabilities for the Requests hooks system. 8 | 9 | Available hooks: 10 | 11 | ``response``: 12 | The response generated from a Request. 13 | 14 | """ 15 | HOOKS = ['response'] 16 | 17 | def default_hooks(): 18 | return dict((event, []) for event in HOOKS) 19 | 20 | # TODO: response is the only one 21 | 22 | 23 | def dispatch_hook(key, hooks, hook_data, **kwargs): 24 | """Dispatches a hook dictionary on a given piece of data.""" 25 | hooks = hooks or dict() 26 | hooks = hooks.get(key) 27 | if hooks: 28 | if hasattr(hooks, '__call__'): 29 | hooks = [hooks] 30 | for hook in hooks: 31 | _hook_data = hook(hook_data, **kwargs) 32 | if _hook_data is not None: 33 | hook_data = _hook_data 34 | return hook_data 35 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/README.rst: -------------------------------------------------------------------------------- 1 | If you are planning to submit a pull request to requests with any changes in 2 | this library do not go any further. These are independent libraries which we 3 | vendor into requests. Any changes necessary to these libraries must be made in 4 | them and submitted as separate pull requests to those libraries. 5 | 6 | urllib3 pull requests go here: https://github.com/shazow/urllib3 7 | 8 | chardet pull requests go here: https://github.com/chardet/chardet 9 | 10 | See https://github.com/kennethreitz/requests/pull/1812#issuecomment-30854316 11 | for the reasoning behind this. 12 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/__init__.py: -------------------------------------------------------------------------------- 1 | ''' 2 | Debian and other distributions "unbundle" requests' vendored dependencies, and 3 | rewrite all imports to use the global versions of ``urllib3`` and ``chardet``. 4 | The problem with this is that not only requests itself imports those 5 | dependencies, but third-party code outside of the distros' control too. 6 | 7 | In reaction to these problems, the distro maintainers replaced 8 | ``requests.packages`` with a magical "stub module" that imports the correct 9 | modules. The implementations were varying in quality and all had severe 10 | problems. For example, a symlink (or hardlink) that links the correct modules 11 | into place introduces problems regarding object identity, since you now have 12 | two modules in `sys.modules` with the same API, but different identities:: 13 | 14 | requests.packages.urllib3 is not urllib3 15 | 16 | With version ``2.5.2``, requests started to maintain its own stub, so that 17 | distro-specific breakage would be reduced to a minimum, even though the whole 18 | issue is not requests' fault in the first place. See 19 | https://github.com/kennethreitz/requests/pull/2375 for the corresponding pull 20 | request. 21 | ''' 22 | 23 | from __future__ import absolute_import 24 | import sys 25 | 26 | try: 27 | from . import urllib3 28 | except ImportError: 29 | import urllib3 30 | sys.modules['%s.urllib3' % __name__] = urllib3 31 | 32 | try: 33 | from . import chardet 34 | except ImportError: 35 | import chardet 36 | sys.modules['%s.chardet' % __name__] = chardet 37 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/chardet/__init__.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # This library is free software; you can redistribute it and/or 3 | # modify it under the terms of the GNU Lesser General Public 4 | # License as published by the Free Software Foundation; either 5 | # version 2.1 of the License, or (at your option) any later version. 6 | # 7 | # This library is distributed in the hope that it will be useful, 8 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 9 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 10 | # Lesser General Public License for more details. 11 | # 12 | # You should have received a copy of the GNU Lesser General Public 13 | # License along with this library; if not, write to the Free Software 14 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 15 | # 02110-1301 USA 16 | ######################### END LICENSE BLOCK ######################### 17 | 18 | __version__ = "2.3.0" 19 | from sys import version_info 20 | 21 | 22 | def detect(aBuf): 23 | if ((version_info < (3, 0) and isinstance(aBuf, unicode)) or 24 | (version_info >= (3, 0) and not isinstance(aBuf, bytes))): 25 | raise ValueError('Expected a bytes object, not a unicode object') 26 | 27 | from . import universaldetector 28 | u = universaldetector.UniversalDetector() 29 | u.reset() 30 | u.feed(aBuf) 31 | u.close() 32 | return u.result 33 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/chardet/big5prober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is Mozilla Communicator client code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 1998 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # 12 | # This library is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU Lesser General Public 14 | # License as published by the Free Software Foundation; either 15 | # version 2.1 of the License, or (at your option) any later version. 16 | # 17 | # This library is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | # Lesser General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU Lesser General Public 23 | # License along with this library; if not, write to the Free Software 24 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 25 | # 02110-1301 USA 26 | ######################### END LICENSE BLOCK ######################### 27 | 28 | from .mbcharsetprober import MultiByteCharSetProber 29 | from .codingstatemachine import CodingStateMachine 30 | from .chardistribution import Big5DistributionAnalysis 31 | from .mbcssm import Big5SMModel 32 | 33 | 34 | class Big5Prober(MultiByteCharSetProber): 35 | def __init__(self): 36 | MultiByteCharSetProber.__init__(self) 37 | self._mCodingSM = CodingStateMachine(Big5SMModel) 38 | self._mDistributionAnalyzer = Big5DistributionAnalysis() 39 | self.reset() 40 | 41 | def get_charset_name(self): 42 | return "Big5" 43 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/chardet/charsetprober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is Mozilla Universal charset detector code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 2001 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # Shy Shalom - original C code 12 | # 13 | # This library is free software; you can redistribute it and/or 14 | # modify it under the terms of the GNU Lesser General Public 15 | # License as published by the Free Software Foundation; either 16 | # version 2.1 of the License, or (at your option) any later version. 17 | # 18 | # This library is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | # Lesser General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Lesser General Public 24 | # License along with this library; if not, write to the Free Software 25 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 26 | # 02110-1301 USA 27 | ######################### END LICENSE BLOCK ######################### 28 | 29 | from . import constants 30 | import re 31 | 32 | 33 | class CharSetProber: 34 | def __init__(self): 35 | pass 36 | 37 | def reset(self): 38 | self._mState = constants.eDetecting 39 | 40 | def get_charset_name(self): 41 | return None 42 | 43 | def feed(self, aBuf): 44 | pass 45 | 46 | def get_state(self): 47 | return self._mState 48 | 49 | def get_confidence(self): 50 | return 0.0 51 | 52 | def filter_high_bit_only(self, aBuf): 53 | aBuf = re.sub(b'([\x00-\x7F])+', b' ', aBuf) 54 | return aBuf 55 | 56 | def filter_without_english_letters(self, aBuf): 57 | aBuf = re.sub(b'([A-Za-z])+', b' ', aBuf) 58 | return aBuf 59 | 60 | def filter_with_english_letters(self, aBuf): 61 | # TODO 62 | return aBuf 63 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/chardet/codingstatemachine.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is mozilla.org code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 1998 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # 12 | # This library is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU Lesser General Public 14 | # License as published by the Free Software Foundation; either 15 | # version 2.1 of the License, or (at your option) any later version. 16 | # 17 | # This library is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | # Lesser General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU Lesser General Public 23 | # License along with this library; if not, write to the Free Software 24 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 25 | # 02110-1301 USA 26 | ######################### END LICENSE BLOCK ######################### 27 | 28 | from .constants import eStart 29 | from .compat import wrap_ord 30 | 31 | 32 | class CodingStateMachine: 33 | def __init__(self, sm): 34 | self._mModel = sm 35 | self._mCurrentBytePos = 0 36 | self._mCurrentCharLen = 0 37 | self.reset() 38 | 39 | def reset(self): 40 | self._mCurrentState = eStart 41 | 42 | def next_state(self, c): 43 | # for each byte we get its class 44 | # if it is first byte, we also get byte length 45 | # PY3K: aBuf is a byte stream, so c is an int, not a byte 46 | byteCls = self._mModel['classTable'][wrap_ord(c)] 47 | if self._mCurrentState == eStart: 48 | self._mCurrentBytePos = 0 49 | self._mCurrentCharLen = self._mModel['charLenTable'][byteCls] 50 | # from byte's class and stateTable, we get its next state 51 | curr_state = (self._mCurrentState * self._mModel['classFactor'] 52 | + byteCls) 53 | self._mCurrentState = self._mModel['stateTable'][curr_state] 54 | self._mCurrentBytePos += 1 55 | return self._mCurrentState 56 | 57 | def get_current_charlen(self): 58 | return self._mCurrentCharLen 59 | 60 | def get_coding_state_machine(self): 61 | return self._mModel['name'] 62 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/chardet/compat.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # Contributor(s): 3 | # Ian Cordasco - port to Python 4 | # 5 | # This library is free software; you can redistribute it and/or 6 | # modify it under the terms of the GNU Lesser General Public 7 | # License as published by the Free Software Foundation; either 8 | # version 2.1 of the License, or (at your option) any later version. 9 | # 10 | # This library is distributed in the hope that it will be useful, 11 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 12 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 | # Lesser General Public License for more details. 14 | # 15 | # You should have received a copy of the GNU Lesser General Public 16 | # License along with this library; if not, write to the Free Software 17 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 18 | # 02110-1301 USA 19 | ######################### END LICENSE BLOCK ######################### 20 | 21 | import sys 22 | 23 | 24 | if sys.version_info < (3, 0): 25 | base_str = (str, unicode) 26 | else: 27 | base_str = (bytes, str) 28 | 29 | 30 | def wrap_ord(a): 31 | if sys.version_info < (3, 0) and isinstance(a, base_str): 32 | return ord(a) 33 | else: 34 | return a 35 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/chardet/constants.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is Mozilla Universal charset detector code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 2001 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # Shy Shalom - original C code 12 | # 13 | # This library is free software; you can redistribute it and/or 14 | # modify it under the terms of the GNU Lesser General Public 15 | # License as published by the Free Software Foundation; either 16 | # version 2.1 of the License, or (at your option) any later version. 17 | # 18 | # This library is distributed in the hope that it will be useful, 19 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 20 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 21 | # Lesser General Public License for more details. 22 | # 23 | # You should have received a copy of the GNU Lesser General Public 24 | # License along with this library; if not, write to the Free Software 25 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 26 | # 02110-1301 USA 27 | ######################### END LICENSE BLOCK ######################### 28 | 29 | _debug = 0 30 | 31 | eDetecting = 0 32 | eFoundIt = 1 33 | eNotMe = 2 34 | 35 | eStart = 0 36 | eError = 1 37 | eItsMe = 2 38 | 39 | SHORTCUT_THRESHOLD = 0.95 40 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/chardet/cp949prober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is mozilla.org code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 1998 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # 12 | # This library is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU Lesser General Public 14 | # License as published by the Free Software Foundation; either 15 | # version 2.1 of the License, or (at your option) any later version. 16 | # 17 | # This library is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | # Lesser General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU Lesser General Public 23 | # License along with this library; if not, write to the Free Software 24 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 25 | # 02110-1301 USA 26 | ######################### END LICENSE BLOCK ######################### 27 | 28 | from .mbcharsetprober import MultiByteCharSetProber 29 | from .codingstatemachine import CodingStateMachine 30 | from .chardistribution import EUCKRDistributionAnalysis 31 | from .mbcssm import CP949SMModel 32 | 33 | 34 | class CP949Prober(MultiByteCharSetProber): 35 | def __init__(self): 36 | MultiByteCharSetProber.__init__(self) 37 | self._mCodingSM = CodingStateMachine(CP949SMModel) 38 | # NOTE: CP949 is a superset of EUC-KR, so the distribution should be 39 | # not different. 40 | self._mDistributionAnalyzer = EUCKRDistributionAnalysis() 41 | self.reset() 42 | 43 | def get_charset_name(self): 44 | return "CP949" 45 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/chardet/euckrprober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is mozilla.org code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 1998 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # 12 | # This library is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU Lesser General Public 14 | # License as published by the Free Software Foundation; either 15 | # version 2.1 of the License, or (at your option) any later version. 16 | # 17 | # This library is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | # Lesser General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU Lesser General Public 23 | # License along with this library; if not, write to the Free Software 24 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 25 | # 02110-1301 USA 26 | ######################### END LICENSE BLOCK ######################### 27 | 28 | from .mbcharsetprober import MultiByteCharSetProber 29 | from .codingstatemachine import CodingStateMachine 30 | from .chardistribution import EUCKRDistributionAnalysis 31 | from .mbcssm import EUCKRSMModel 32 | 33 | 34 | class EUCKRProber(MultiByteCharSetProber): 35 | def __init__(self): 36 | MultiByteCharSetProber.__init__(self) 37 | self._mCodingSM = CodingStateMachine(EUCKRSMModel) 38 | self._mDistributionAnalyzer = EUCKRDistributionAnalysis() 39 | self.reset() 40 | 41 | def get_charset_name(self): 42 | return "EUC-KR" 43 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/chardet/euctwprober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is mozilla.org code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 1998 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # 12 | # This library is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU Lesser General Public 14 | # License as published by the Free Software Foundation; either 15 | # version 2.1 of the License, or (at your option) any later version. 16 | # 17 | # This library is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | # Lesser General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU Lesser General Public 23 | # License along with this library; if not, write to the Free Software 24 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 25 | # 02110-1301 USA 26 | ######################### END LICENSE BLOCK ######################### 27 | 28 | from .mbcharsetprober import MultiByteCharSetProber 29 | from .codingstatemachine import CodingStateMachine 30 | from .chardistribution import EUCTWDistributionAnalysis 31 | from .mbcssm import EUCTWSMModel 32 | 33 | class EUCTWProber(MultiByteCharSetProber): 34 | def __init__(self): 35 | MultiByteCharSetProber.__init__(self) 36 | self._mCodingSM = CodingStateMachine(EUCTWSMModel) 37 | self._mDistributionAnalyzer = EUCTWDistributionAnalysis() 38 | self.reset() 39 | 40 | def get_charset_name(self): 41 | return "EUC-TW" 42 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/chardet/gb2312prober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is mozilla.org code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 1998 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # 12 | # This library is free software; you can redistribute it and/or 13 | # modify it under the terms of the GNU Lesser General Public 14 | # License as published by the Free Software Foundation; either 15 | # version 2.1 of the License, or (at your option) any later version. 16 | # 17 | # This library is distributed in the hope that it will be useful, 18 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 19 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 20 | # Lesser General Public License for more details. 21 | # 22 | # You should have received a copy of the GNU Lesser General Public 23 | # License along with this library; if not, write to the Free Software 24 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 25 | # 02110-1301 USA 26 | ######################### END LICENSE BLOCK ######################### 27 | 28 | from .mbcharsetprober import MultiByteCharSetProber 29 | from .codingstatemachine import CodingStateMachine 30 | from .chardistribution import GB2312DistributionAnalysis 31 | from .mbcssm import GB2312SMModel 32 | 33 | class GB2312Prober(MultiByteCharSetProber): 34 | def __init__(self): 35 | MultiByteCharSetProber.__init__(self) 36 | self._mCodingSM = CodingStateMachine(GB2312SMModel) 37 | self._mDistributionAnalyzer = GB2312DistributionAnalysis() 38 | self.reset() 39 | 40 | def get_charset_name(self): 41 | return "GB2312" 42 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/chardet/mbcsgroupprober.py: -------------------------------------------------------------------------------- 1 | ######################## BEGIN LICENSE BLOCK ######################## 2 | # The Original Code is Mozilla Universal charset detector code. 3 | # 4 | # The Initial Developer of the Original Code is 5 | # Netscape Communications Corporation. 6 | # Portions created by the Initial Developer are Copyright (C) 2001 7 | # the Initial Developer. All Rights Reserved. 8 | # 9 | # Contributor(s): 10 | # Mark Pilgrim - port to Python 11 | # Shy Shalom - original C code 12 | # Proofpoint, Inc. 13 | # 14 | # This library is free software; you can redistribute it and/or 15 | # modify it under the terms of the GNU Lesser General Public 16 | # License as published by the Free Software Foundation; either 17 | # version 2.1 of the License, or (at your option) any later version. 18 | # 19 | # This library is distributed in the hope that it will be useful, 20 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 21 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 22 | # Lesser General Public License for more details. 23 | # 24 | # You should have received a copy of the GNU Lesser General Public 25 | # License along with this library; if not, write to the Free Software 26 | # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 27 | # 02110-1301 USA 28 | ######################### END LICENSE BLOCK ######################### 29 | 30 | from .charsetgroupprober import CharSetGroupProber 31 | from .utf8prober import UTF8Prober 32 | from .sjisprober import SJISProber 33 | from .eucjpprober import EUCJPProber 34 | from .gb2312prober import GB2312Prober 35 | from .euckrprober import EUCKRProber 36 | from .cp949prober import CP949Prober 37 | from .big5prober import Big5Prober 38 | from .euctwprober import EUCTWProber 39 | 40 | 41 | class MBCSGroupProber(CharSetGroupProber): 42 | def __init__(self): 43 | CharSetGroupProber.__init__(self) 44 | self._mProbers = [ 45 | UTF8Prober(), 46 | SJISProber(), 47 | EUCJPProber(), 48 | GB2312Prober(), 49 | EUCKRProber(), 50 | CP949Prober(), 51 | Big5Prober(), 52 | EUCTWProber() 53 | ] 54 | self.reset() 55 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/urllib3/__init__.py: -------------------------------------------------------------------------------- 1 | """ 2 | urllib3 - Thread-safe connection pooling and re-using. 3 | """ 4 | 5 | __author__ = 'Andrey Petrov (andrey.petrov@shazow.net)' 6 | __license__ = 'MIT' 7 | __version__ = '1.12' 8 | 9 | 10 | from .connectionpool import ( 11 | HTTPConnectionPool, 12 | HTTPSConnectionPool, 13 | connection_from_url 14 | ) 15 | 16 | from . import exceptions 17 | from .filepost import encode_multipart_formdata 18 | from .poolmanager import PoolManager, ProxyManager, proxy_from_url 19 | from .response import HTTPResponse 20 | from .util.request import make_headers 21 | from .util.url import get_host 22 | from .util.timeout import Timeout 23 | from .util.retry import Retry 24 | 25 | 26 | # Set default logging handler to avoid "No handler found" warnings. 27 | import logging 28 | try: # Python 2.7+ 29 | from logging import NullHandler 30 | except ImportError: 31 | class NullHandler(logging.Handler): 32 | def emit(self, record): 33 | pass 34 | 35 | logging.getLogger(__name__).addHandler(NullHandler()) 36 | 37 | def add_stderr_logger(level=logging.DEBUG): 38 | """ 39 | Helper for quickly adding a StreamHandler to the logger. Useful for 40 | debugging. 41 | 42 | Returns the handler after adding it. 43 | """ 44 | # This method needs to be in this __init__.py to get the __name__ correct 45 | # even if urllib3 is vendored within another package. 46 | logger = logging.getLogger(__name__) 47 | handler = logging.StreamHandler() 48 | handler.setFormatter(logging.Formatter('%(asctime)s %(levelname)s %(message)s')) 49 | logger.addHandler(handler) 50 | logger.setLevel(level) 51 | logger.debug('Added a stderr logging handler to logger: %s' % __name__) 52 | return handler 53 | 54 | # ... Clean up. 55 | del NullHandler 56 | 57 | 58 | import warnings 59 | # SecurityWarning's always go off by default. 60 | warnings.simplefilter('always', exceptions.SecurityWarning, append=True) 61 | # SubjectAltNameWarning's should go off once per host 62 | warnings.simplefilter('default', exceptions.SubjectAltNameWarning) 63 | # InsecurePlatformWarning's don't vary between requests, so we keep it default. 64 | warnings.simplefilter('default', exceptions.InsecurePlatformWarning, 65 | append=True) 66 | 67 | def disable_warnings(category=exceptions.HTTPWarning): 68 | """ 69 | Helper for quickly disabling all urllib3 warnings. 70 | """ 71 | warnings.simplefilter('ignore', category) 72 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/urllib3/contrib/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/apigee/henchman/13c53c66669800aaa89f1799ac974b45ec473c3d/modules/curl/curl/requests/requests/packages/urllib3/contrib/__init__.py -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/urllib3/filepost.py: -------------------------------------------------------------------------------- 1 | import codecs 2 | 3 | from uuid import uuid4 4 | from io import BytesIO 5 | 6 | from .packages import six 7 | from .packages.six import b 8 | from .fields import RequestField 9 | 10 | writer = codecs.lookup('utf-8')[3] 11 | 12 | 13 | def choose_boundary(): 14 | """ 15 | Our embarassingly-simple replacement for mimetools.choose_boundary. 16 | """ 17 | return uuid4().hex 18 | 19 | 20 | def iter_field_objects(fields): 21 | """ 22 | Iterate over fields. 23 | 24 | Supports list of (k, v) tuples and dicts, and lists of 25 | :class:`~urllib3.fields.RequestField`. 26 | 27 | """ 28 | if isinstance(fields, dict): 29 | i = six.iteritems(fields) 30 | else: 31 | i = iter(fields) 32 | 33 | for field in i: 34 | if isinstance(field, RequestField): 35 | yield field 36 | else: 37 | yield RequestField.from_tuples(*field) 38 | 39 | 40 | def iter_fields(fields): 41 | """ 42 | .. deprecated:: 1.6 43 | 44 | Iterate over fields. 45 | 46 | The addition of :class:`~urllib3.fields.RequestField` makes this function 47 | obsolete. Instead, use :func:`iter_field_objects`, which returns 48 | :class:`~urllib3.fields.RequestField` objects. 49 | 50 | Supports list of (k, v) tuples and dicts. 51 | """ 52 | if isinstance(fields, dict): 53 | return ((k, v) for k, v in six.iteritems(fields)) 54 | 55 | return ((k, v) for k, v in fields) 56 | 57 | 58 | def encode_multipart_formdata(fields, boundary=None): 59 | """ 60 | Encode a dictionary of ``fields`` using the multipart/form-data MIME format. 61 | 62 | :param fields: 63 | Dictionary of fields or list of (key, :class:`~urllib3.fields.RequestField`). 64 | 65 | :param boundary: 66 | If not specified, then a random boundary will be generated using 67 | :func:`mimetools.choose_boundary`. 68 | """ 69 | body = BytesIO() 70 | if boundary is None: 71 | boundary = choose_boundary() 72 | 73 | for field in iter_field_objects(fields): 74 | body.write(b('--%s\r\n' % (boundary))) 75 | 76 | writer(body).write(field.render_headers()) 77 | data = field.data 78 | 79 | if isinstance(data, int): 80 | data = str(data) # Backwards compatibility 81 | 82 | if isinstance(data, six.text_type): 83 | writer(body).write(data) 84 | else: 85 | body.write(data) 86 | 87 | body.write(b'\r\n') 88 | 89 | body.write(b('--%s--\r\n' % (boundary))) 90 | 91 | content_type = str('multipart/form-data; boundary=%s' % boundary) 92 | 93 | return body.getvalue(), content_type 94 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/urllib3/packages/__init__.py: -------------------------------------------------------------------------------- 1 | from __future__ import absolute_import 2 | 3 | from . import ssl_match_hostname 4 | 5 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/urllib3/packages/ssl_match_hostname/__init__.py: -------------------------------------------------------------------------------- 1 | try: 2 | # Python 3.2+ 3 | from ssl import CertificateError, match_hostname 4 | except ImportError: 5 | try: 6 | # Backport of the function from a pypi module 7 | from backports.ssl_match_hostname import CertificateError, match_hostname 8 | except ImportError: 9 | # Our vendored copy 10 | from ._implementation import CertificateError, match_hostname 11 | 12 | # Not needed, but documenting what we provide. 13 | __all__ = ('CertificateError', 'match_hostname') 14 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/urllib3/util/__init__.py: -------------------------------------------------------------------------------- 1 | # For backwards compatibility, provide imports that used to be here. 2 | from .connection import is_connection_dropped 3 | from .request import make_headers 4 | from .response import is_fp_closed 5 | from .ssl_ import ( 6 | SSLContext, 7 | HAS_SNI, 8 | assert_fingerprint, 9 | resolve_cert_reqs, 10 | resolve_ssl_version, 11 | ssl_wrap_socket, 12 | ) 13 | from .timeout import ( 14 | current_time, 15 | Timeout, 16 | ) 17 | 18 | from .retry import Retry 19 | from .url import ( 20 | get_host, 21 | parse_url, 22 | split_first, 23 | Url, 24 | ) 25 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/urllib3/util/request.py: -------------------------------------------------------------------------------- 1 | from base64 import b64encode 2 | 3 | from ..packages.six import b 4 | 5 | ACCEPT_ENCODING = 'gzip,deflate' 6 | 7 | 8 | def make_headers(keep_alive=None, accept_encoding=None, user_agent=None, 9 | basic_auth=None, proxy_basic_auth=None, disable_cache=None): 10 | """ 11 | Shortcuts for generating request headers. 12 | 13 | :param keep_alive: 14 | If ``True``, adds 'connection: keep-alive' header. 15 | 16 | :param accept_encoding: 17 | Can be a boolean, list, or string. 18 | ``True`` translates to 'gzip,deflate'. 19 | List will get joined by comma. 20 | String will be used as provided. 21 | 22 | :param user_agent: 23 | String representing the user-agent you want, such as 24 | "python-urllib3/0.6" 25 | 26 | :param basic_auth: 27 | Colon-separated username:password string for 'authorization: basic ...' 28 | auth header. 29 | 30 | :param proxy_basic_auth: 31 | Colon-separated username:password string for 'proxy-authorization: basic ...' 32 | auth header. 33 | 34 | :param disable_cache: 35 | If ``True``, adds 'cache-control: no-cache' header. 36 | 37 | Example:: 38 | 39 | >>> make_headers(keep_alive=True, user_agent="Batman/1.0") 40 | {'connection': 'keep-alive', 'user-agent': 'Batman/1.0'} 41 | >>> make_headers(accept_encoding=True) 42 | {'accept-encoding': 'gzip,deflate'} 43 | """ 44 | headers = {} 45 | if accept_encoding: 46 | if isinstance(accept_encoding, str): 47 | pass 48 | elif isinstance(accept_encoding, list): 49 | accept_encoding = ','.join(accept_encoding) 50 | else: 51 | accept_encoding = ACCEPT_ENCODING 52 | headers['accept-encoding'] = accept_encoding 53 | 54 | if user_agent: 55 | headers['user-agent'] = user_agent 56 | 57 | if keep_alive: 58 | headers['connection'] = 'keep-alive' 59 | 60 | if basic_auth: 61 | headers['authorization'] = 'Basic ' + \ 62 | b64encode(b(basic_auth)).decode('utf-8') 63 | 64 | if proxy_basic_auth: 65 | headers['proxy-authorization'] = 'Basic ' + \ 66 | b64encode(b(proxy_basic_auth)).decode('utf-8') 67 | 68 | if disable_cache: 69 | headers['cache-control'] = 'no-cache' 70 | 71 | return headers 72 | -------------------------------------------------------------------------------- /modules/curl/curl/requests/requests/packages/urllib3/util/response.py: -------------------------------------------------------------------------------- 1 | from ..packages.six.moves import http_client as httplib 2 | 3 | from ..exceptions import HeaderParsingError 4 | 5 | 6 | def is_fp_closed(obj): 7 | """ 8 | Checks whether a given file-like object is closed. 9 | 10 | :param obj: 11 | The file-like object to check. 12 | """ 13 | 14 | try: 15 | # Check via the official file-like-object way. 16 | return obj.closed 17 | except AttributeError: 18 | pass 19 | 20 | try: 21 | # Check if the object is a container for another file-like object that 22 | # gets released on exhaustion (e.g. HTTPResponse). 23 | return obj.fp is None 24 | except AttributeError: 25 | pass 26 | 27 | raise ValueError("Unable to determine whether fp is closed.") 28 | 29 | 30 | def assert_header_parsing(headers): 31 | """ 32 | Asserts whether all headers have been successfully parsed. 33 | Extracts encountered errors from the result of parsing headers. 34 | 35 | Only works on Python 3. 36 | 37 | :param headers: Headers to verify. 38 | :type headers: `httplib.HTTPMessage`. 39 | 40 | :raises urllib3.exceptions.HeaderParsingError: 41 | If parsing errors are found. 42 | """ 43 | 44 | # This will fail silently if we pass in the wrong kind of parameter. 45 | # To make debugging easier add an explicit check. 46 | if not isinstance(headers, httplib.HTTPMessage): 47 | raise TypeError('expected httplib.Message, got {}.'.format( 48 | type(headers))) 49 | 50 | defects = getattr(headers, 'defects', None) 51 | get_payload = getattr(headers, 'get_payload', None) 52 | 53 | unparsed_data = None 54 | if get_payload: # Platform-specific: Python 3. 55 | unparsed_data = get_payload() 56 | 57 | if defects or unparsed_data: 58 | raise HeaderParsingError(defects=defects, unparsed_data=unparsed_data) 59 | 60 | 61 | def is_response_to_head(response): 62 | """ 63 | Checks, wether a the request of a response has been a HEAD-request. 64 | Handles the quirks of AppEngine. 65 | 66 | :param conn: 67 | :type conn: :class:`httplib.HTTPResponse` 68 | """ 69 | # FIXME: Can we do this somehow without accessing private httplib _method? 70 | method = response._method 71 | if isinstance(method, int): # Platform-specific: Appengine 72 | return method == 3 73 | return method.upper() == 'HEAD' 74 | -------------------------------------------------------------------------------- /modules/curl/curl/xmltodict/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2012 Martin Blech and individual contributors. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /modules/rpm/rpm: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import traceback 4 | import os 5 | import json 6 | import subprocess 7 | import json 8 | import re 9 | 10 | # Params for this module 11 | # url: url that provides the rpm that should be installed 12 | # loglevel: if debug, it shows you the entire output as part of 'output' key 13 | 14 | params = json.loads(sys.stdin.read()) 15 | result = {} 16 | url = "" 17 | try: 18 | loglevel = params.pop("loglevel", "info") 19 | state = params.pop("state", "present") 20 | url = params.pop('url', url) 21 | if not url: 22 | raise "Missing required param 'url'" 23 | url = "'%s'" % url 24 | 25 | msg = "" 26 | if state == "present" || state == "": 27 | commands = ["rpm", "-ivh", url] 28 | msg = "Successfully installed package %s" % url 29 | elif state == "absent": 30 | commands = ["rpm", "-e", url] 31 | msg = "Successfully uninstalled package %s" % url 32 | else: 33 | raise Exception("state should be either 'present' or 'absent'. Got %s" % state) 34 | 35 | replacepkgs = params.get("replacepkgs", False) 36 | if replacepkgs and replacepkgs in ["yes", "true", True]: 37 | commands.append("--replacepkgs") 38 | 39 | p = subprocess.Popen(commands, stdout=subprocess.PIPE,stderr=subprocess.PIPE) 40 | output, err = p.communicate() 41 | 42 | if p.returncode > 0: 43 | raise Exception(err) 44 | 45 | result['status'] = "changed" 46 | result['msg'] = msg 47 | result['output'] = {'stdout': output, 'stderr': err} 48 | 49 | except Exception as e: 50 | result['status'] = "error" 51 | result['msg'] = "Error occurred while installing package {0} - {1}".format(url, e.message) 52 | result['output'] = {'stdout': output, 'stderr': err} 53 | print json.dumps(result) 54 | -------------------------------------------------------------------------------- /modules/rpm/rpm_module.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "os" 7 | "os/exec" 8 | 9 | "encoding/json" 10 | ) 11 | 12 | type RpmModule struct { 13 | Name string 14 | State string 15 | Url string 16 | Replacepkgs string 17 | } 18 | 19 | var result map[string]interface{} = map[string]interface{}{} 20 | var yumSubcommands map[string]string = map[string]string{ 21 | "present": "install", 22 | "absent": "remove", 23 | } 24 | 25 | func main() { 26 | // recover code 27 | // also does the printout of result 28 | defer func() { 29 | if r := recover(); r != nil { 30 | result["status"] = "error" 31 | result["msg"] = r 32 | } 33 | 34 | output, err := json.Marshal(result) 35 | if err != nil { 36 | panic(err) 37 | } 38 | fmt.Print(string(output)) 39 | }() 40 | 41 | rpmParams := RpmModule{} 42 | 43 | // basically unmarshall but can take in a io.Reader 44 | dec := json.NewDecoder(os.Stdin) 45 | if err := dec.Decode(&rpmParams); err != nil { 46 | panic(err.Error()) 47 | } 48 | 49 | if rpmParams.Url == "" { 50 | panic("Missing required param 'url'") 51 | } 52 | rpmParams.Url = fmt.Sprintf("'%s'", rpmParams.Url) 53 | 54 | msg := "" 55 | var cmds []string 56 | if rpmParams.State == "present" || rpmParams.State == "" { 57 | cmds = []string{"-ivh", rpmParams.Url} 58 | } else if rpmParams.State == "absent" { 59 | cmds = []string{"-e", rpmParams.Url} 60 | } else { 61 | panic(fmt.Sprintf("State should be either 'present' or 'absent'. Got %s", rpmParams.State)) 62 | } 63 | 64 | for _, x := range []string{"yes", "true", "True"} { 65 | if rpmParams.Replacepkgs == x { 66 | cmds = append(cmds, "--replacepkgs") 67 | break 68 | } 69 | } 70 | 71 | cmd := exec.Command("rpm", cmds...) 72 | 73 | var stdout, stderr bytes.Buffer 74 | cmd.Stdout = &stdout 75 | cmd.Stderr = &stderr 76 | 77 | if err := cmd.Run(); err != nil { 78 | panic(fmt.Sprintf("Error occurred while installing/removing package %s - %s", rpmParams.Url, stderr.String())) 79 | } 80 | 81 | result["status"] = "changed" 82 | result["msg"] = msg 83 | result["output"] = map[string]string{ 84 | "stdout": stdout.String(), 85 | "stderr": stderr.String(), 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /modules/shell/shell_module.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "os" 7 | "os/exec" 8 | "strings" 9 | 10 | "encoding/json" 11 | ) 12 | 13 | type ShellModule struct { 14 | Cmd string 15 | Chdir string 16 | Env string 17 | Shell string 18 | } 19 | 20 | var result map[string]interface{} = map[string]interface{}{} 21 | 22 | func main() { 23 | // recover code 24 | // also does the printout of result 25 | defer func() { 26 | if r := recover(); r != nil { 27 | result["status"] = "error" 28 | result["msg"] = fmt.Sprintf("Command exec'ed with errors. Error - %s", r) 29 | } 30 | 31 | output, err := json.Marshal(result) 32 | if err != nil { 33 | panic(err) 34 | } 35 | 36 | result["msg"] = result["msg"].(string) + fmt.Sprintf(" - %v", len(output)) 37 | 38 | output, err = json.Marshal(result) 39 | if err != nil { 40 | panic(err) 41 | } 42 | fmt.Print(string(output)) 43 | }() 44 | 45 | shellParams := ShellModule{} 46 | 47 | // basically unmarshall but can take in a io.Reader 48 | dec := json.NewDecoder(os.Stdin) 49 | if err := dec.Decode(&shellParams); err != nil { 50 | panic(err.Error()) 51 | } 52 | 53 | if shellParams.Cmd == "" { 54 | panic("Required parameter 'cmd' not found") 55 | } 56 | 57 | if shellParams.Shell == "" { 58 | shellParams.Shell = "sh" 59 | } 60 | if err := setEnv(shellParams.Env); err != nil { 61 | panic("While setting env vars, " + err.Error()) 62 | } 63 | 64 | var cmd *exec.Cmd 65 | cmd = exec.Command("/bin/"+shellParams.Shell, "-c", shellParams.Cmd) 66 | cmd.Dir = shellParams.Chdir 67 | 68 | var stdout, stderr bytes.Buffer 69 | cmd.Stdout = &stdout 70 | cmd.Stderr = &stderr 71 | 72 | if err := cmd.Run(); err != nil { 73 | result["status"] = "failure" 74 | } else { 75 | result["status"] = "changed" 76 | } 77 | 78 | result["msg"] = "executed command" 79 | result["output"] = map[string]string{ 80 | "stdout": stdout.String(), 81 | "stderr": stderr.String(), 82 | } 83 | } 84 | 85 | // setEnv expects a string of "key=val key=val key=val" and adds them to the current env 86 | func setEnv(envStr string) error { 87 | envList := strings.Split(envStr, " ") 88 | for _, envKeyVal := range envList { 89 | if strings.ContainsAny(envKeyVal, "=") { 90 | keyVal := strings.Split(envKeyVal, "=") 91 | if err := os.Setenv(keyVal[0], keyVal[1]); err != nil { 92 | return err 93 | } 94 | } 95 | } 96 | 97 | return nil 98 | } 99 | -------------------------------------------------------------------------------- /modules/yum/yum: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python 2 | import sys 3 | import os 4 | import json 5 | import subprocess 6 | 7 | yum_subcommands = { 8 | "present": "install", 9 | "absent": "remove", 10 | } 11 | 12 | # Params for this module 13 | # package: package name that will be installed via yum 14 | def is_installed(name, version): 15 | command = ["rpm", "-qa"] + name.split() 16 | p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 17 | output, err = p.communicate() 18 | for pkg in output.split("\n"): 19 | if pkg.startswith(name): 20 | if version: 21 | if pkg.endswith(version): 22 | return True 23 | else: 24 | return True 25 | return False 26 | 27 | params = json.loads(sys.stdin.read()) 28 | result = {} 29 | possible_states = ["absent", "present"] 30 | try: 31 | name = params.get('name') 32 | version = params.get('version') 33 | state = params.get('state', 'present') 34 | # If version is latest. Just ignore it 35 | if version == 'latest': 36 | version = None 37 | # check if state provided is valid 38 | if state not in possible_states: 39 | raise Exception("Valid states are one of %s " % ','.join(possible_states)) 40 | 41 | full_pkgname = name 42 | if version: 43 | full_pkgname = name + "-" + version 44 | 45 | installed = is_installed(name, version) 46 | if installed and state == "present": 47 | result['msg'] = "Package %s already present" % full_pkgname 48 | result['status'] = "ok" 49 | elif not installed and state == "absent": 50 | result['msg'] = "Package %s already absent" % full_pkgname 51 | result['status'] = "ok" 52 | else: 53 | sub_command = yum_subcommands[state] 54 | command = ["yum", sub_command, "-y", full_pkgname] 55 | p = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.PIPE) 56 | output, err = p.communicate() 57 | if p.returncode > 0: 58 | raise Exception(err.decode('utf-8')) 59 | else: 60 | output = output.decode('utf-8') 61 | result['status'] = "changed" 62 | result['msg'] = "State of package %s changed - %s" % (name, output) 63 | result['output'] = output 64 | except Exception, e: 65 | result['status'] = "error" 66 | result['msg'] = "Error occurred while installing package %s - %s" % (name, e.message) 67 | result['output'] = e.message 68 | 69 | print json.dumps(result) 70 | -------------------------------------------------------------------------------- /package.sh: -------------------------------------------------------------------------------- 1 | # Package tarballs per arch. 2 | # FIXME: Parameterize this, but not important right now 3 | 4 | set -e 5 | 6 | # Geese? 7 | GOOSES="darwin linux freebsd" 8 | GOARCHS="amd64" 9 | 10 | GIT_COMMIT_SHA1=`git rev-parse --short HEAD` 11 | 12 | mkdir -p artifacts 13 | 14 | ARTIFACTS=`pwd`/artifacts 15 | 16 | echo "Creating go module binaries" 17 | ./generateModuleBinaries.py 18 | 19 | for os in ${GOOSES} 20 | do 21 | for arch in ${GOARCHS} 22 | do 23 | echo "**** Building $os.$arch ****" 24 | BINDIR="bin/$os/$arch" 25 | GOOS=$os GOARCH=$arch godep go build -ldflags "-X 'main.minversion=$(echo ${CIRCLE_BUILD_NUM})'" -o bin/$os/$arch/henchman 26 | cp -R modules ${BINDIR} 27 | cd ${BINDIR} 28 | tar -czvf "henchman.${GIT_COMMIT_SHA1}.${os}.${arch}.tar.gz" henchman modules 29 | cp *.tar.gz ${ARTIFACTS} 30 | cd - 31 | done 32 | done 33 | 34 | echo "Copying artifacts" 35 | cp -r ${ARTIFACTS}/* $CIRCLE_ARTIFACTS 36 | 37 | echo "Cleaning up..." 38 | rm -rf bin/ 39 | -------------------------------------------------------------------------------- /vendor/github.com/codegangsta/cli/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 1.1 3 | 4 | script: 5 | - go vet ./... 6 | - go test -v ./... 7 | -------------------------------------------------------------------------------- /vendor/github.com/codegangsta/cli/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (C) 2013 Jeremy Saenz 2 | All Rights Reserved. 3 | 4 | MIT LICENSE 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy of 7 | this software and associated documentation files (the "Software"), to deal in 8 | the Software without restriction, including without limitation the rights to 9 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 10 | the Software, and to permit persons to whom the Software is furnished to do so, 11 | subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 18 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 19 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 20 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 21 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/github.com/codegangsta/cli/cli.go: -------------------------------------------------------------------------------- 1 | // Package cli provides a minimal framework for creating and organizing command line 2 | // Go applications. cli is designed to be easy to understand and write, the most simple 3 | // cli application can be written as follows: 4 | // func main() { 5 | // cli.NewApp().Run(os.Args) 6 | // } 7 | // 8 | // Of course this application does not do much, so let's make this an actual application: 9 | // func main() { 10 | // app := cli.NewApp() 11 | // app.Name = "greet" 12 | // app.Usage = "say a greeting" 13 | // app.Action = func(c *cli.Context) { 14 | // println("Greetings") 15 | // } 16 | // 17 | // app.Run(os.Args) 18 | // } 19 | package cli 20 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/.gitignore: -------------------------------------------------------------------------------- 1 | # Compiled Object files, Static and Dynamic libs (Shared Objects) 2 | *.o 3 | *.a 4 | *.so 5 | 6 | # Folders 7 | _obj 8 | _test 9 | .idea 10 | 11 | # Architecture specific extensions/prefixes 12 | *.[568vq] 13 | [568vq].out 14 | 15 | *.cgo1.go 16 | *.cgo2.c 17 | _cgo_defun.c 18 | _cgo_gotypes.go 19 | _cgo_export.* 20 | 21 | _testmain.go 22 | 23 | *.exe 24 | 25 | .project 26 | EBNF.txt 27 | test1.tpl 28 | pongo2_internal_test.go 29 | tpl-error.out 30 | /count.out 31 | /cover.out 32 | *.swp 33 | *.iml 34 | /cpu.out 35 | /mem.out 36 | /pongo2.test 37 | *.error 38 | /profile 39 | /coverage.out 40 | /pongo2_internal_test.ignore 41 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.4 5 | - tip 6 | install: 7 | - go get golang.org/x/tools/cmd/cover 8 | - go get github.com/mattn/goveralls 9 | - go get gopkg.in/check.v1 10 | script: 11 | - go test -v -covermode=count -coverprofile=coverage.out -bench . -cpu 1,4 12 | - '[ "${TRAVIS_PULL_REQUEST}" = "false" ] && $HOME/gopath/bin/goveralls -coverprofile=coverage.out -service=travis-ci -repotoken $COVERALLS_TOKEN || true' 13 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/AUTHORS: -------------------------------------------------------------------------------- 1 | Main author and maintainer of pongo2: 2 | 3 | * Florian Schlachter 4 | 5 | Contributors (in no specific order): 6 | 7 | * @romanoaugusto88 8 | * @vitalbh 9 | 10 | Feel free to add yourself to the list or to modify your entry if you did a contribution. 11 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2013-2014 Florian Schlachter 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy of 6 | this software and associated documentation files (the "Software"), to deal in 7 | the Software without restriction, including without limitation the rights to 8 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 9 | the Software, and to permit persons to whom the Software is furnished to do so, 10 | subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 17 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 18 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 19 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 20 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/doc.go: -------------------------------------------------------------------------------- 1 | // A Django-syntax like template-engine 2 | // 3 | // Blog posts about pongo2 (including introduction and migration): 4 | // https://www.florian-schlachter.de/?tag=pongo2 5 | // 6 | // Complete documentation on the template language: 7 | // https://docs.djangoproject.com/en/dev/topics/templates/ 8 | // 9 | // Try out pongo2 live in the pongo2 playground: 10 | // https://www.florian-schlachter.de/pongo2/ 11 | // 12 | // Make sure to read README.md in the repository as well. 13 | // 14 | // A tiny example with template strings: 15 | // 16 | // (Snippet on playground: https://www.florian-schlachter.de/pongo2/?id=1206546277) 17 | // 18 | // // Compile the template first (i. e. creating the AST) 19 | // tpl, err := pongo2.FromString("Hello {{ name|capfirst }}!") 20 | // if err != nil { 21 | // panic(err) 22 | // } 23 | // // Now you can render the template with the given 24 | // // pongo2.Context how often you want to. 25 | // out, err := tpl.Execute(pongo2.Context{"name": "fred"}) 26 | // if err != nil { 27 | // panic(err) 28 | // } 29 | // fmt.Println(out) // Output: Hello Fred! 30 | // 31 | package pongo2 32 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/error.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | import ( 4 | "bufio" 5 | "fmt" 6 | "os" 7 | ) 8 | 9 | // The Error type is being used to address an error during lexing, parsing or 10 | // execution. If you want to return an error object (for example in your own 11 | // tag or filter) fill this object with as much information as you have. 12 | // Make sure "Sender" is always given (if you're returning an error within 13 | // a filter, make Sender equals 'filter:yourfilter'; same goes for tags: 'tag:mytag'). 14 | // It's okay if you only fill in ErrorMsg if you don't have any other details at hand. 15 | type Error struct { 16 | Template *Template 17 | Filename string 18 | Line int 19 | Column int 20 | Token *Token 21 | Sender string 22 | ErrorMsg string 23 | } 24 | 25 | func (e *Error) updateFromTokenIfNeeded(template *Template, t *Token) *Error { 26 | if e.Template == nil { 27 | e.Template = template 28 | } 29 | 30 | if e.Token == nil { 31 | e.Token = t 32 | if e.Line <= 0 { 33 | e.Line = t.Line 34 | e.Column = t.Col 35 | } 36 | } 37 | 38 | return e 39 | } 40 | 41 | // Returns a nice formatted error string. 42 | func (e *Error) Error() string { 43 | s := "[Error" 44 | if e.Sender != "" { 45 | s += " (where: " + e.Sender + ")" 46 | } 47 | if e.Filename != "" { 48 | s += " in " + e.Filename 49 | } 50 | if e.Line > 0 { 51 | s += fmt.Sprintf(" | Line %d Col %d", e.Line, e.Column) 52 | if e.Token != nil { 53 | s += fmt.Sprintf(" near '%s'", e.Token.Val) 54 | } 55 | } 56 | s += "] " 57 | s += e.ErrorMsg 58 | return s 59 | } 60 | 61 | // RawLine returns the affected line from the original template, if available. 62 | func (e *Error) RawLine() (line string, available bool) { 63 | if e.Line <= 0 || e.Filename == "" { 64 | return "", false 65 | } 66 | 67 | filename := e.Filename 68 | if e.Template != nil { 69 | filename = e.Template.set.resolveFilename(e.Template, e.Filename) 70 | } 71 | file, err := os.Open(filename) 72 | if err != nil { 73 | panic(err) 74 | } 75 | defer func() { 76 | err := file.Close() 77 | if err != nil { 78 | panic(err) 79 | } 80 | }() 81 | 82 | scanner := bufio.NewScanner(file) 83 | l := 0 84 | for scanner.Scan() { 85 | l++ 86 | if l == e.Line { 87 | return scanner.Text(), true 88 | } 89 | } 90 | return "", false 91 | } 92 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/helpers.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | func max(a, b int) int { 4 | if a > b { 5 | return a 6 | } 7 | return b 8 | } 9 | 10 | func min(a, b int) int { 11 | if a < b { 12 | return a 13 | } 14 | return b 15 | } 16 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/nodes.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | // The root document 4 | type nodeDocument struct { 5 | Nodes []INode 6 | } 7 | 8 | func (doc *nodeDocument) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 9 | for _, n := range doc.Nodes { 10 | err := n.Execute(ctx, writer) 11 | if err != nil { 12 | return err 13 | } 14 | } 15 | return nil 16 | } 17 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/nodes_html.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | type nodeHTML struct { 4 | token *Token 5 | } 6 | 7 | func (n *nodeHTML) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 8 | writer.WriteString(n.token.Val) 9 | return nil 10 | } 11 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/nodes_wrapper.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | type NodeWrapper struct { 4 | Endtag string 5 | nodes []INode 6 | } 7 | 8 | func (wrapper *NodeWrapper) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 9 | for _, n := range wrapper.nodes { 10 | err := n.Execute(ctx, writer) 11 | if err != nil { 12 | return err 13 | } 14 | } 15 | return nil 16 | } 17 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/parser_document.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | // Doc = { ( Filter | Tag | HTML ) } 4 | func (p *Parser) parseDocElement() (INode, *Error) { 5 | t := p.Current() 6 | 7 | switch t.Typ { 8 | case TokenHTML: 9 | p.Consume() // consume HTML element 10 | return &nodeHTML{token: t}, nil 11 | case TokenSymbol: 12 | switch t.Val { 13 | case "{{": 14 | // parse variable 15 | variable, err := p.parseVariableElement() 16 | if err != nil { 17 | return nil, err 18 | } 19 | return variable, nil 20 | case "{%": 21 | // parse tag 22 | tag, err := p.parseTagElement() 23 | if err != nil { 24 | return nil, err 25 | } 26 | return tag, nil 27 | } 28 | } 29 | return nil, p.Error("Unexpected token (only HTML/tags/filters in templates allowed)", t) 30 | } 31 | 32 | func (tpl *Template) parse() *Error { 33 | tpl.parser = newParser(tpl.name, tpl.tokens, tpl) 34 | doc, err := tpl.parser.parseDocument() 35 | if err != nil { 36 | return err 37 | } 38 | tpl.root = doc 39 | return nil 40 | } 41 | 42 | func (p *Parser) parseDocument() (*nodeDocument, *Error) { 43 | doc := &nodeDocument{} 44 | 45 | for p.Remaining() > 0 { 46 | node, err := p.parseDocElement() 47 | if err != nil { 48 | return nil, err 49 | } 50 | doc.Nodes = append(doc.Nodes, node) 51 | } 52 | 53 | return doc, nil 54 | } 55 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/pongo2.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | // Version string 4 | const Version = "dev" 5 | 6 | // Must panics, if a Template couldn't successfully parsed. This is how you 7 | // would use it: 8 | // var baseTemplate = pongo2.Must(pongo2.FromFile("templates/base.html")) 9 | func Must(tpl *Template, err error) *Template { 10 | if err != nil { 11 | panic(err) 12 | } 13 | return tpl 14 | } 15 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/tags_autoescape.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | type tagAutoescapeNode struct { 4 | wrapper *NodeWrapper 5 | autoescape bool 6 | } 7 | 8 | func (node *tagAutoescapeNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 9 | old := ctx.Autoescape 10 | ctx.Autoescape = node.autoescape 11 | 12 | err := node.wrapper.Execute(ctx, writer) 13 | if err != nil { 14 | return err 15 | } 16 | 17 | ctx.Autoescape = old 18 | 19 | return nil 20 | } 21 | 22 | func tagAutoescapeParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) { 23 | autoescapeNode := &tagAutoescapeNode{} 24 | 25 | wrapper, _, err := doc.WrapUntilTag("endautoescape") 26 | if err != nil { 27 | return nil, err 28 | } 29 | autoescapeNode.wrapper = wrapper 30 | 31 | modeToken := arguments.MatchType(TokenIdentifier) 32 | if modeToken == nil { 33 | return nil, arguments.Error("A mode is required for autoescape-tag.", nil) 34 | } 35 | if modeToken.Val == "on" { 36 | autoescapeNode.autoescape = true 37 | } else if modeToken.Val == "off" { 38 | autoescapeNode.autoescape = false 39 | } else { 40 | return nil, arguments.Error("Only 'on' or 'off' is valid as an autoescape-mode.", nil) 41 | } 42 | 43 | if arguments.Remaining() > 0 { 44 | return nil, arguments.Error("Malformed autoescape-tag arguments.", nil) 45 | } 46 | 47 | return autoescapeNode, nil 48 | } 49 | 50 | func init() { 51 | RegisterTag("autoescape", tagAutoescapeParser) 52 | } 53 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/tags_comment.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | type tagCommentNode struct{} 4 | 5 | func (node *tagCommentNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 6 | return nil 7 | } 8 | 9 | func tagCommentParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) { 10 | commentNode := &tagCommentNode{} 11 | 12 | // TODO: Process the endtag's arguments (see django 'comment'-tag documentation) 13 | _, _, err := doc.WrapUntilTag("endcomment") 14 | if err != nil { 15 | return nil, err 16 | } 17 | 18 | if arguments.Count() != 0 { 19 | return nil, arguments.Error("Tag 'comment' does not take any argument.", nil) 20 | } 21 | 22 | return commentNode, nil 23 | } 24 | 25 | func init() { 26 | RegisterTag("comment", tagCommentParser) 27 | } 28 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/tags_cycle.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | type tagCycleValue struct { 4 | node *tagCycleNode 5 | value *Value 6 | } 7 | 8 | type tagCycleNode struct { 9 | position *Token 10 | args []IEvaluator 11 | idx int 12 | asName string 13 | silent bool 14 | } 15 | 16 | func (cv *tagCycleValue) String() string { 17 | return cv.value.String() 18 | } 19 | 20 | func (node *tagCycleNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 21 | item := node.args[node.idx%len(node.args)] 22 | node.idx++ 23 | 24 | val, err := item.Evaluate(ctx) 25 | if err != nil { 26 | return err 27 | } 28 | 29 | if t, ok := val.Interface().(*tagCycleValue); ok { 30 | // {% cycle "test1" "test2" 31 | // {% cycle cycleitem %} 32 | 33 | // Update the cycle value with next value 34 | item := t.node.args[t.node.idx%len(t.node.args)] 35 | t.node.idx++ 36 | 37 | val, err := item.Evaluate(ctx) 38 | if err != nil { 39 | return err 40 | } 41 | 42 | t.value = val 43 | 44 | if !t.node.silent { 45 | writer.WriteString(val.String()) 46 | } 47 | } else { 48 | // Regular call 49 | 50 | cycleValue := &tagCycleValue{ 51 | node: node, 52 | value: val, 53 | } 54 | 55 | if node.asName != "" { 56 | ctx.Private[node.asName] = cycleValue 57 | } 58 | if !node.silent { 59 | writer.WriteString(val.String()) 60 | } 61 | } 62 | 63 | return nil 64 | } 65 | 66 | // HINT: We're not supporting the old comma-seperated list of expresions argument-style 67 | func tagCycleParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) { 68 | cycleNode := &tagCycleNode{ 69 | position: start, 70 | } 71 | 72 | for arguments.Remaining() > 0 { 73 | node, err := arguments.ParseExpression() 74 | if err != nil { 75 | return nil, err 76 | } 77 | cycleNode.args = append(cycleNode.args, node) 78 | 79 | if arguments.MatchOne(TokenKeyword, "as") != nil { 80 | // as 81 | 82 | nameToken := arguments.MatchType(TokenIdentifier) 83 | if nameToken == nil { 84 | return nil, arguments.Error("Name (identifier) expected after 'as'.", nil) 85 | } 86 | cycleNode.asName = nameToken.Val 87 | 88 | if arguments.MatchOne(TokenIdentifier, "silent") != nil { 89 | cycleNode.silent = true 90 | } 91 | 92 | // Now we're finished 93 | break 94 | } 95 | } 96 | 97 | if arguments.Remaining() > 0 { 98 | return nil, arguments.Error("Malformed cycle-tag.", nil) 99 | } 100 | 101 | return cycleNode, nil 102 | } 103 | 104 | func init() { 105 | RegisterTag("cycle", tagCycleParser) 106 | } 107 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/tags_extends.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | type tagExtendsNode struct { 4 | filename string 5 | } 6 | 7 | func (node *tagExtendsNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 8 | return nil 9 | } 10 | 11 | func tagExtendsParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) { 12 | extendsNode := &tagExtendsNode{} 13 | 14 | if doc.template.level > 1 { 15 | return nil, arguments.Error("The 'extends' tag can only defined on root level.", start) 16 | } 17 | 18 | if doc.template.parent != nil { 19 | // Already one parent 20 | return nil, arguments.Error("This template has already one parent.", start) 21 | } 22 | 23 | if filenameToken := arguments.MatchType(TokenString); filenameToken != nil { 24 | // prepared, static template 25 | 26 | // Get parent's filename 27 | parentFilename := doc.template.set.resolveFilename(doc.template, filenameToken.Val) 28 | 29 | // Parse the parent 30 | parentTemplate, err := doc.template.set.FromFile(parentFilename) 31 | if err != nil { 32 | return nil, err.(*Error) 33 | } 34 | 35 | // Keep track of things 36 | parentTemplate.child = doc.template 37 | doc.template.parent = parentTemplate 38 | extendsNode.filename = parentFilename 39 | } else { 40 | return nil, arguments.Error("Tag 'extends' requires a template filename as string.", nil) 41 | } 42 | 43 | if arguments.Remaining() > 0 { 44 | return nil, arguments.Error("Tag 'extends' does only take 1 argument.", nil) 45 | } 46 | 47 | return extendsNode, nil 48 | } 49 | 50 | func init() { 51 | RegisterTag("extends", tagExtendsParser) 52 | } 53 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/tags_filter.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | import ( 4 | "bytes" 5 | ) 6 | 7 | type nodeFilterCall struct { 8 | name string 9 | paramExpr IEvaluator 10 | } 11 | 12 | type tagFilterNode struct { 13 | position *Token 14 | bodyWrapper *NodeWrapper 15 | filterChain []*nodeFilterCall 16 | } 17 | 18 | func (node *tagFilterNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 19 | temp := bytes.NewBuffer(make([]byte, 0, 1024)) // 1 KiB size 20 | 21 | err := node.bodyWrapper.Execute(ctx, temp) 22 | if err != nil { 23 | return err 24 | } 25 | 26 | value := AsValue(temp.String()) 27 | 28 | for _, call := range node.filterChain { 29 | var param *Value 30 | if call.paramExpr != nil { 31 | param, err = call.paramExpr.Evaluate(ctx) 32 | if err != nil { 33 | return err 34 | } 35 | } else { 36 | param = AsValue(nil) 37 | } 38 | value, err = ApplyFilter(call.name, value, param) 39 | if err != nil { 40 | return ctx.Error(err.Error(), node.position) 41 | } 42 | } 43 | 44 | writer.WriteString(value.String()) 45 | 46 | return nil 47 | } 48 | 49 | func tagFilterParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) { 50 | filterNode := &tagFilterNode{ 51 | position: start, 52 | } 53 | 54 | wrapper, _, err := doc.WrapUntilTag("endfilter") 55 | if err != nil { 56 | return nil, err 57 | } 58 | filterNode.bodyWrapper = wrapper 59 | 60 | for arguments.Remaining() > 0 { 61 | filterCall := &nodeFilterCall{} 62 | 63 | nameToken := arguments.MatchType(TokenIdentifier) 64 | if nameToken == nil { 65 | return nil, arguments.Error("Expected a filter name (identifier).", nil) 66 | } 67 | filterCall.name = nameToken.Val 68 | 69 | if arguments.MatchOne(TokenSymbol, ":") != nil { 70 | // Filter parameter 71 | // NOTICE: we can't use ParseExpression() here, because it would parse the next filter "|..." as well in the argument list 72 | expr, err := arguments.parseVariableOrLiteral() 73 | if err != nil { 74 | return nil, err 75 | } 76 | filterCall.paramExpr = expr 77 | } 78 | 79 | filterNode.filterChain = append(filterNode.filterChain, filterCall) 80 | 81 | if arguments.MatchOne(TokenSymbol, "|") == nil { 82 | break 83 | } 84 | } 85 | 86 | if arguments.Remaining() > 0 { 87 | return nil, arguments.Error("Malformed filter-tag arguments.", nil) 88 | } 89 | 90 | return filterNode, nil 91 | } 92 | 93 | func init() { 94 | RegisterTag("filter", tagFilterParser) 95 | } 96 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/tags_firstof.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | type tagFirstofNode struct { 4 | position *Token 5 | args []IEvaluator 6 | } 7 | 8 | func (node *tagFirstofNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 9 | for _, arg := range node.args { 10 | val, err := arg.Evaluate(ctx) 11 | if err != nil { 12 | return err 13 | } 14 | 15 | if val.IsTrue() { 16 | if ctx.Autoescape && !arg.FilterApplied("safe") { 17 | val, err = ApplyFilter("escape", val, nil) 18 | if err != nil { 19 | return err 20 | } 21 | } 22 | 23 | writer.WriteString(val.String()) 24 | return nil 25 | } 26 | } 27 | 28 | return nil 29 | } 30 | 31 | func tagFirstofParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) { 32 | firstofNode := &tagFirstofNode{ 33 | position: start, 34 | } 35 | 36 | for arguments.Remaining() > 0 { 37 | node, err := arguments.ParseExpression() 38 | if err != nil { 39 | return nil, err 40 | } 41 | firstofNode.args = append(firstofNode.args, node) 42 | } 43 | 44 | return firstofNode, nil 45 | } 46 | 47 | func init() { 48 | RegisterTag("firstof", tagFirstofParser) 49 | } 50 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/tags_if.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | type tagIfNode struct { 4 | conditions []IEvaluator 5 | wrappers []*NodeWrapper 6 | } 7 | 8 | func (node *tagIfNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 9 | for i, condition := range node.conditions { 10 | result, err := condition.Evaluate(ctx) 11 | if err != nil { 12 | return err 13 | } 14 | 15 | if result.IsTrue() { 16 | return node.wrappers[i].Execute(ctx, writer) 17 | } 18 | // Last condition? 19 | if len(node.conditions) == i+1 && len(node.wrappers) > i+1 { 20 | return node.wrappers[i+1].Execute(ctx, writer) 21 | } 22 | } 23 | return nil 24 | } 25 | 26 | func tagIfParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) { 27 | ifNode := &tagIfNode{} 28 | 29 | // Parse first and main IF condition 30 | condition, err := arguments.ParseExpression() 31 | if err != nil { 32 | return nil, err 33 | } 34 | ifNode.conditions = append(ifNode.conditions, condition) 35 | 36 | if arguments.Remaining() > 0 { 37 | return nil, arguments.Error("If-condition is malformed.", nil) 38 | } 39 | 40 | // Check the rest 41 | for { 42 | wrapper, tagArgs, err := doc.WrapUntilTag("elif", "else", "endif") 43 | if err != nil { 44 | return nil, err 45 | } 46 | ifNode.wrappers = append(ifNode.wrappers, wrapper) 47 | 48 | if wrapper.Endtag == "elif" { 49 | // elif can take a condition 50 | condition, err = tagArgs.ParseExpression() 51 | if err != nil { 52 | return nil, err 53 | } 54 | ifNode.conditions = append(ifNode.conditions, condition) 55 | 56 | if tagArgs.Remaining() > 0 { 57 | return nil, tagArgs.Error("Elif-condition is malformed.", nil) 58 | } 59 | } else { 60 | if tagArgs.Count() > 0 { 61 | // else/endif can't take any conditions 62 | return nil, tagArgs.Error("Arguments not allowed here.", nil) 63 | } 64 | } 65 | 66 | if wrapper.Endtag == "endif" { 67 | break 68 | } 69 | } 70 | 71 | return ifNode, nil 72 | } 73 | 74 | func init() { 75 | RegisterTag("if", tagIfParser) 76 | } 77 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/tags_ifequal.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | type tagIfEqualNode struct { 4 | var1, var2 IEvaluator 5 | thenWrapper *NodeWrapper 6 | elseWrapper *NodeWrapper 7 | } 8 | 9 | func (node *tagIfEqualNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 10 | r1, err := node.var1.Evaluate(ctx) 11 | if err != nil { 12 | return err 13 | } 14 | r2, err := node.var2.Evaluate(ctx) 15 | if err != nil { 16 | return err 17 | } 18 | 19 | result := r1.EqualValueTo(r2) 20 | 21 | if result { 22 | return node.thenWrapper.Execute(ctx, writer) 23 | } 24 | if node.elseWrapper != nil { 25 | return node.elseWrapper.Execute(ctx, writer) 26 | } 27 | return nil 28 | } 29 | 30 | func tagIfEqualParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) { 31 | ifequalNode := &tagIfEqualNode{} 32 | 33 | // Parse two expressions 34 | var1, err := arguments.ParseExpression() 35 | if err != nil { 36 | return nil, err 37 | } 38 | var2, err := arguments.ParseExpression() 39 | if err != nil { 40 | return nil, err 41 | } 42 | ifequalNode.var1 = var1 43 | ifequalNode.var2 = var2 44 | 45 | if arguments.Remaining() > 0 { 46 | return nil, arguments.Error("ifequal only takes 2 arguments.", nil) 47 | } 48 | 49 | // Wrap then/else-blocks 50 | wrapper, endargs, err := doc.WrapUntilTag("else", "endifequal") 51 | if err != nil { 52 | return nil, err 53 | } 54 | ifequalNode.thenWrapper = wrapper 55 | 56 | if endargs.Count() > 0 { 57 | return nil, endargs.Error("Arguments not allowed here.", nil) 58 | } 59 | 60 | if wrapper.Endtag == "else" { 61 | // if there's an else in the if-statement, we need the else-Block as well 62 | wrapper, endargs, err = doc.WrapUntilTag("endifequal") 63 | if err != nil { 64 | return nil, err 65 | } 66 | ifequalNode.elseWrapper = wrapper 67 | 68 | if endargs.Count() > 0 { 69 | return nil, endargs.Error("Arguments not allowed here.", nil) 70 | } 71 | } 72 | 73 | return ifequalNode, nil 74 | } 75 | 76 | func init() { 77 | RegisterTag("ifequal", tagIfEqualParser) 78 | } 79 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/tags_ifnotequal.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | type tagIfNotEqualNode struct { 4 | var1, var2 IEvaluator 5 | thenWrapper *NodeWrapper 6 | elseWrapper *NodeWrapper 7 | } 8 | 9 | func (node *tagIfNotEqualNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 10 | r1, err := node.var1.Evaluate(ctx) 11 | if err != nil { 12 | return err 13 | } 14 | r2, err := node.var2.Evaluate(ctx) 15 | if err != nil { 16 | return err 17 | } 18 | 19 | result := !r1.EqualValueTo(r2) 20 | 21 | if result { 22 | return node.thenWrapper.Execute(ctx, writer) 23 | } 24 | if node.elseWrapper != nil { 25 | return node.elseWrapper.Execute(ctx, writer) 26 | } 27 | return nil 28 | } 29 | 30 | func tagIfNotEqualParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) { 31 | ifnotequalNode := &tagIfNotEqualNode{} 32 | 33 | // Parse two expressions 34 | var1, err := arguments.ParseExpression() 35 | if err != nil { 36 | return nil, err 37 | } 38 | var2, err := arguments.ParseExpression() 39 | if err != nil { 40 | return nil, err 41 | } 42 | ifnotequalNode.var1 = var1 43 | ifnotequalNode.var2 = var2 44 | 45 | if arguments.Remaining() > 0 { 46 | return nil, arguments.Error("ifequal only takes 2 arguments.", nil) 47 | } 48 | 49 | // Wrap then/else-blocks 50 | wrapper, endargs, err := doc.WrapUntilTag("else", "endifnotequal") 51 | if err != nil { 52 | return nil, err 53 | } 54 | ifnotequalNode.thenWrapper = wrapper 55 | 56 | if endargs.Count() > 0 { 57 | return nil, endargs.Error("Arguments not allowed here.", nil) 58 | } 59 | 60 | if wrapper.Endtag == "else" { 61 | // if there's an else in the if-statement, we need the else-Block as well 62 | wrapper, endargs, err = doc.WrapUntilTag("endifnotequal") 63 | if err != nil { 64 | return nil, err 65 | } 66 | ifnotequalNode.elseWrapper = wrapper 67 | 68 | if endargs.Count() > 0 { 69 | return nil, endargs.Error("Arguments not allowed here.", nil) 70 | } 71 | } 72 | 73 | return ifnotequalNode, nil 74 | } 75 | 76 | func init() { 77 | RegisterTag("ifnotequal", tagIfNotEqualParser) 78 | } 79 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/tags_import.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | import ( 4 | "fmt" 5 | ) 6 | 7 | type tagImportNode struct { 8 | position *Token 9 | filename string 10 | macros map[string]*tagMacroNode // alias/name -> macro instance 11 | } 12 | 13 | func (node *tagImportNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 14 | for name, macro := range node.macros { 15 | func(name string, macro *tagMacroNode) { 16 | ctx.Private[name] = func(args ...*Value) *Value { 17 | return macro.call(ctx, args...) 18 | } 19 | }(name, macro) 20 | } 21 | return nil 22 | } 23 | 24 | func tagImportParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) { 25 | importNode := &tagImportNode{ 26 | position: start, 27 | macros: make(map[string]*tagMacroNode), 28 | } 29 | 30 | filenameToken := arguments.MatchType(TokenString) 31 | if filenameToken == nil { 32 | return nil, arguments.Error("Import-tag needs a filename as string.", nil) 33 | } 34 | 35 | importNode.filename = doc.template.set.resolveFilename(doc.template, filenameToken.Val) 36 | 37 | if arguments.Remaining() == 0 { 38 | return nil, arguments.Error("You must at least specify one macro to import.", nil) 39 | } 40 | 41 | // Compile the given template 42 | tpl, err := doc.template.set.FromFile(importNode.filename) 43 | if err != nil { 44 | return nil, err.(*Error).updateFromTokenIfNeeded(doc.template, start) 45 | } 46 | 47 | for arguments.Remaining() > 0 { 48 | macroNameToken := arguments.MatchType(TokenIdentifier) 49 | if macroNameToken == nil { 50 | return nil, arguments.Error("Expected macro name (identifier).", nil) 51 | } 52 | 53 | asName := macroNameToken.Val 54 | if arguments.Match(TokenKeyword, "as") != nil { 55 | aliasToken := arguments.MatchType(TokenIdentifier) 56 | if aliasToken == nil { 57 | return nil, arguments.Error("Expected macro alias name (identifier).", nil) 58 | } 59 | asName = aliasToken.Val 60 | } 61 | 62 | macroInstance, has := tpl.exportedMacros[macroNameToken.Val] 63 | if !has { 64 | return nil, arguments.Error(fmt.Sprintf("Macro '%s' not found (or not exported) in '%s'.", macroNameToken.Val, 65 | importNode.filename), macroNameToken) 66 | } 67 | 68 | importNode.macros[asName] = macroInstance 69 | 70 | if arguments.Remaining() == 0 { 71 | break 72 | } 73 | 74 | if arguments.Match(TokenSymbol, ",") == nil { 75 | return nil, arguments.Error("Expected ','.", nil) 76 | } 77 | } 78 | 79 | return importNode, nil 80 | } 81 | 82 | func init() { 83 | RegisterTag("import", tagImportParser) 84 | } 85 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/tags_now.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | import ( 4 | "time" 5 | ) 6 | 7 | type tagNowNode struct { 8 | position *Token 9 | format string 10 | fake bool 11 | } 12 | 13 | func (node *tagNowNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 14 | var t time.Time 15 | if node.fake { 16 | t = time.Date(2014, time.February, 05, 18, 31, 45, 00, time.UTC) 17 | } else { 18 | t = time.Now() 19 | } 20 | 21 | writer.WriteString(t.Format(node.format)) 22 | 23 | return nil 24 | } 25 | 26 | func tagNowParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) { 27 | nowNode := &tagNowNode{ 28 | position: start, 29 | } 30 | 31 | formatToken := arguments.MatchType(TokenString) 32 | if formatToken == nil { 33 | return nil, arguments.Error("Expected a format string.", nil) 34 | } 35 | nowNode.format = formatToken.Val 36 | 37 | if arguments.MatchOne(TokenIdentifier, "fake") != nil { 38 | nowNode.fake = true 39 | } 40 | 41 | if arguments.Remaining() > 0 { 42 | return nil, arguments.Error("Malformed now-tag arguments.", nil) 43 | } 44 | 45 | return nowNode, nil 46 | } 47 | 48 | func init() { 49 | RegisterTag("now", tagNowParser) 50 | } 51 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/tags_set.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | type tagSetNode struct { 4 | name string 5 | expression IEvaluator 6 | } 7 | 8 | func (node *tagSetNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 9 | // Evaluate expression 10 | value, err := node.expression.Evaluate(ctx) 11 | if err != nil { 12 | return err 13 | } 14 | 15 | ctx.Private[node.name] = value 16 | return nil 17 | } 18 | 19 | func tagSetParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) { 20 | node := &tagSetNode{} 21 | 22 | // Parse variable name 23 | typeToken := arguments.MatchType(TokenIdentifier) 24 | if typeToken == nil { 25 | return nil, arguments.Error("Expected an identifier.", nil) 26 | } 27 | node.name = typeToken.Val 28 | 29 | if arguments.Match(TokenSymbol, "=") == nil { 30 | return nil, arguments.Error("Expected '='.", nil) 31 | } 32 | 33 | // Variable expression 34 | keyExpression, err := arguments.ParseExpression() 35 | if err != nil { 36 | return nil, err 37 | } 38 | node.expression = keyExpression 39 | 40 | // Remaining arguments 41 | if arguments.Remaining() > 0 { 42 | return nil, arguments.Error("Malformed 'set'-tag arguments.", nil) 43 | } 44 | 45 | return node, nil 46 | } 47 | 48 | func init() { 49 | RegisterTag("set", tagSetParser) 50 | } 51 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/tags_spaceless.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | import ( 4 | "bytes" 5 | "regexp" 6 | ) 7 | 8 | type tagSpacelessNode struct { 9 | wrapper *NodeWrapper 10 | } 11 | 12 | var tagSpacelessRegexp = regexp.MustCompile(`(?U:(<.*>))([\t\n\v\f\r ]+)(?U:(<.*>))`) 13 | 14 | func (node *tagSpacelessNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 15 | b := bytes.NewBuffer(make([]byte, 0, 1024)) // 1 KiB 16 | 17 | err := node.wrapper.Execute(ctx, b) 18 | if err != nil { 19 | return err 20 | } 21 | 22 | s := b.String() 23 | // Repeat this recursively 24 | changed := true 25 | for changed { 26 | s2 := tagSpacelessRegexp.ReplaceAllString(s, "$1$3") 27 | changed = s != s2 28 | s = s2 29 | } 30 | 31 | writer.WriteString(s) 32 | 33 | return nil 34 | } 35 | 36 | func tagSpacelessParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) { 37 | spacelessNode := &tagSpacelessNode{} 38 | 39 | wrapper, _, err := doc.WrapUntilTag("endspaceless") 40 | if err != nil { 41 | return nil, err 42 | } 43 | spacelessNode.wrapper = wrapper 44 | 45 | if arguments.Remaining() > 0 { 46 | return nil, arguments.Error("Malformed spaceless-tag arguments.", nil) 47 | } 48 | 49 | return spacelessNode, nil 50 | } 51 | 52 | func init() { 53 | RegisterTag("spaceless", tagSpacelessParser) 54 | } 55 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/tags_ssi.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | import ( 4 | "io/ioutil" 5 | ) 6 | 7 | type tagSSINode struct { 8 | filename string 9 | content string 10 | template *Template 11 | } 12 | 13 | func (node *tagSSINode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 14 | if node.template != nil { 15 | // Execute the template within the current context 16 | includeCtx := make(Context) 17 | includeCtx.Update(ctx.Public) 18 | includeCtx.Update(ctx.Private) 19 | 20 | err := node.template.execute(includeCtx, writer) 21 | if err != nil { 22 | return err.(*Error) 23 | } 24 | } else { 25 | // Just print out the content 26 | writer.WriteString(node.content) 27 | } 28 | return nil 29 | } 30 | 31 | func tagSSIParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) { 32 | SSINode := &tagSSINode{} 33 | 34 | if fileToken := arguments.MatchType(TokenString); fileToken != nil { 35 | SSINode.filename = fileToken.Val 36 | 37 | if arguments.Match(TokenIdentifier, "parsed") != nil { 38 | // parsed 39 | temporaryTpl, err := doc.template.set.FromFile(doc.template.set.resolveFilename(doc.template, fileToken.Val)) 40 | if err != nil { 41 | return nil, err.(*Error).updateFromTokenIfNeeded(doc.template, fileToken) 42 | } 43 | SSINode.template = temporaryTpl 44 | } else { 45 | // plaintext 46 | buf, err := ioutil.ReadFile(doc.template.set.resolveFilename(doc.template, fileToken.Val)) 47 | if err != nil { 48 | return nil, (&Error{ 49 | Sender: "tag:ssi", 50 | ErrorMsg: err.Error(), 51 | }).updateFromTokenIfNeeded(doc.template, fileToken) 52 | } 53 | SSINode.content = string(buf) 54 | } 55 | } else { 56 | return nil, arguments.Error("First argument must be a string.", nil) 57 | } 58 | 59 | if arguments.Remaining() > 0 { 60 | return nil, arguments.Error("Malformed SSI-tag argument.", nil) 61 | } 62 | 63 | return SSINode, nil 64 | } 65 | 66 | func init() { 67 | RegisterTag("ssi", tagSSIParser) 68 | } 69 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/tags_templatetag.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | type tagTemplateTagNode struct { 4 | content string 5 | } 6 | 7 | var templateTagMapping = map[string]string{ 8 | "openblock": "{%", 9 | "closeblock": "%}", 10 | "openvariable": "{{", 11 | "closevariable": "}}", 12 | "openbrace": "{", 13 | "closebrace": "}", 14 | "opencomment": "{#", 15 | "closecomment": "#}", 16 | } 17 | 18 | func (node *tagTemplateTagNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 19 | writer.WriteString(node.content) 20 | return nil 21 | } 22 | 23 | func tagTemplateTagParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) { 24 | ttNode := &tagTemplateTagNode{} 25 | 26 | if argToken := arguments.MatchType(TokenIdentifier); argToken != nil { 27 | output, found := templateTagMapping[argToken.Val] 28 | if !found { 29 | return nil, arguments.Error("Argument not found", argToken) 30 | } 31 | ttNode.content = output 32 | } else { 33 | return nil, arguments.Error("Identifier expected.", nil) 34 | } 35 | 36 | if arguments.Remaining() > 0 { 37 | return nil, arguments.Error("Malformed templatetag-tag argument.", nil) 38 | } 39 | 40 | return ttNode, nil 41 | } 42 | 43 | func init() { 44 | RegisterTag("templatetag", tagTemplateTagParser) 45 | } 46 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/tags_widthratio.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | import ( 4 | "fmt" 5 | "math" 6 | ) 7 | 8 | type tagWidthratioNode struct { 9 | position *Token 10 | current, max IEvaluator 11 | width IEvaluator 12 | ctxName string 13 | } 14 | 15 | func (node *tagWidthratioNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 16 | current, err := node.current.Evaluate(ctx) 17 | if err != nil { 18 | return err 19 | } 20 | 21 | max, err := node.max.Evaluate(ctx) 22 | if err != nil { 23 | return err 24 | } 25 | 26 | width, err := node.width.Evaluate(ctx) 27 | if err != nil { 28 | return err 29 | } 30 | 31 | value := int(math.Ceil(current.Float()/max.Float()*width.Float() + 0.5)) 32 | 33 | if node.ctxName == "" { 34 | writer.WriteString(fmt.Sprintf("%d", value)) 35 | } else { 36 | ctx.Private[node.ctxName] = value 37 | } 38 | 39 | return nil 40 | } 41 | 42 | func tagWidthratioParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) { 43 | widthratioNode := &tagWidthratioNode{ 44 | position: start, 45 | } 46 | 47 | current, err := arguments.ParseExpression() 48 | if err != nil { 49 | return nil, err 50 | } 51 | widthratioNode.current = current 52 | 53 | max, err := arguments.ParseExpression() 54 | if err != nil { 55 | return nil, err 56 | } 57 | widthratioNode.max = max 58 | 59 | width, err := arguments.ParseExpression() 60 | if err != nil { 61 | return nil, err 62 | } 63 | widthratioNode.width = width 64 | 65 | if arguments.MatchOne(TokenKeyword, "as") != nil { 66 | // Name follows 67 | nameToken := arguments.MatchType(TokenIdentifier) 68 | if nameToken == nil { 69 | return nil, arguments.Error("Expected name (identifier).", nil) 70 | } 71 | widthratioNode.ctxName = nameToken.Val 72 | } 73 | 74 | if arguments.Remaining() > 0 { 75 | return nil, arguments.Error("Malformed widthratio-tag arguments.", nil) 76 | } 77 | 78 | return widthratioNode, nil 79 | } 80 | 81 | func init() { 82 | RegisterTag("widthratio", tagWidthratioParser) 83 | } 84 | -------------------------------------------------------------------------------- /vendor/github.com/flosch/pongo2/tags_with.go: -------------------------------------------------------------------------------- 1 | package pongo2 2 | 3 | type tagWithNode struct { 4 | withPairs map[string]IEvaluator 5 | wrapper *NodeWrapper 6 | } 7 | 8 | func (node *tagWithNode) Execute(ctx *ExecutionContext, writer TemplateWriter) *Error { 9 | //new context for block 10 | withctx := NewChildExecutionContext(ctx) 11 | 12 | // Put all custom with-pairs into the context 13 | for key, value := range node.withPairs { 14 | val, err := value.Evaluate(ctx) 15 | if err != nil { 16 | return err 17 | } 18 | withctx.Private[key] = val 19 | } 20 | 21 | return node.wrapper.Execute(withctx, writer) 22 | } 23 | 24 | func tagWithParser(doc *Parser, start *Token, arguments *Parser) (INodeTag, *Error) { 25 | withNode := &tagWithNode{ 26 | withPairs: make(map[string]IEvaluator), 27 | } 28 | 29 | if arguments.Count() == 0 { 30 | return nil, arguments.Error("Tag 'with' requires at least one argument.", nil) 31 | } 32 | 33 | wrapper, endargs, err := doc.WrapUntilTag("endwith") 34 | if err != nil { 35 | return nil, err 36 | } 37 | withNode.wrapper = wrapper 38 | 39 | if endargs.Count() > 0 { 40 | return nil, endargs.Error("Arguments not allowed here.", nil) 41 | } 42 | 43 | // Scan through all arguments to see which style the user uses (old or new style). 44 | // If we find any "as" keyword we will enforce old style; otherwise we will use new style. 45 | oldStyle := false // by default we're using the new_style 46 | for i := 0; i < arguments.Count(); i++ { 47 | if arguments.PeekN(i, TokenKeyword, "as") != nil { 48 | oldStyle = true 49 | break 50 | } 51 | } 52 | 53 | for arguments.Remaining() > 0 { 54 | if oldStyle { 55 | valueExpr, err := arguments.ParseExpression() 56 | if err != nil { 57 | return nil, err 58 | } 59 | if arguments.Match(TokenKeyword, "as") == nil { 60 | return nil, arguments.Error("Expected 'as' keyword.", nil) 61 | } 62 | keyToken := arguments.MatchType(TokenIdentifier) 63 | if keyToken == nil { 64 | return nil, arguments.Error("Expected an identifier", nil) 65 | } 66 | withNode.withPairs[keyToken.Val] = valueExpr 67 | } else { 68 | keyToken := arguments.MatchType(TokenIdentifier) 69 | if keyToken == nil { 70 | return nil, arguments.Error("Expected an identifier", nil) 71 | } 72 | if arguments.Match(TokenSymbol, "=") == nil { 73 | return nil, arguments.Error("Expected '='.", nil) 74 | } 75 | valueExpr, err := arguments.ParseExpression() 76 | if err != nil { 77 | return nil, err 78 | } 79 | withNode.withPairs[keyToken.Val] = valueExpr 80 | } 81 | } 82 | 83 | return withNode, nil 84 | } 85 | 86 | func init() { 87 | RegisterTag("with", tagWithParser) 88 | } 89 | -------------------------------------------------------------------------------- /vendor/github.com/flynn/go-shlex/Makefile: -------------------------------------------------------------------------------- 1 | # Copyright 2011 Google Inc. All Rights Reserved. 2 | # 3 | # Licensed under the Apache License, Version 2.0 (the "License"); 4 | # you may not use this file except in compliance with the License. 5 | # You may obtain a copy of the License at 6 | # 7 | # http://www.apache.org/licenses/LICENSE-2.0 8 | # 9 | # Unless required by applicable law or agreed to in writing, software 10 | # distributed under the License is distributed on an "AS IS" BASIS, 11 | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 | # See the License for the specific language governing permissions and 13 | # limitations under the License. 14 | 15 | include $(GOROOT)/src/Make.inc 16 | 17 | TARG=shlex 18 | GOFILES=\ 19 | shlex.go\ 20 | 21 | include $(GOROOT)/src/Make.pkg 22 | -------------------------------------------------------------------------------- /vendor/github.com/flynn/go-shlex/README.md: -------------------------------------------------------------------------------- 1 | go-shlex is a simple lexer for go that supports shell-style quoting, 2 | commenting, and escaping. 3 | -------------------------------------------------------------------------------- /vendor/github.com/kr/fs/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012 The Go Authors. 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 | -------------------------------------------------------------------------------- /vendor/github.com/kr/fs/Readme: -------------------------------------------------------------------------------- 1 | Filesystem Package 2 | 3 | http://godoc.org/github.com/kr/fs 4 | -------------------------------------------------------------------------------- /vendor/github.com/kr/fs/filesystem.go: -------------------------------------------------------------------------------- 1 | package fs 2 | 3 | import ( 4 | "io/ioutil" 5 | "os" 6 | "path/filepath" 7 | ) 8 | 9 | // FileSystem defines the methods of an abstract filesystem. 10 | type FileSystem interface { 11 | 12 | // ReadDir reads the directory named by dirname and returns a 13 | // list of directory entries. 14 | ReadDir(dirname string) ([]os.FileInfo, error) 15 | 16 | // Lstat returns a FileInfo describing the named file. If the file is a 17 | // symbolic link, the returned FileInfo describes the symbolic link. Lstat 18 | // makes no attempt to follow the link. 19 | Lstat(name string) (os.FileInfo, error) 20 | 21 | // Join joins any number of path elements into a single path, adding a 22 | // separator if necessary. The result is Cleaned; in particular, all 23 | // empty strings are ignored. 24 | // 25 | // The separator is FileSystem specific. 26 | Join(elem ...string) string 27 | } 28 | 29 | // fs represents a FileSystem provided by the os package. 30 | type fs struct{} 31 | 32 | func (f *fs) ReadDir(dirname string) ([]os.FileInfo, error) { return ioutil.ReadDir(dirname) } 33 | 34 | func (f *fs) Lstat(name string) (os.FileInfo, error) { return os.Lstat(name) } 35 | 36 | func (f *fs) Join(elem ...string) string { return filepath.Join(elem...) } 37 | -------------------------------------------------------------------------------- /vendor/github.com/mgutz/ansi/.gitignore: -------------------------------------------------------------------------------- 1 | *.test 2 | -------------------------------------------------------------------------------- /vendor/github.com/mgutz/ansi/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | Copyright (c) 2013 Mario L. Gutierrez 3 | 4 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 5 | 6 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 7 | 8 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 9 | 10 | -------------------------------------------------------------------------------- /vendor/github.com/mgutz/ansi/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package ansi is a small, fast library to create ANSI colored strings and codes. 3 | 4 | Installation 5 | 6 | # this installs the color viewer and the package 7 | go get -u github.com/mgutz/ansi/cmd/ansi-mgutz 8 | 9 | Example 10 | 11 | // colorize a string, SLOW 12 | msg := ansi.Color("foo", "red+b:white") 13 | 14 | // create a closure to avoid recalculating ANSI code compilation 15 | phosphorize := ansi.ColorFunc("green+h:black") 16 | msg = phosphorize("Bring back the 80s!") 17 | msg2 := phospohorize("Look, I'm a CRT!") 18 | 19 | // cache escape codes and build strings manually 20 | lime := ansi.ColorCode("green+h:black") 21 | reset := ansi.ColorCode("reset") 22 | 23 | fmt.Println(lime, "Bring back the 80s!", reset) 24 | 25 | Other examples 26 | 27 | Color(s, "red") // red 28 | Color(s, "red+b") // red bold 29 | Color(s, "red+B") // red blinking 30 | Color(s, "red+u") // red underline 31 | Color(s, "red+bh") // red bold bright 32 | Color(s, "red:white") // red on white 33 | Color(s, "red+b:white+h") // red bold on white bright 34 | Color(s, "red+B:white+h") // red blink on white bright 35 | 36 | To view color combinations, from terminal 37 | 38 | ansi-mgutz 39 | 40 | Style format 41 | 42 | "foregroundColor+attributes:backgroundColor+attributes" 43 | 44 | Colors 45 | 46 | black 47 | red 48 | green 49 | yellow 50 | blue 51 | magenta 52 | cyan 53 | white 54 | 55 | Attributes 56 | 57 | b = bold foreground 58 | B = Blink foreground 59 | u = underline foreground 60 | h = high intensity (bright) foreground, background 61 | i = inverse 62 | 63 | Wikipedia ANSI escape codes [Colors](http://en.wikipedia.org/wiki/ANSI_escape_code#Colors) 64 | */ 65 | package ansi 66 | -------------------------------------------------------------------------------- /vendor/github.com/mgutz/ansi/print.go: -------------------------------------------------------------------------------- 1 | package ansi 2 | 3 | // PrintStyles prints all style combinations to the terminal. 4 | func PrintStyles() { 5 | oldPlain := plain 6 | plain = false 7 | 8 | bgColors := []string{ 9 | "", 10 | ":black", 11 | ":red", 12 | ":green", 13 | ":yellow", 14 | ":blue", 15 | ":magenta", 16 | ":cyan", 17 | ":white", 18 | } 19 | for fg := range Colors { 20 | for _, bg := range bgColors { 21 | println(padColor(fg, []string{"" + bg, "+b" + bg, "+bh" + bg, "+u" + bg})) 22 | println(padColor(fg, []string{"+uh" + bg, "+B" + bg, "+Bb" + bg /* backgrounds */, "" + bg + "+h"})) 23 | println(padColor(fg, []string{"+b" + bg + "+h", "+bh" + bg + "+h", "+u" + bg + "+h", "+uh" + bg + "+h"})) 24 | } 25 | } 26 | plain = oldPlain 27 | } 28 | 29 | func pad(s string, length int) string { 30 | for len(s) < length { 31 | s += " " 32 | } 33 | return s 34 | } 35 | 36 | func padColor(s string, styles []string) string { 37 | buffer := "" 38 | for _, style := range styles { 39 | buffer += Color(pad(s+style, 20), s+style) 40 | } 41 | return buffer 42 | } 43 | -------------------------------------------------------------------------------- /vendor/github.com/pborman/uuid/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | Paul Borman 2 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /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/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/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 dervied 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/pborman/uuid/json.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 "errors" 8 | 9 | func (u UUID) MarshalJSON() ([]byte, error) { 10 | if len(u) == 0 { 11 | return []byte(`""`), nil 12 | } 13 | return []byte(`"` + u.String() + `"`), nil 14 | } 15 | 16 | func (u *UUID) UnmarshalJSON(data []byte) error { 17 | if len(data) == 0 || string(data) == `""` { 18 | return nil 19 | } 20 | if len(data) < 2 || data[0] != '"' || data[len(data)-1] != '"' { 21 | return errors.New("invalid UUID format") 22 | } 23 | data = data[1 : len(data)-1] 24 | uu := Parse(string(data)) 25 | if uu == nil { 26 | return errors.New("invalid UUID format") 27 | } 28 | *u = uu 29 | return nil 30 | } 31 | -------------------------------------------------------------------------------- /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 | "errors" 9 | "fmt" 10 | ) 11 | 12 | // Scan implements sql.Scanner so UUIDs can be read from databases transparently 13 | // Currently, database types that map to string and []byte are supported. Please 14 | // consult database-specific driver documentation for matching types. 15 | func (uuid *UUID) Scan(src interface{}) error { 16 | switch src.(type) { 17 | case string: 18 | // see uuid.Parse for required string format 19 | parsed := Parse(src.(string)) 20 | 21 | if parsed == nil { 22 | return errors.New("Scan: invalid UUID format") 23 | } 24 | 25 | *uuid = parsed 26 | case []byte: 27 | // assumes a simple slice of bytes, just check validity and store 28 | u := UUID(src.([]byte)) 29 | 30 | if u.Variant() == Invalid { 31 | return errors.New("Scan: invalid UUID format") 32 | } 33 | 34 | *uuid = u 35 | default: 36 | return fmt.Errorf("Scan: unable to scan type %T into UUID", src) 37 | } 38 | 39 | return nil 40 | } 41 | -------------------------------------------------------------------------------- /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 = []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/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 | -------------------------------------------------------------------------------- /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/pkg/sftp/.gitignore: -------------------------------------------------------------------------------- 1 | .*.swo 2 | .*.swp 3 | 4 | server_standalone/server_standalone 5 | 6 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/sftp/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | Dave Cheney 2 | Saulius Gurklys 3 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/sftp/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Dave Cheney 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 5 | 6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 8 | 9 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 10 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/sftp/README.md: -------------------------------------------------------------------------------- 1 | sftp 2 | ---- 3 | 4 | The `sftp` package provides support for file system operations on remote ssh servers using the SFTP subsystem. 5 | 6 | [![wercker status](https://app.wercker.com/status/7d3e9b916954ac3a7ed15a457938bac4/s/master "wercker status")](https://app.wercker.com/project/bykey/7d3e9b916954ac3a7ed15a457938bac4) 7 | 8 | usage and examples 9 | ------------------ 10 | 11 | See [godoc.org/github.com/pkg/sftp](http://godoc.org/github.com/pkg/sftp) for examples and usage. 12 | 13 | The basic operation of the package mirrors the facilities of the [os](http://golang.org/pkg/os) package. 14 | 15 | The Walker interface for directory traversal is heavily inspired by Keith Rarick's [fs](http://godoc.org/github.com/kr/fs) package. 16 | 17 | roadmap 18 | ------- 19 | 20 | * Currently all traffic with the server is serialized, this can be improved by allowing overlapping requests/responses. 21 | * There is way too much duplication in the Client methods. If there was an unmarshal(interface{}) method this would reduce a heap of the duplication. 22 | * Implement integration tests by talking directly to a real opensftp-server process. This shouldn't be too difficult to implement with a small refactoring to the sftp.NewClient method. These tests should be gated on an -sftp.integration test flag. _in progress_ 23 | 24 | contributing 25 | ------------ 26 | 27 | Features, Issues, and Pull Requests are always welcome. 28 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/sftp/attrs_stubs.go: -------------------------------------------------------------------------------- 1 | // +build !cgo,!plan9 windows android 2 | 3 | package sftp 4 | 5 | import ( 6 | "os" 7 | ) 8 | 9 | func fileStatFromInfoOs(fi os.FileInfo, flags *uint32, fileStat *FileStat) { 10 | // todo 11 | } 12 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/sftp/attrs_unix.go: -------------------------------------------------------------------------------- 1 | // +build darwin dragonfly freebsd !android,linux netbsd openbsd solaris 2 | // +build cgo 3 | 4 | package sftp 5 | 6 | import ( 7 | "os" 8 | "syscall" 9 | ) 10 | 11 | func fileStatFromInfoOs(fi os.FileInfo, flags *uint32, fileStat *FileStat) { 12 | if statt, ok := fi.Sys().(*syscall.Stat_t); ok { 13 | *flags |= ssh_FILEXFER_ATTR_UIDGID 14 | fileStat.Uid = statt.Uid 15 | fileStat.Gid = statt.Gid 16 | } 17 | } 18 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/sftp/debug.go: -------------------------------------------------------------------------------- 1 | // +build debug 2 | 3 | package sftp 4 | 5 | import "log" 6 | 7 | func debug(fmt string, args ...interface{}) { 8 | log.Printf(fmt, args...) 9 | } 10 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/sftp/release.go: -------------------------------------------------------------------------------- 1 | // +build !debug 2 | 3 | package sftp 4 | 5 | func debug(fmt string, args ...interface{}) {} 6 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/sftp/server_stubs.go: -------------------------------------------------------------------------------- 1 | // +build !cgo,!plan9 windows android 2 | 3 | package sftp 4 | 5 | import ( 6 | "os" 7 | "path" 8 | ) 9 | 10 | func runLs(dirname string, dirent os.FileInfo) string { 11 | return path.Join(dirname, dirent.Name()) 12 | } 13 | -------------------------------------------------------------------------------- /vendor/github.com/pkg/sftp/wercker.yml: -------------------------------------------------------------------------------- 1 | box: wercker/golang 2 | # Build definition 3 | build: 4 | # The steps that will be executed on build 5 | steps: 6 | # Sets the go workspace and places you package 7 | # at the right place in the workspace tree 8 | - setup-go-workspace 9 | 10 | # Gets the dependencies 11 | - script: 12 | name: go get 13 | code: | 14 | cd $WERCKER_SOURCE_DIR 15 | go version 16 | go get -t ./... 17 | 18 | # Build the project 19 | - script: 20 | name: go build 21 | code: | 22 | go build ./... 23 | 24 | # Test the project 25 | - script: 26 | name: go test 27 | code: | 28 | go test ./... 29 | 30 | - script: 31 | name: go test -integration 32 | cost: | 33 | go test -intergration ./... 34 | 35 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/AUTHORS: -------------------------------------------------------------------------------- 1 | # This source code refers to The Go Authors for copyright purposes. 2 | # The master list of authors is in the main Go distribution, 3 | # visible at http://tip.golang.org/AUTHORS. 4 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/CONTRIBUTORS: -------------------------------------------------------------------------------- 1 | # This source code was written by the Go contributors. 2 | # The master list of contributors is in the main Go distribution, 3 | # visible at http://tip.golang.org/CONTRIBUTORS. 4 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2009 The Go Authors. 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 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/PATENTS: -------------------------------------------------------------------------------- 1 | Additional IP Rights Grant (Patents) 2 | 3 | "This implementation" means the copyrightable works distributed by 4 | Google as part of the Go project. 5 | 6 | Google hereby grants to You a perpetual, worldwide, non-exclusive, 7 | no-charge, royalty-free, irrevocable (except as stated in this section) 8 | patent license to make, have made, use, offer to sell, sell, import, 9 | transfer and otherwise run, modify and propagate the contents of this 10 | implementation of Go, where such license applies only to those patent 11 | claims, both currently owned or controlled by Google and acquired in 12 | the future, licensable by Google that are necessarily infringed by this 13 | implementation of Go. This grant does not include claims that would be 14 | infringed only as a consequence of further modification of this 15 | implementation. If you or your agent or exclusive licensee institute or 16 | order or agree to the institution of patent litigation against any 17 | entity (including a cross-claim or counterclaim in a lawsuit) alleging 18 | that this implementation of Go or any code incorporated within this 19 | implementation of Go constitutes direct or contributory patent 20 | infringement, or inducement of patent infringement, then any patent 21 | rights granted to you under this License for this implementation of Go 22 | shall terminate as of the date such litigation is filed. 23 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/curve25519/const_amd64.s: -------------------------------------------------------------------------------- 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 | // This code was translated into a form compatible with 6a from the public 6 | // domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html 7 | 8 | // +build amd64,!gccgo,!appengine 9 | 10 | DATA ·REDMASK51(SB)/8, $0x0007FFFFFFFFFFFF 11 | GLOBL ·REDMASK51(SB), 8, $8 12 | 13 | DATA ·_121666_213(SB)/8, $996687872 14 | GLOBL ·_121666_213(SB), 8, $8 15 | 16 | DATA ·_2P0(SB)/8, $0xFFFFFFFFFFFDA 17 | GLOBL ·_2P0(SB), 8, $8 18 | 19 | DATA ·_2P1234(SB)/8, $0xFFFFFFFFFFFFE 20 | GLOBL ·_2P1234(SB), 8, $8 21 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/curve25519/cswap_amd64.s: -------------------------------------------------------------------------------- 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 | // This code was translated into a form compatible with 6a from the public 6 | // domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html 7 | 8 | // +build amd64,!gccgo,!appengine 9 | 10 | // func cswap(inout *[5]uint64, v uint64) 11 | TEXT ·cswap(SB),7,$0 12 | MOVQ inout+0(FP),DI 13 | MOVQ v+8(FP),SI 14 | 15 | CMPQ SI,$1 16 | MOVQ 0(DI),SI 17 | MOVQ 80(DI),DX 18 | MOVQ 8(DI),CX 19 | MOVQ 88(DI),R8 20 | MOVQ SI,R9 21 | CMOVQEQ DX,SI 22 | CMOVQEQ R9,DX 23 | MOVQ CX,R9 24 | CMOVQEQ R8,CX 25 | CMOVQEQ R9,R8 26 | MOVQ SI,0(DI) 27 | MOVQ DX,80(DI) 28 | MOVQ CX,8(DI) 29 | MOVQ R8,88(DI) 30 | MOVQ 16(DI),SI 31 | MOVQ 96(DI),DX 32 | MOVQ 24(DI),CX 33 | MOVQ 104(DI),R8 34 | MOVQ SI,R9 35 | CMOVQEQ DX,SI 36 | CMOVQEQ R9,DX 37 | MOVQ CX,R9 38 | CMOVQEQ R8,CX 39 | CMOVQEQ R9,R8 40 | MOVQ SI,16(DI) 41 | MOVQ DX,96(DI) 42 | MOVQ CX,24(DI) 43 | MOVQ R8,104(DI) 44 | MOVQ 32(DI),SI 45 | MOVQ 112(DI),DX 46 | MOVQ 40(DI),CX 47 | MOVQ 120(DI),R8 48 | MOVQ SI,R9 49 | CMOVQEQ DX,SI 50 | CMOVQEQ R9,DX 51 | MOVQ CX,R9 52 | CMOVQEQ R8,CX 53 | CMOVQEQ R9,R8 54 | MOVQ SI,32(DI) 55 | MOVQ DX,112(DI) 56 | MOVQ CX,40(DI) 57 | MOVQ R8,120(DI) 58 | MOVQ 48(DI),SI 59 | MOVQ 128(DI),DX 60 | MOVQ 56(DI),CX 61 | MOVQ 136(DI),R8 62 | MOVQ SI,R9 63 | CMOVQEQ DX,SI 64 | CMOVQEQ R9,DX 65 | MOVQ CX,R9 66 | CMOVQEQ R8,CX 67 | CMOVQEQ R9,R8 68 | MOVQ SI,48(DI) 69 | MOVQ DX,128(DI) 70 | MOVQ CX,56(DI) 71 | MOVQ R8,136(DI) 72 | MOVQ 64(DI),SI 73 | MOVQ 144(DI),DX 74 | MOVQ 72(DI),CX 75 | MOVQ 152(DI),R8 76 | MOVQ SI,R9 77 | CMOVQEQ DX,SI 78 | CMOVQEQ R9,DX 79 | MOVQ CX,R9 80 | CMOVQEQ R8,CX 81 | CMOVQEQ R9,R8 82 | MOVQ SI,64(DI) 83 | MOVQ DX,144(DI) 84 | MOVQ CX,72(DI) 85 | MOVQ R8,152(DI) 86 | MOVQ DI,AX 87 | MOVQ SI,DX 88 | RET 89 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/curve25519/doc.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 curve25519 provides an implementation of scalar multiplication on 6 | // the elliptic curve known as curve25519. See http://cr.yp.to/ecdh.html 7 | package curve25519 8 | 9 | // basePoint is the x coordinate of the generator of the curve. 10 | var basePoint = [32]byte{9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0} 11 | 12 | // ScalarMult sets dst to the product in*base where dst and base are the x 13 | // coordinates of group points and all values are in little-endian form. 14 | func ScalarMult(dst, in, base *[32]byte) { 15 | scalarMult(dst, in, base) 16 | } 17 | 18 | // ScalarBaseMult sets dst to the product in*base where dst and base are the x 19 | // coordinates of group points, base is the standard generator and all values 20 | // are in little-endian form. 21 | func ScalarBaseMult(dst, in *[32]byte) { 22 | ScalarMult(dst, in, &basePoint) 23 | } 24 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/curve25519/freeze_amd64.s: -------------------------------------------------------------------------------- 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 | // This code was translated into a form compatible with 6a from the public 6 | // domain sources in SUPERCOP: http://bench.cr.yp.to/supercop.html 7 | 8 | // +build amd64,!gccgo,!appengine 9 | 10 | // func freeze(inout *[5]uint64) 11 | TEXT ·freeze(SB),7,$96-8 12 | MOVQ inout+0(FP), DI 13 | 14 | MOVQ SP,R11 15 | MOVQ $31,CX 16 | NOTQ CX 17 | ANDQ CX,SP 18 | ADDQ $32,SP 19 | 20 | MOVQ R11,0(SP) 21 | MOVQ R12,8(SP) 22 | MOVQ R13,16(SP) 23 | MOVQ R14,24(SP) 24 | MOVQ R15,32(SP) 25 | MOVQ BX,40(SP) 26 | MOVQ BP,48(SP) 27 | MOVQ 0(DI),SI 28 | MOVQ 8(DI),DX 29 | MOVQ 16(DI),CX 30 | MOVQ 24(DI),R8 31 | MOVQ 32(DI),R9 32 | MOVQ ·REDMASK51(SB),AX 33 | MOVQ AX,R10 34 | SUBQ $18,R10 35 | MOVQ $3,R11 36 | REDUCELOOP: 37 | MOVQ SI,R12 38 | SHRQ $51,R12 39 | ANDQ AX,SI 40 | ADDQ R12,DX 41 | MOVQ DX,R12 42 | SHRQ $51,R12 43 | ANDQ AX,DX 44 | ADDQ R12,CX 45 | MOVQ CX,R12 46 | SHRQ $51,R12 47 | ANDQ AX,CX 48 | ADDQ R12,R8 49 | MOVQ R8,R12 50 | SHRQ $51,R12 51 | ANDQ AX,R8 52 | ADDQ R12,R9 53 | MOVQ R9,R12 54 | SHRQ $51,R12 55 | ANDQ AX,R9 56 | IMUL3Q $19,R12,R12 57 | ADDQ R12,SI 58 | SUBQ $1,R11 59 | JA REDUCELOOP 60 | MOVQ $1,R12 61 | CMPQ R10,SI 62 | CMOVQLT R11,R12 63 | CMPQ AX,DX 64 | CMOVQNE R11,R12 65 | CMPQ AX,CX 66 | CMOVQNE R11,R12 67 | CMPQ AX,R8 68 | CMOVQNE R11,R12 69 | CMPQ AX,R9 70 | CMOVQNE R11,R12 71 | NEGQ R12 72 | ANDQ R12,AX 73 | ANDQ R12,R10 74 | SUBQ R10,SI 75 | SUBQ AX,DX 76 | SUBQ AX,CX 77 | SUBQ AX,R8 78 | SUBQ AX,R9 79 | MOVQ SI,0(DI) 80 | MOVQ DX,8(DI) 81 | MOVQ CX,16(DI) 82 | MOVQ R8,24(DI) 83 | MOVQ R9,32(DI) 84 | MOVQ 0(SP),R11 85 | MOVQ 8(SP),R12 86 | MOVQ 16(SP),R13 87 | MOVQ 24(SP),R14 88 | MOVQ 32(SP),R15 89 | MOVQ 40(SP),BX 90 | MOVQ 48(SP),BP 91 | MOVQ R11,SP 92 | MOVQ DI,AX 93 | MOVQ SI,DX 94 | RET 95 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/ssh/buffer.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 ssh 6 | 7 | import ( 8 | "io" 9 | "sync" 10 | ) 11 | 12 | // buffer provides a linked list buffer for data exchange 13 | // between producer and consumer. Theoretically the buffer is 14 | // of unlimited capacity as it does no allocation of its own. 15 | type buffer struct { 16 | // protects concurrent access to head, tail and closed 17 | *sync.Cond 18 | 19 | head *element // the buffer that will be read first 20 | tail *element // the buffer that will be read last 21 | 22 | closed bool 23 | } 24 | 25 | // An element represents a single link in a linked list. 26 | type element struct { 27 | buf []byte 28 | next *element 29 | } 30 | 31 | // newBuffer returns an empty buffer that is not closed. 32 | func newBuffer() *buffer { 33 | e := new(element) 34 | b := &buffer{ 35 | Cond: newCond(), 36 | head: e, 37 | tail: e, 38 | } 39 | return b 40 | } 41 | 42 | // write makes buf available for Read to receive. 43 | // buf must not be modified after the call to write. 44 | func (b *buffer) write(buf []byte) { 45 | b.Cond.L.Lock() 46 | e := &element{buf: buf} 47 | b.tail.next = e 48 | b.tail = e 49 | b.Cond.Signal() 50 | b.Cond.L.Unlock() 51 | } 52 | 53 | // eof closes the buffer. Reads from the buffer once all 54 | // the data has been consumed will receive os.EOF. 55 | func (b *buffer) eof() error { 56 | b.Cond.L.Lock() 57 | b.closed = true 58 | b.Cond.Signal() 59 | b.Cond.L.Unlock() 60 | return nil 61 | } 62 | 63 | // Read reads data from the internal buffer in buf. Reads will block 64 | // if no data is available, or until the buffer is closed. 65 | func (b *buffer) Read(buf []byte) (n int, err error) { 66 | b.Cond.L.Lock() 67 | defer b.Cond.L.Unlock() 68 | 69 | for len(buf) > 0 { 70 | // if there is data in b.head, copy it 71 | if len(b.head.buf) > 0 { 72 | r := copy(buf, b.head.buf) 73 | buf, b.head.buf = buf[r:], b.head.buf[r:] 74 | n += r 75 | continue 76 | } 77 | // if there is a next buffer, make it the head 78 | if len(b.head.buf) == 0 && b.head != b.tail { 79 | b.head = b.head.next 80 | continue 81 | } 82 | 83 | // if at least one byte has been copied, return 84 | if n > 0 { 85 | break 86 | } 87 | 88 | // if nothing was read, and there is nothing outstanding 89 | // check to see if the buffer is closed. 90 | if b.closed { 91 | err = io.EOF 92 | break 93 | } 94 | // out of buffers, wait for producer 95 | b.Cond.Wait() 96 | } 97 | return 98 | } 99 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/ssh/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 ssh implements an SSH client and server. 7 | 8 | SSH is a transport security protocol, an authentication protocol and a 9 | family of application protocols. The most typical application level 10 | protocol is a remote shell and this is specifically implemented. However, 11 | the multiplexed nature of SSH is exposed to users that wish to support 12 | others. 13 | 14 | References: 15 | [PROTOCOL.certkeys]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=HEAD 16 | [SSH-PARAMETERS]: http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1 17 | */ 18 | package ssh 19 | -------------------------------------------------------------------------------- /vendor/golang.org/x/crypto/ssh/mac.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 ssh 6 | 7 | // Message authentication support 8 | 9 | import ( 10 | "crypto/hmac" 11 | "crypto/sha1" 12 | "crypto/sha256" 13 | "hash" 14 | ) 15 | 16 | type macMode struct { 17 | keySize int 18 | new func(key []byte) hash.Hash 19 | } 20 | 21 | // truncatingMAC wraps around a hash.Hash and truncates the output digest to 22 | // a given size. 23 | type truncatingMAC struct { 24 | length int 25 | hmac hash.Hash 26 | } 27 | 28 | func (t truncatingMAC) Write(data []byte) (int, error) { 29 | return t.hmac.Write(data) 30 | } 31 | 32 | func (t truncatingMAC) Sum(in []byte) []byte { 33 | out := t.hmac.Sum(in) 34 | return out[:len(in)+t.length] 35 | } 36 | 37 | func (t truncatingMAC) Reset() { 38 | t.hmac.Reset() 39 | } 40 | 41 | func (t truncatingMAC) Size() int { 42 | return t.length 43 | } 44 | 45 | func (t truncatingMAC) BlockSize() int { return t.hmac.BlockSize() } 46 | 47 | var macModes = map[string]*macMode{ 48 | "hmac-sha2-256": {32, func(key []byte) hash.Hash { 49 | return hmac.New(sha256.New, key) 50 | }}, 51 | "hmac-sha1": {20, func(key []byte) hash.Hash { 52 | return hmac.New(sha1.New, key) 53 | }}, 54 | "hmac-sha1-96": {20, func(key []byte) hash.Hash { 55 | return truncatingMAC{12, hmac.New(sha1.New, key)} 56 | }}, 57 | } 58 | -------------------------------------------------------------------------------- /vendor/gopkg.in/Sirupsen/logrus.v0/.gitignore: -------------------------------------------------------------------------------- 1 | logrus 2 | -------------------------------------------------------------------------------- /vendor/gopkg.in/Sirupsen/logrus.v0/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | go: 3 | - 1.2 4 | - 1.3 5 | - 1.4 6 | - tip 7 | install: 8 | - go get -t ./... 9 | -------------------------------------------------------------------------------- /vendor/gopkg.in/Sirupsen/logrus.v0/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.8.7 2 | 3 | * logrus/core: fix possible race (#216) 4 | * logrus/doc: small typo fixes and doc improvements 5 | 6 | 7 | # 0.8.6 8 | 9 | * hooks/raven: allow passing an initialized client 10 | 11 | # 0.8.5 12 | 13 | * logrus/core: revert #208 14 | 15 | # 0.8.4 16 | 17 | * formatter/text: fix data race (#218) 18 | 19 | # 0.8.3 20 | 21 | * logrus/core: fix entry log level (#208) 22 | * logrus/core: improve performance of text formatter by 40% 23 | * logrus/core: expose `LevelHooks` type 24 | * logrus/core: add support for DragonflyBSD and NetBSD 25 | * formatter/text: print structs more verbosely 26 | 27 | # 0.8.2 28 | 29 | * logrus: fix more Fatal family functions 30 | 31 | # 0.8.1 32 | 33 | * logrus: fix not exiting on `Fatalf` and `Fatalln` 34 | 35 | # 0.8.0 36 | 37 | * logrus: defaults to stderr instead of stdout 38 | * hooks/sentry: add special field for `*http.Request` 39 | * formatter/text: ignore Windows for colors 40 | 41 | # 0.7.3 42 | 43 | * formatter/\*: allow configuration of timestamp layout 44 | 45 | # 0.7.2 46 | 47 | * formatter/text: Add configuration option for time format (#158) 48 | -------------------------------------------------------------------------------- /vendor/gopkg.in/Sirupsen/logrus.v0/LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2014 Simon Eskildsen 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /vendor/gopkg.in/Sirupsen/logrus.v0/doc.go: -------------------------------------------------------------------------------- 1 | /* 2 | Package logrus is a structured logger for Go, completely API compatible with the standard library logger. 3 | 4 | 5 | The simplest way to use Logrus is simply the package-level exported logger: 6 | 7 | package main 8 | 9 | import ( 10 | log "github.com/Sirupsen/logrus" 11 | ) 12 | 13 | func main() { 14 | log.WithFields(log.Fields{ 15 | "animal": "walrus", 16 | "number": 1, 17 | "size": 10, 18 | }).Info("A walrus appears") 19 | } 20 | 21 | Output: 22 | time="2015-09-07T08:48:33Z" level=info msg="A walrus appears" animal=walrus number=1 size=10 23 | 24 | For a full guide visit https://github.com/Sirupsen/logrus 25 | */ 26 | package logrus 27 | -------------------------------------------------------------------------------- /vendor/gopkg.in/Sirupsen/logrus.v0/formatter.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import "time" 4 | 5 | const DefaultTimestampFormat = time.RFC3339 6 | 7 | // The Formatter interface is used to implement a custom Formatter. It takes an 8 | // `Entry`. It exposes all the fields, including the default ones: 9 | // 10 | // * `entry.Data["msg"]`. The message passed from Info, Warn, Error .. 11 | // * `entry.Data["time"]`. The timestamp. 12 | // * `entry.Data["level"]. The level the entry was logged at. 13 | // 14 | // Any additional fields added with `WithField` or `WithFields` are also in 15 | // `entry.Data`. Format is expected to return an array of bytes which are then 16 | // logged to `logger.Out`. 17 | type Formatter interface { 18 | Format(*Entry) ([]byte, error) 19 | } 20 | 21 | // This is to not silently overwrite `time`, `msg` and `level` fields when 22 | // dumping it. If this code wasn't there doing: 23 | // 24 | // logrus.WithField("level", 1).Info("hello") 25 | // 26 | // Would just silently drop the user provided level. Instead with this code 27 | // it'll logged as: 28 | // 29 | // {"level": "info", "fields.level": 1, "msg": "hello", "time": "..."} 30 | // 31 | // It's not exported because it's still using Data in an opinionated way. It's to 32 | // avoid code duplication between the two default formatters. 33 | func prefixFieldClashes(data Fields) { 34 | _, ok := data["time"] 35 | if ok { 36 | data["fields.time"] = data["time"] 37 | } 38 | 39 | _, ok = data["msg"] 40 | if ok { 41 | data["fields.msg"] = data["msg"] 42 | } 43 | 44 | _, ok = data["level"] 45 | if ok { 46 | data["fields.level"] = data["level"] 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /vendor/gopkg.in/Sirupsen/logrus.v0/hooks.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | // A hook to be fired when logging on the logging levels returned from 4 | // `Levels()` on your implementation of the interface. Note that this is not 5 | // fired in a goroutine or a channel with workers, you should handle such 6 | // functionality yourself if your call is non-blocking and you don't wish for 7 | // the logging calls for levels returned from `Levels()` to block. 8 | type Hook interface { 9 | Levels() []Level 10 | Fire(*Entry) error 11 | } 12 | 13 | // Internal type for storing the hooks on a logger instance. 14 | type LevelHooks map[Level][]Hook 15 | 16 | // Add a hook to an instance of logger. This is called with 17 | // `log.Hooks.Add(new(MyHook))` where `MyHook` implements the `Hook` interface. 18 | func (hooks LevelHooks) Add(hook Hook) { 19 | for _, level := range hook.Levels() { 20 | hooks[level] = append(hooks[level], hook) 21 | } 22 | } 23 | 24 | // Fire all the hooks for the passed level. Used by `entry.log` to fire 25 | // appropriate hooks for a log entry. 26 | func (hooks LevelHooks) Fire(level Level, entry *Entry) error { 27 | for _, hook := range hooks[level] { 28 | if err := hook.Fire(entry); err != nil { 29 | return err 30 | } 31 | } 32 | 33 | return nil 34 | } 35 | -------------------------------------------------------------------------------- /vendor/gopkg.in/Sirupsen/logrus.v0/json_formatter.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | ) 7 | 8 | type JSONFormatter struct { 9 | // TimestampFormat sets the format used for marshaling timestamps. 10 | TimestampFormat string 11 | } 12 | 13 | func (f *JSONFormatter) Format(entry *Entry) ([]byte, error) { 14 | data := make(Fields, len(entry.Data)+3) 15 | for k, v := range entry.Data { 16 | switch v := v.(type) { 17 | case error: 18 | // Otherwise errors are ignored by `encoding/json` 19 | // https://github.com/Sirupsen/logrus/issues/137 20 | data[k] = v.Error() 21 | default: 22 | data[k] = v 23 | } 24 | } 25 | prefixFieldClashes(data) 26 | 27 | timestampFormat := f.TimestampFormat 28 | if timestampFormat == "" { 29 | timestampFormat = DefaultTimestampFormat 30 | } 31 | 32 | data["time"] = entry.Time.Format(timestampFormat) 33 | data["msg"] = entry.Message 34 | data["level"] = entry.Level.String() 35 | 36 | serialized, err := json.Marshal(data) 37 | if err != nil { 38 | return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) 39 | } 40 | return append(serialized, '\n'), nil 41 | } 42 | -------------------------------------------------------------------------------- /vendor/gopkg.in/Sirupsen/logrus.v0/terminal_bsd.go: -------------------------------------------------------------------------------- 1 | // +build darwin freebsd openbsd netbsd dragonfly 2 | 3 | package logrus 4 | 5 | import "syscall" 6 | 7 | const ioctlReadTermios = syscall.TIOCGETA 8 | 9 | type Termios syscall.Termios 10 | -------------------------------------------------------------------------------- /vendor/gopkg.in/Sirupsen/logrus.v0/terminal_linux.go: -------------------------------------------------------------------------------- 1 | // Based on ssh/terminal: 2 | // Copyright 2013 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | package logrus 7 | 8 | import "syscall" 9 | 10 | const ioctlReadTermios = syscall.TCGETS 11 | 12 | type Termios syscall.Termios 13 | -------------------------------------------------------------------------------- /vendor/gopkg.in/Sirupsen/logrus.v0/terminal_notwindows.go: -------------------------------------------------------------------------------- 1 | // Based on ssh/terminal: 2 | // Copyright 2011 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | // +build linux darwin freebsd openbsd netbsd dragonfly 7 | 8 | package logrus 9 | 10 | import ( 11 | "syscall" 12 | "unsafe" 13 | ) 14 | 15 | // IsTerminal returns true if the given file descriptor is a terminal. 16 | func IsTerminal() bool { 17 | fd := syscall.Stdout 18 | var termios Termios 19 | _, _, err := syscall.Syscall6(syscall.SYS_IOCTL, uintptr(fd), ioctlReadTermios, uintptr(unsafe.Pointer(&termios)), 0, 0, 0) 20 | return err == 0 21 | } 22 | -------------------------------------------------------------------------------- /vendor/gopkg.in/Sirupsen/logrus.v0/terminal_windows.go: -------------------------------------------------------------------------------- 1 | // Based on ssh/terminal: 2 | // Copyright 2011 The Go Authors. All rights reserved. 3 | // Use of this source code is governed by a BSD-style 4 | // license that can be found in the LICENSE file. 5 | 6 | // +build windows 7 | 8 | package logrus 9 | 10 | import ( 11 | "syscall" 12 | "unsafe" 13 | ) 14 | 15 | var kernel32 = syscall.NewLazyDLL("kernel32.dll") 16 | 17 | var ( 18 | procGetConsoleMode = kernel32.NewProc("GetConsoleMode") 19 | ) 20 | 21 | // IsTerminal returns true if the given file descriptor is a terminal. 22 | func IsTerminal() bool { 23 | fd := syscall.Stdout 24 | var st uint32 25 | r, _, e := syscall.Syscall(procGetConsoleMode.Addr(), 2, uintptr(fd), uintptr(unsafe.Pointer(&st)), 0) 26 | return r != 0 && e == 0 27 | } 28 | -------------------------------------------------------------------------------- /vendor/gopkg.in/Sirupsen/logrus.v0/writer.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "bufio" 5 | "io" 6 | "runtime" 7 | ) 8 | 9 | func (logger *Logger) Writer() *io.PipeWriter { 10 | reader, writer := io.Pipe() 11 | 12 | go logger.writerScanner(reader) 13 | runtime.SetFinalizer(writer, writerFinalizer) 14 | 15 | return writer 16 | } 17 | 18 | func (logger *Logger) writerScanner(reader *io.PipeReader) { 19 | scanner := bufio.NewScanner(reader) 20 | for scanner.Scan() { 21 | logger.Print(scanner.Text()) 22 | } 23 | if err := scanner.Err(); err != nil { 24 | logger.Errorf("Error while reading from Writer: %s", err) 25 | } 26 | reader.Close() 27 | } 28 | 29 | func writerFinalizer(writer *io.PipeWriter) { 30 | writer.Close() 31 | } 32 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/LICENSE.libyaml: -------------------------------------------------------------------------------- 1 | The following files were ported to Go from C files of libyaml, and thus 2 | are still covered by their original copyright and license: 3 | 4 | apic.go 5 | emitterc.go 6 | parserc.go 7 | readerc.go 8 | scannerc.go 9 | writerc.go 10 | yamlh.go 11 | yamlprivateh.go 12 | 13 | Copyright (c) 2006 Kirill Simonov 14 | 15 | Permission is hereby granted, free of charge, to any person obtaining a copy of 16 | this software and associated documentation files (the "Software"), to deal in 17 | the Software without restriction, including without limitation the rights to 18 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies 19 | of the Software, and to permit persons to whom the Software is furnished to do 20 | so, subject to the following conditions: 21 | 22 | The above copyright notice and this permission notice shall be included in all 23 | copies or substantial portions of the Software. 24 | 25 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 26 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 27 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 28 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 29 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 30 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 31 | SOFTWARE. 32 | -------------------------------------------------------------------------------- /vendor/gopkg.in/yaml.v2/writerc.go: -------------------------------------------------------------------------------- 1 | package yaml 2 | 3 | // Set the writer error and return false. 4 | func yaml_emitter_set_writer_error(emitter *yaml_emitter_t, problem string) bool { 5 | emitter.error = yaml_WRITER_ERROR 6 | emitter.problem = problem 7 | return false 8 | } 9 | 10 | // Flush the output buffer. 11 | func yaml_emitter_flush(emitter *yaml_emitter_t) bool { 12 | if emitter.write_handler == nil { 13 | panic("write handler not set") 14 | } 15 | 16 | // Check if the buffer is empty. 17 | if emitter.buffer_pos == 0 { 18 | return true 19 | } 20 | 21 | // If the output encoding is UTF-8, we don't need to recode the buffer. 22 | if emitter.encoding == yaml_UTF8_ENCODING { 23 | if err := emitter.write_handler(emitter, emitter.buffer[:emitter.buffer_pos]); err != nil { 24 | return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) 25 | } 26 | emitter.buffer_pos = 0 27 | return true 28 | } 29 | 30 | // Recode the buffer into the raw buffer. 31 | var low, high int 32 | if emitter.encoding == yaml_UTF16LE_ENCODING { 33 | low, high = 0, 1 34 | } else { 35 | high, low = 1, 0 36 | } 37 | 38 | pos := 0 39 | for pos < emitter.buffer_pos { 40 | // See the "reader.c" code for more details on UTF-8 encoding. Note 41 | // that we assume that the buffer contains a valid UTF-8 sequence. 42 | 43 | // Read the next UTF-8 character. 44 | octet := emitter.buffer[pos] 45 | 46 | var w int 47 | var value rune 48 | switch { 49 | case octet&0x80 == 0x00: 50 | w, value = 1, rune(octet&0x7F) 51 | case octet&0xE0 == 0xC0: 52 | w, value = 2, rune(octet&0x1F) 53 | case octet&0xF0 == 0xE0: 54 | w, value = 3, rune(octet&0x0F) 55 | case octet&0xF8 == 0xF0: 56 | w, value = 4, rune(octet&0x07) 57 | } 58 | for k := 1; k < w; k++ { 59 | octet = emitter.buffer[pos+k] 60 | value = (value << 6) + (rune(octet) & 0x3F) 61 | } 62 | pos += w 63 | 64 | // Write the character. 65 | if value < 0x10000 { 66 | var b [2]byte 67 | b[high] = byte(value >> 8) 68 | b[low] = byte(value & 0xFF) 69 | emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1]) 70 | } else { 71 | // Write the character using a surrogate pair (check "reader.c"). 72 | var b [4]byte 73 | value -= 0x10000 74 | b[high] = byte(0xD8 + (value >> 18)) 75 | b[low] = byte((value >> 10) & 0xFF) 76 | b[high+2] = byte(0xDC + ((value >> 8) & 0xFF)) 77 | b[low+2] = byte(value & 0xFF) 78 | emitter.raw_buffer = append(emitter.raw_buffer, b[0], b[1], b[2], b[3]) 79 | } 80 | } 81 | 82 | // Write the raw buffer. 83 | if err := emitter.write_handler(emitter, emitter.raw_buffer); err != nil { 84 | return yaml_emitter_set_writer_error(emitter, "write error: "+err.Error()) 85 | } 86 | emitter.buffer_pos = 0 87 | emitter.raw_buffer = emitter.raw_buffer[:0] 88 | return true 89 | } 90 | --------------------------------------------------------------------------------