├── Godeps ├── _workspace │ ├── .gitignore │ └── src │ │ ├── github.com │ │ ├── Sirupsen │ │ │ └── logrus │ │ │ │ ├── .gitignore │ │ │ │ ├── .travis.yml │ │ │ │ ├── terminal_bsd.go │ │ │ │ ├── terminal_linux.go │ │ │ │ ├── hooks │ │ │ │ ├── syslog │ │ │ │ │ ├── README.md │ │ │ │ │ ├── syslog_test.go │ │ │ │ │ └── syslog.go │ │ │ │ ├── papertrail │ │ │ │ │ ├── papertrail_test.go │ │ │ │ │ ├── papertrail.go │ │ │ │ │ └── README.md │ │ │ │ ├── airbrake │ │ │ │ │ └── airbrake.go │ │ │ │ └── bugsnag │ │ │ │ │ └── bugsnag_test.go │ │ │ │ ├── terminal_notwindows.go │ │ │ │ ├── writer.go │ │ │ │ ├── terminal_windows.go │ │ │ │ ├── examples │ │ │ │ ├── hook │ │ │ │ │ └── hook.go │ │ │ │ └── basic │ │ │ │ │ └── basic.go │ │ │ │ ├── CHANGELOG.md │ │ │ │ ├── json_formatter.go │ │ │ │ ├── LICENSE │ │ │ │ ├── hooks.go │ │ │ │ ├── entry_test.go │ │ │ │ ├── formatters │ │ │ │ └── logstash │ │ │ │ │ ├── logstash_test.go │ │ │ │ │ └── logstash.go │ │ │ │ ├── formatter.go │ │ │ │ └── text_formatter_test.go │ │ ├── smartystreets │ │ │ ├── assertions │ │ │ │ ├── .gitignore │ │ │ │ ├── internal │ │ │ │ │ ├── oglemock │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ ├── createmock │ │ │ │ │ │ │ └── test_cases │ │ │ │ │ │ │ │ ├── golden.unknown_package │ │ │ │ │ │ │ │ ├── golden.unknown_interface │ │ │ │ │ │ │ │ ├── golden.no_package │ │ │ │ │ │ │ │ └── golden.no_interfaces │ │ │ │ │ │ ├── sample │ │ │ │ │ │ │ ├── README.markdown │ │ │ │ │ │ │ └── mock_io │ │ │ │ │ │ │ │ └── mock_io.go │ │ │ │ │ │ ├── generate │ │ │ │ │ │ │ └── test_cases │ │ │ │ │ │ │ │ ├── renamed_pkg │ │ │ │ │ │ │ │ └── renamed_pkg.go │ │ │ │ │ │ │ │ ├── complicated_pkg │ │ │ │ │ │ │ │ └── complicated_pkg.go │ │ │ │ │ │ │ │ └── golden.renamed_pkg.go │ │ │ │ │ │ ├── mock_object.go │ │ │ │ │ │ ├── error_reporter.go │ │ │ │ │ │ ├── action.go │ │ │ │ │ │ ├── do_all.go │ │ │ │ │ │ └── invoke.go │ │ │ │ │ ├── ogletest │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ ├── srcutil │ │ │ │ │ │ │ ├── docs.go │ │ │ │ │ │ │ └── methods.go │ │ │ │ │ │ ├── test_cases │ │ │ │ │ │ │ ├── golden.no_cases_test │ │ │ │ │ │ │ ├── golden.unexported_test │ │ │ │ │ │ │ ├── golden.stop_test │ │ │ │ │ │ │ ├── golden.run_twice_test │ │ │ │ │ │ │ ├── golden.passing_test │ │ │ │ │ │ │ ├── golden.filtered_test │ │ │ │ │ │ │ ├── golden.mock_test │ │ │ │ │ │ │ ├── no_cases.test.go │ │ │ │ │ │ │ ├── unexported.test.go │ │ │ │ │ │ │ ├── run_twice.test.go │ │ │ │ │ │ │ └── stop.test.go │ │ │ │ │ │ ├── assert_that.go │ │ │ │ │ │ └── doc.go │ │ │ │ │ ├── oglematchers │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ ├── any.go │ │ │ │ │ │ ├── has_same_type_as.go │ │ │ │ │ │ ├── transform_description.go │ │ │ │ │ │ ├── has_substr.go │ │ │ │ │ │ ├── greater_than.go │ │ │ │ │ │ ├── greater_or_equal.go │ │ │ │ │ │ ├── new_matcher.go │ │ │ │ │ │ ├── less_or_equal.go │ │ │ │ │ │ ├── not.go │ │ │ │ │ │ ├── any_test.go │ │ │ │ │ │ ├── error.go │ │ │ │ │ │ ├── contains.go │ │ │ │ │ │ ├── pointee.go │ │ │ │ │ │ └── matches_regexp.go │ │ │ │ │ ├── reqtrace │ │ │ │ │ │ ├── .gitignore │ │ │ │ │ │ └── README.md │ │ │ │ │ └── Makefile │ │ │ │ ├── .travis.yml │ │ │ │ ├── assertions.goconvey │ │ │ │ ├── filter.go │ │ │ │ ├── doc_test.go │ │ │ │ ├── serializer_test.go │ │ │ │ ├── LICENSE.md │ │ │ │ ├── serializer.go │ │ │ │ └── utilities_for_test.go │ │ │ └── goconvey │ │ │ │ └── convey │ │ │ │ ├── reporting │ │ │ │ ├── reporting.goconvey │ │ │ │ ├── doc.go │ │ │ │ ├── console.go │ │ │ │ ├── gotest.go │ │ │ │ ├── dot.go │ │ │ │ ├── dot_test.go │ │ │ │ ├── reporter.go │ │ │ │ ├── printer.go │ │ │ │ ├── problems_test.go │ │ │ │ ├── problems.go │ │ │ │ ├── gotest_test.go │ │ │ │ ├── story.go │ │ │ │ └── statistics.go │ │ │ │ ├── convey.goconvey │ │ │ │ ├── nilReporter.go │ │ │ │ ├── gotest │ │ │ │ └── utils.go │ │ │ │ ├── focused_execution_test.go │ │ │ │ └── init.go │ │ └── jtolds │ │ │ └── gls │ │ │ ├── gen_sym.go │ │ │ ├── id_pool.go │ │ │ └── LICENSE │ │ └── gopkg.in │ │ └── yaml.v2 │ │ ├── suite_test.go │ │ └── LICENSE.libyaml ├── Readme └── Godeps.json ├── logo.png ├── pkg ├── request │ ├── test_data │ │ └── some.json │ ├── response.go │ ├── client_mock.go │ ├── request.go │ ├── api.go │ ├── response_test.go │ ├── rest_test.go │ └── client.go ├── util │ ├── doc.go │ ├── mock │ │ └── io.go │ ├── strutil │ │ └── stringutil.go │ ├── testutil │ │ └── http.go │ ├── rand │ │ └── random.go │ └── arg_test.go ├── sys │ ├── ssh │ │ └── test_keys │ │ │ ├── test_rsa1 │ │ │ ├── test_ecdsa.pub │ │ │ ├── test_ecdsa │ │ │ ├── test_rsa.pub │ │ │ ├── test_dsa.pub │ │ │ ├── test_rsa1.pub │ │ │ ├── test_dsa │ │ │ └── test_rsa │ ├── nss │ │ ├── doc.go │ │ ├── service_mock.go │ │ ├── passwd_test.go │ │ ├── shadow.go │ │ ├── group_test.go │ │ ├── gshadow_test.go │ │ ├── gshadow.go │ │ ├── shadow_test.go │ │ ├── group.go │ │ ├── passwd.go │ │ └── service_test.go │ ├── initd │ │ ├── systemd │ │ │ ├── test_units │ │ │ │ ├── echo.socket │ │ │ │ └── echo@.service │ │ │ ├── unit.go │ │ │ └── systemd_test.go │ │ ├── manager.go │ │ └── manager_mock.go │ ├── firewall │ │ ├── manager.go │ │ └── iptables │ │ │ ├── iptables.go │ │ │ └── iptables_test.go │ ├── executor_test.go │ ├── script.go │ ├── executor_mock.go │ └── executor.go ├── file │ ├── file_system.go │ ├── directory.go │ └── directory_test.go ├── distro │ ├── doc.go │ ├── implementation_test.go │ └── centos.go ├── datasrc │ ├── provider │ │ ├── gce │ │ │ ├── test_metadata │ │ │ │ └── GCEv1_project.json │ │ │ └── gce.go │ │ ├── openstack │ │ │ ├── test_metadata │ │ │ │ └── 2012-08-10.json │ │ │ ├── metadata.go │ │ │ ├── openstack.go │ │ │ └── openstack_test.go │ │ ├── provider.go │ │ ├── ec2 │ │ │ ├── test_metadata │ │ │ │ └── 2009-04-04.json │ │ │ ├── metadata.go │ │ │ └── ec2_test.go │ │ └── configdrive │ │ │ └── configdrive.go │ ├── userdata │ │ ├── cloudconfig │ │ │ └── test_configs │ │ │ │ ├── sshkeys.yaml │ │ │ │ ├── runcmd.yaml │ │ │ │ └── write_files.yaml │ │ └── userdata.go │ ├── metadata │ │ └── metadata.go │ └── datasource_test.go ├── flog │ └── log.go └── context │ └── context_test.go ├── unit └── flamingo.service ├── .gitignore ├── .travis.yml ├── bin ├── test ├── install └── build ├── docs ├── README.md ├── providers.md └── config-drive.md └── flamingo.spec /Godeps/_workspace/.gitignore: -------------------------------------------------------------------------------- 1 | /pkg 2 | /bin 3 | -------------------------------------------------------------------------------- /logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmrts/flamingo/HEAD/logo.png -------------------------------------------------------------------------------- /pkg/request/test_data/some.json: -------------------------------------------------------------------------------- 1 | { 2 | "isJSON": true 3 | } 4 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/.gitignore: -------------------------------------------------------------------------------- 1 | logrus 2 | -------------------------------------------------------------------------------- /pkg/util/doc.go: -------------------------------------------------------------------------------- 1 | //Package utils contains utility functions. 2 | package util 3 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | Thumbs.db 3 | -------------------------------------------------------------------------------- /pkg/sys/ssh/test_keys/test_rsa1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tmrts/flamingo/HEAD/pkg/sys/ssh/test_keys/test_rsa1 -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/reporting.goconvey: -------------------------------------------------------------------------------- 1 | #ignore 2 | -timeout=1s 3 | -------------------------------------------------------------------------------- /pkg/sys/nss/doc.go: -------------------------------------------------------------------------------- 1 | // Package nss contains the gateway to query system Name Switch Service databases. 2 | package nss 3 | -------------------------------------------------------------------------------- /pkg/sys/initd/systemd/test_units/echo.socket: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=echo socket 3 | 4 | [Socket] 5 | ListenStream=2222 6 | Accept=yes 7 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglemock/.gitignore: -------------------------------------------------------------------------------- 1 | *.6 2 | 6.out 3 | _obj/ 4 | _test/ 5 | _testmain.go 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/ogletest/.gitignore: -------------------------------------------------------------------------------- 1 | *.6 2 | 6.out 3 | _obj/ 4 | _test/ 5 | _testmain.go 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglematchers/.gitignore: -------------------------------------------------------------------------------- 1 | *.6 2 | 6.out 3 | _obj/ 4 | _test/ 5 | _testmain.go 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglemock/createmock/test_cases/golden.unknown_package: -------------------------------------------------------------------------------- 1 | Unknown package: foo/bar 2 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglemock/createmock/test_cases/golden.unknown_interface: -------------------------------------------------------------------------------- 1 | Unknown interface: Frobnicator 2 | -------------------------------------------------------------------------------- /pkg/file/file_system.go: -------------------------------------------------------------------------------- 1 | package file 2 | 3 | type System interface { 4 | New(string, ...argument) error 5 | WriteTo(string, ...argument) error 6 | } 7 | -------------------------------------------------------------------------------- /pkg/sys/initd/systemd/test_units/echo@.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=echo service 3 | 4 | [Service] 5 | ExecStart=-/bin/cat 6 | StandardInput=socket 7 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglemock/createmock/test_cases/golden.no_package: -------------------------------------------------------------------------------- 1 | Usage: createmock [package] [interface ...] 2 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglemock/createmock/test_cases/golden.no_interfaces: -------------------------------------------------------------------------------- 1 | Usage: createmock [package] [interface ...] 2 | -------------------------------------------------------------------------------- /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 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/.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 | -------------------------------------------------------------------------------- /pkg/distro/doc.go: -------------------------------------------------------------------------------- 1 | // Package distro contains the implementations of 2 | // different operating systems to be used for 3 | // contextualizing cloud instances. 4 | package distro 5 | -------------------------------------------------------------------------------- /unit/flamingo.service: -------------------------------------------------------------------------------- 1 | [Unit] 2 | Description=Flamingo Cloud Instance Contextualization Tool 3 | 4 | [Service] 5 | ExecStart=-/bin/flamingo 6 | 7 | [Install] 8 | WantedBy=multi-user.target 9 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | go: 4 | - 1.2 5 | - 1.3 6 | - 1.4 7 | 8 | install: 9 | - go get golang.org/x/tools/cover 10 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/assertions.goconvey: -------------------------------------------------------------------------------- 1 | #ignore 2 | -timeout=1s 3 | -coverpkg=github.com/smartystreets/assertions,github.com/smartystreets/assertions/internal/oglematchers -------------------------------------------------------------------------------- /pkg/sys/ssh/test_keys/test_ecdsa.pub: -------------------------------------------------------------------------------- 1 | ecdsa-sha2-nistp256 AAAAE2VjZHNhLXNoYTItbmlzdHAyNTYAAAAIbmlzdHAyNTYAAABBBNxOFNFuviYC0CoGbV7Sbel191c8tcbA/Zm2i5S42zjnR/QI/4WsyxXtGAGjE0DowPrttN8un+rr46FsJ6CgFDw= keywiz@keywiz-GA-890GPA-UD3H 2 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/gopkg.in/yaml.v2/suite_test.go: -------------------------------------------------------------------------------- 1 | package yaml_test 2 | 3 | import ( 4 | . "gopkg.in/check.v1" 5 | "testing" 6 | ) 7 | 8 | func Test(t *testing.T) { TestingT(t) } 9 | 10 | type S struct{} 11 | 12 | var _ = Suite(&S{}) 13 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/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 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/ogletest/srcutil/docs.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | 4 | // Functions for working with source code. 5 | package srcutil 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/convey.goconvey: -------------------------------------------------------------------------------- 1 | #ignore 2 | -timeout=1s 3 | #-covermode=count 4 | #-coverpkg=github.com/smartystreets/goconvey/convey,github.com/smartystreets/goconvey/convey/gotest,github.com/smartystreets/goconvey/convey/reporting -------------------------------------------------------------------------------- /pkg/sys/ssh/test_keys/test_ecdsa: -------------------------------------------------------------------------------- 1 | -----BEGIN EC PRIVATE KEY----- 2 | MHcCAQEEICujMgaY3PjKs0elWJnu6oWY5ZS+VoW2mb4TTyBHcUa6oAoGCCqGSM49 3 | AwEHoUQDQgAE3E4U0W6+JgLQKgZtXtJt6XX3Vzy1xsD9mbaLlLjbOOdH9Aj/hazL 4 | Fe0YAaMTQOjA+u203y6f6uvjoWwnoKAUPA== 5 | -----END EC PRIVATE KEY----- 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.no_cases_test: -------------------------------------------------------------------------------- 1 | [----------] Running tests from NoCasesTest 2 | SetUpTestSuite run! 3 | TearDownTestSuite run! 4 | [----------] Finished with tests from NoCasesTest 5 | PASS 6 | ok somepkg 1.234s 7 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/doc.go: -------------------------------------------------------------------------------- 1 | // Package reporting contains internal functionality related 2 | // to console reporting and output. Although this package has 3 | // exported names is not intended for public consumption. See the 4 | // examples package for how to use this project. 5 | package reporting 6 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglemock/sample/README.markdown: -------------------------------------------------------------------------------- 1 | This directory contains sample code generated with the `createmock` command. For 2 | example, the file `mock_io.go` can be regenerated with: 3 | 4 | createmock io Reader > sample/mock_io/mock_io.go 5 | 6 | The files are also used by `integration_test.go`. 7 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/console.go: -------------------------------------------------------------------------------- 1 | package reporting 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | ) 7 | 8 | type console struct{} 9 | 10 | func (self *console) Write(p []byte) (n int, err error) { 11 | return fmt.Print(string(p)) 12 | } 13 | 14 | func NewConsole() io.Writer { 15 | return new(console) 16 | } 17 | -------------------------------------------------------------------------------- /pkg/util/mock/io.go: -------------------------------------------------------------------------------- 1 | package mock 2 | 3 | import "bytes" 4 | 5 | type ReadCloser struct { 6 | *bytes.Buffer 7 | IsClosed bool 8 | } 9 | 10 | func (mrc *ReadCloser) Close() (err error) { 11 | mrc.IsClosed = true 12 | return 13 | } 14 | 15 | func NewReadCloser(contents string) *ReadCloser { 16 | return &ReadCloser{bytes.NewBufferString(contents), false} 17 | } 18 | -------------------------------------------------------------------------------- /pkg/util/strutil/stringutil.go: -------------------------------------------------------------------------------- 1 | // Package strutil provides different string utilities 2 | package strutil 3 | 4 | import ( 5 | "io" 6 | "io/ioutil" 7 | "strings" 8 | ) 9 | 10 | func ToReader(s string) (r io.Reader) { 11 | return strings.NewReader(s) 12 | } 13 | 14 | func ToReadCloser(s string) (rc io.ReadCloser) { 15 | return ioutil.NopCloser(ToReader(s)) 16 | } 17 | -------------------------------------------------------------------------------- /.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 | -------------------------------------------------------------------------------- /pkg/file/directory.go: -------------------------------------------------------------------------------- 1 | package file 2 | 3 | import "os" 4 | 5 | func EnsureDirectoryExists(dirname string, perms os.FileMode, userID int, groupID int) error { 6 | if err := os.MkdirAll(dirname, perms); err != nil { 7 | return err 8 | } 9 | 10 | if err := os.Chmod(dirname, perms); err != nil { 11 | return err 12 | } 13 | 14 | return os.Chown(dirname, userID, groupID) 15 | } 16 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/jtolds/gls/gen_sym.go: -------------------------------------------------------------------------------- 1 | package gls 2 | 3 | var ( 4 | symPool = &idPool{} 5 | ) 6 | 7 | // ContextKey is a throwaway value you can use as a key to a ContextManager 8 | type ContextKey struct{ id uint } 9 | 10 | // GenSym will return a brand new, never-before-used ContextKey 11 | func GenSym() ContextKey { 12 | return ContextKey{id: symPool.Acquire()} 13 | } 14 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: go 2 | 3 | sudo: false 4 | 5 | matrix: 6 | include: 7 | - go: 1.4 8 | - go: 1.3 9 | 10 | install: 11 | - go get github.com/tools/godep 12 | - go get golang.org/x/tools/cmd/cover 13 | - go get github.com/axw/gocov/gocov 14 | - go get github.com/mattn/goveralls 15 | 16 | script: 17 | - bin/test -v -race 18 | - $HOME/gopath/bin/goveralls -service=travis-ci 19 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/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 | -------------------------------------------------------------------------------- /pkg/sys/initd/systemd/unit.go: -------------------------------------------------------------------------------- 1 | package systemd 2 | 3 | import "github.com/tmrts/flamingo/pkg/sys/initd" 4 | 5 | type Unit struct { 6 | name string 7 | path string 8 | } 9 | 10 | func NewUnit(name, path string) initd.Component { 11 | return Unit{name, path} 12 | } 13 | 14 | func (u Unit) Name() string { 15 | return u.name 16 | } 17 | 18 | func (u Unit) Path() string { 19 | return u.path 20 | } 21 | -------------------------------------------------------------------------------- /pkg/sys/ssh/test_keys/test_rsa.pub: -------------------------------------------------------------------------------- 1 | ssh-rsa AAAAB3NzaC1yc2EAAAADAQABAAABAQDUdCIV3Eub9IshOUECNfTCquozYOSSEiLJv0QQmpiqYK6Zoxo+KKVZTJdW+hx3Nxye1W3pkcTbUcZoWmbKmLtibGZvE/aw4+moHW2EPxn9wxywI8PgMXqOeQN3yNg811Pf2LNOfJNs6IpDYuMG2voOVQT+MFZMhFboecn7MNlIqIN23VefOw8Zx7x7uJ9sHwydfYdav0a6CRnST+7Eaby9I3JjZBDJdYRk9X/HDMotsSTx0mvhBHV10kLrCbrPcmz/zLOOKd3IxYNiub1+qXAQ+Mvk1tUqdtf1V6rH6AzDbsVc14LFY4q3H741jBKj6cPNyqN+uxDl8uSFo9yn6pwJ keywiz@keywiz-GA-890GPA-UD3H 2 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.unexported_test: -------------------------------------------------------------------------------- 1 | [----------] Running tests from UnexportedTest 2 | [ RUN ] UnexportedTest.SomeTest 3 | unexported_test.go:42: 4 | Expected: 4 5 | Actual: 3 6 | 7 | [ FAILED ] UnexportedTest.SomeTest 8 | [----------] Finished with tests from UnexportedTest 9 | --- FAIL: TestSomething (1.23s) 10 | FAIL 11 | exit status 1 12 | FAIL somepkg 1.234s 13 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/reqtrace/.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 | -------------------------------------------------------------------------------- /pkg/util/testutil/http.go: -------------------------------------------------------------------------------- 1 | package testutil 2 | 3 | import ( 4 | "net/http" 5 | "net/http/httptest" 6 | ) 7 | 8 | type HandlerFunc func(http.ResponseWriter, *http.Request) 9 | 10 | type mockHandler struct { 11 | h HandlerFunc 12 | } 13 | 14 | func (m mockHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { 15 | m.h(w, r) 16 | } 17 | 18 | func NewMockServer(h HandlerFunc) *httptest.Server { 19 | return httptest.NewServer(mockHandler{h}) 20 | } 21 | -------------------------------------------------------------------------------- /pkg/sys/firewall/manager.go: -------------------------------------------------------------------------------- 1 | package firewall 2 | 3 | type Table string 4 | 5 | const ( 6 | Filter Table = "filter" 7 | Nat Table = "nat" 8 | Raw Table = "raw" 9 | ) 10 | 11 | type Chain struct { 12 | Name string 13 | Table Table 14 | } 15 | 16 | type Manager interface { 17 | CheckDependencies() error 18 | AppendTo(Chain, string) error 19 | DeleteFrom(Chain, string) error 20 | InsertTo(Chain, string) error 21 | Check(Chain, string) (bool, error) 22 | } 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.stop_test: -------------------------------------------------------------------------------- 1 | [----------] Running tests from StopTest 2 | [ RUN ] StopTest.First 3 | TearDown running. 4 | [ OK ] StopTest.First 5 | [ RUN ] StopTest.Second 6 | About to call StopRunningTests. 7 | Called StopRunningTests. 8 | TearDown running. 9 | [ OK ] StopTest.Second 10 | TearDownTestSuite running. 11 | Exiting early due to user request. 12 | exit status 1 13 | FAIL somepkg 1.234s 14 | -------------------------------------------------------------------------------- /pkg/datasrc/provider/gce/test_metadata/GCEv1_project.json: -------------------------------------------------------------------------------- 1 | { 2 | "attributes": { 3 | "google-compute-default-region": "us-central1", 4 | "google-compute-default-zone": "us-central1-f", 5 | "sshKeys": "user1:ssh-rsa RSA_PUBLIC_KEY_FOR_USER_1 user1@machine\nuser1:ssh-dsa DSA_PUBLIC_KEY_FOR_USER_1 user1@machine\nuser2:ssh-rsa RSA_PUBLIC_KEY_FOR_USER_2 user2@machine\n" 6 | }, 7 | "numericProjectId": 446264097457, 8 | "projectId": "speedy-flamingo-101778" 9 | } 10 | -------------------------------------------------------------------------------- /pkg/datasrc/provider/openstack/test_metadata/2012-08-10.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "test", 3 | "hostname": "test.novalocal", 4 | "uuid": "d8e02d56-2648-49a3-bf97-6be8f1204f38", 5 | "project_id": "f7ac731cc11f40efbc03a9f9e1d1d21f", 6 | "availability_zone": "nova", 7 | "launch_index": 0, 8 | "public_keys": { 9 | "mykey": "ssh-rsa RSA_PUBLIC_KEY Generated by Nova\n" 10 | }, 11 | "meta": { 12 | "priority": "low", 13 | "role": "webserver" 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /pkg/distro/implementation_test.go: -------------------------------------------------------------------------------- 1 | package distro_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | ) 8 | 9 | func TestCentOSImplementation(t *testing.T) { 10 | Convey("Given the distribution implementation of CentOS", t, func() { 11 | /* 12 | * mockExec := sys.NewMockExecutor() 13 | * 14 | * centOS := distro.CentOS(mockExec) 15 | * 16 | */ 17 | Convey("It should do consume the given meta-data", func() { 18 | }) 19 | }) 20 | } 21 | -------------------------------------------------------------------------------- /bin/test: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | export GOSTRUCTURE="https://golang.org/doc/code.html" 4 | [ -z "$GOPATH" ] && echo "GOPATH needs to be configured. Please see ${GOSTRUCTURE}" && exit 1 5 | 6 | function flamingo-test { 7 | export ORG_PATH="github.com/tmrts" 8 | export REPO_PATH="${ORG_PATH}/flamingo" 9 | 10 | go get ${REPO_PATH} 11 | go get github.com/tools/godep 12 | 13 | cd ${GOPATH} 14 | cd src/${REPO_PATH} 15 | godep restore 16 | 17 | go test "$@" ./... 18 | } 19 | 20 | flamingo-test -v 21 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.run_twice_test: -------------------------------------------------------------------------------- 1 | [----------] Running tests from RunTwiceTest 2 | [ RUN ] RunTwiceTest.PassingMethod 3 | [ OK ] RunTwiceTest.PassingMethod 4 | [ RUN ] RunTwiceTest.FailingMethod 5 | run_twice_test.go:46: 6 | Expected: 17.5 7 | Actual: 17 8 | 9 | [ FAILED ] RunTwiceTest.FailingMethod 10 | [----------] Finished with tests from RunTwiceTest 11 | --- FAIL: TestSomething (1.23s) 12 | FAIL 13 | exit status 1 14 | FAIL somepkg 1.234s 15 | -------------------------------------------------------------------------------- /bin/install: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | export GOSTRUCTURE="https://golang.org/doc/code.html" 4 | [ -z "$GOPATH" ] && echo "GOPATH needs to be configured. Please see ${GOSTRUCTURE}" && exit 1 5 | 6 | function flamingo-install { 7 | export ORG_PATH="github.com/tmrts" 8 | export REPO_PATH="${ORG_PATH}/flamingo" 9 | 10 | go get ${REPO_PATH} 11 | go get github.com/tools/godep 12 | 13 | cd ${GOPATH} 14 | cd src/${REPO_PATH} 15 | godep restore 16 | 17 | go install "$@" flamingo.go 18 | } 19 | 20 | flamingo-install 21 | -------------------------------------------------------------------------------- /bin/build: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env bash 2 | 3 | export GOSTRUCTURE="https://golang.org/doc/code.html" 4 | [ -z "$GOPATH" ] && echo "GOPATH needs to be configured. Please see ${GOSTRUCTURE}" && exit 1 5 | 6 | function flamingo-build { 7 | export ORG_PATH="github.com/tmrts" 8 | export REPO_PATH="${ORG_PATH}/flamingo" 9 | 10 | go get ${REPO_PATH} 11 | go get github.com/tools/godep 12 | 13 | cd ${GOPATH} 14 | cd src/${REPO_PATH} 15 | godep restore 16 | 17 | go clean 18 | go build "$@" flamingo.go 19 | } 20 | 21 | flamingo-build 22 | -------------------------------------------------------------------------------- /pkg/sys/nss/service_mock.go: -------------------------------------------------------------------------------- 1 | package nss 2 | 3 | type MockService struct { 4 | DB chan Database 5 | Key chan string 6 | 7 | OutStr chan string 8 | OutErr chan error 9 | } 10 | 11 | func NewMockService() *MockService { 12 | return &MockService{ 13 | DB: make(chan Database, 1), 14 | Key: make(chan string, 1), 15 | 16 | OutStr: make(chan string, 1), 17 | OutErr: make(chan error, 1), 18 | } 19 | } 20 | 21 | func (ms *MockService) GetEntryFrom(db Database, key string) (string, error) { 22 | ms.DB <- db 23 | ms.Key <- key 24 | 25 | return <-ms.OutStr, <-ms.OutErr 26 | } 27 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/README.md: -------------------------------------------------------------------------------- 1 | # Syslog Hooks for Logrus :walrus: 2 | 3 | ## Usage 4 | 5 | ```go 6 | import ( 7 | "log/syslog" 8 | "github.com/Sirupsen/logrus" 9 | logrus_syslog "github.com/Sirupsen/logrus/hooks/syslog" 10 | ) 11 | 12 | func main() { 13 | log := logrus.New() 14 | hook, err := logrus_syslog.NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") 15 | 16 | if err == nil { 17 | log.Hooks.Add(hook) 18 | } 19 | } 20 | ``` 21 | -------------------------------------------------------------------------------- /pkg/sys/ssh/test_keys/test_dsa.pub: -------------------------------------------------------------------------------- 1 | ssh-dss AAAAB3NzaC1kc3MAAACBANC8CDE3BVe207XvnjeJHxMI5uXaQDU9Ns+TlUCN9D+5tLLWY/l2x/7ZJk0rQ01yqXn1CboF7+VeU8EkNxVg5WcFSFcmGwbJeEO8MeY6KyMvazJ7OnatDSLEXi8R4acohRIHaR2xoGJHNAXDBgvLf/wVrwGDbY4lRfliIFzXbTkBAAAAFQDVdzqTfFkaOFu0ZHEJQLPoJGg+9wAAAIEAlMLcrvtbXMeufKAGT2JvsDwu9iSJws4zkK4HL0ZDz97MbE1ZXvl3+GjeF4CoF4lik5wgxKXBfABLApLBGYxXYTUfj5yYuiIFFVdGHLjXYLMYLx5cijgGp7D0vJ4jGlE5gvGlAKeJrGiFefkxotieYJptupxBMeW0WrSylNJviycAAACALv8YXdTY5y/pyUmPyGpC8SdE5k4fDdjd5nUI0VUgk0sOomZxuy0uBfP8WZUqIT02C7/ftsCqiMyJSsNSnF3HXrxHcLHuhNtGt8IcVFRrDQDjT1pQBYYGXlYhlG3NsIo58dgHqoDH5PGZrzfc8AfgT1LCjrPhprl50y3nXXw5LbU= keywiz@keywiz-GA-890GPA-UD3H 2 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail_test.go: -------------------------------------------------------------------------------- 1 | package logrus_papertrail 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | "github.com/Sirupsen/logrus" 8 | "github.com/stvp/go-udp-testing" 9 | ) 10 | 11 | func TestWritingToUDP(t *testing.T) { 12 | port := 16661 13 | udp.SetAddr(fmt.Sprintf(":%d", port)) 14 | 15 | hook, err := NewPapertrailHook("localhost", port, "test") 16 | if err != nil { 17 | t.Errorf("Unable to connect to local UDP server.") 18 | } 19 | 20 | log := logrus.New() 21 | log.Hooks.Add(hook) 22 | 23 | udp.ShouldReceive(t, "foo", func() { 24 | log.Info("foo") 25 | }) 26 | } 27 | -------------------------------------------------------------------------------- /docs/README.md: -------------------------------------------------------------------------------- 1 | ## Building 2 | You can build `Flamingo` on your machine by using the build [executable](../bin/build). 3 | 4 | ## Testing 5 | You can test `Flamingo` on your machine by using the test [executable](../bin/test). 6 | 7 | ## Installing 8 | To install `Flamingo`, as a `Go` tool please use the `install` [executable](../bin/install). 9 | 10 | **Note:** Any or each of these operations can be used in arbitrary sequences. You don't have to 11 | `build` before installing or testing `Flamingo` each operation is independent. 12 | 13 | **Note:** Operations above require `Go` 1.3 or higher to be installed on your system along with `git`. 14 | -------------------------------------------------------------------------------- /pkg/datasrc/userdata/cloudconfig/test_configs/sshkeys.yaml: -------------------------------------------------------------------------------- 1 | #cloud-config 2 | 3 | # TODO: Add specifying a user-name 4 | # authorized ssh keys 5 | # ssh_authorized_keys contains a list of ssh public keys to 6 | # be included as an entry in ~/.ssh/authorized_keys for the root user. 7 | ssh_authorized_keys: 8 | - ssh-rsa RSA_PUBLIC_KEY_1 mykey@host 9 | - ssh-rsa RSA_PUBLIC_KEY_2 mykey@host 10 | 11 | # Send pre-generated ssh private keys to the server 12 | ssh_keys: 13 | rsa_public: ssh-rsa RSA_PUBLIC_KEY smoser@localhost 14 | rsa_private: | 15 | -----BEGIN RSA PRIVATE KEY----- 16 | RSA_PRIVATE_KEY 17 | -----END RSA PRIVATE KEY----- 18 | -------------------------------------------------------------------------------- /pkg/sys/ssh/test_keys/test_rsa1.pub: -------------------------------------------------------------------------------- 1 | 2048 65537 27166103171373657399015293795848441906173999578177655326086264994480141887004376256862316298795936054324065384079758108931925804845170958923778228000703786423795854647763732086885634632121109583023586774419279134253593858013299346327499822669497172259541962005964385217319805551205251011559691592845151259166921601492280384525552403282673581607430260079622785000657624700852932285719506566867709828346105376291093532394932997228363368278001937628727770174062434143998366946633479975990414223759413113582586790888199082732661187022635009133675118147670909342290229002142151904592662121688257004925767170744315156329081 keywiz@keywiz-GA-890GPA-UD3H 2 | -------------------------------------------------------------------------------- /pkg/util/rand/random.go: -------------------------------------------------------------------------------- 1 | package rand 2 | 3 | import ( 4 | "math" 5 | "os" 6 | "strconv" 7 | "time" 8 | ) 9 | 10 | var seed uint32 11 | 12 | func Seed() uint32 { 13 | seed = uint32(time.Now().UnixNano() + int64(os.Getpid())) 14 | 15 | return seed 16 | } 17 | 18 | // String returns a random string of given length. 19 | func String(length int) string { 20 | randomNum := Seed() 21 | 22 | // 123 to 100...0123 then 000...0123 to standardize str length 23 | getStrForm := func(length int) string { 24 | blanketValue := uint32(math.Pow10(length + 1)) 25 | 26 | return strconv.Itoa(int(blanketValue + randomNum%blanketValue))[1:] 27 | } 28 | 29 | return getStrForm(length) 30 | } 31 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/syslog_test.go: -------------------------------------------------------------------------------- 1 | package logrus_syslog 2 | 3 | import ( 4 | "github.com/Sirupsen/logrus" 5 | "log/syslog" 6 | "testing" 7 | ) 8 | 9 | func TestLocalhostAddAndPrint(t *testing.T) { 10 | log := logrus.New() 11 | hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_INFO, "") 12 | 13 | if err != nil { 14 | t.Errorf("Unable to connect to local syslog.") 15 | } 16 | 17 | log.Hooks.Add(hook) 18 | 19 | for _, level := range hook.Levels() { 20 | if len(log.Hooks[level]) != 1 { 21 | t.Errorf("SyslogHook was not added. The length of log.Hooks[%v]: %v", level, len(log.Hooks[level])) 22 | } 23 | } 24 | 25 | log.Info("Congratulations!") 26 | } 27 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/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 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/filter.go: -------------------------------------------------------------------------------- 1 | package assertions 2 | 3 | import "fmt" 4 | 5 | const ( 6 | success = "" 7 | needExactValues = "This assertion requires exactly %d comparison values (you provided %d)." 8 | needNonEmptyCollection = "This assertion requires at least 1 comparison value (you provided 0)." 9 | ) 10 | 11 | func need(needed int, expected []interface{}) string { 12 | if len(expected) != needed { 13 | return fmt.Sprintf(needExactValues, needed, len(expected)) 14 | } 15 | return success 16 | } 17 | 18 | func atLeast(minimum int, expected []interface{}) string { 19 | if len(expected) < 1 { 20 | return needNonEmptyCollection 21 | } 22 | return success 23 | } 24 | -------------------------------------------------------------------------------- /pkg/sys/ssh/test_keys/test_dsa: -------------------------------------------------------------------------------- 1 | -----BEGIN DSA PRIVATE KEY----- 2 | MIIBuwIBAAKBgQDQvAgxNwVXttO17543iR8TCObl2kA1PTbPk5VAjfQ/ubSy1mP5 3 | dsf+2SZNK0NNcql59Qm6Be/lXlPBJDcVYOVnBUhXJhsGyXhDvDHmOisjL2syezp2 4 | rQ0ixF4vEeGnKIUSB2kdsaBiRzQFwwYLy3/8Fa8Bg22OJUX5YiBc1205AQIVANV3 5 | OpN8WRo4W7RkcQlAs+gkaD73AoGBAJTC3K77W1zHrnygBk9ib7A8LvYkicLOM5Cu 6 | By9GQ8/ezGxNWV75d/ho3heAqBeJYpOcIMSlwXwASwKSwRmMV2E1H4+cmLoiBRVX 7 | Rhy412CzGC8eXIo4Bqew9LyeIxpROYLxpQCniaxohXn5MaLYnmCabbqcQTHltFq0 8 | spTSb4snAoGALv8YXdTY5y/pyUmPyGpC8SdE5k4fDdjd5nUI0VUgk0sOomZxuy0u 9 | BfP8WZUqIT02C7/ftsCqiMyJSsNSnF3HXrxHcLHuhNtGt8IcVFRrDQDjT1pQBYYG 10 | XlYhlG3NsIo58dgHqoDH5PGZrzfc8AfgT1LCjrPhprl50y3nXXw5LbUCFHfnU3rE 11 | fMBnct+xGCwoE/rTw8Ry 12 | -----END DSA PRIVATE KEY----- 13 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/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 | -------------------------------------------------------------------------------- /pkg/request/response.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | import ( 4 | "encoding/json" 5 | "io/ioutil" 6 | "net/http" 7 | ) 8 | 9 | /* 10 | *type Response interface { 11 | * StatusCode() int 12 | * 13 | * Headers() http.Header 14 | * Content() chan []byte 15 | * 16 | * Request() *Request 17 | *} 18 | */ 19 | 20 | type Response struct { 21 | *http.Response 22 | } 23 | 24 | func (r *Response) Text() ([]byte, error) { 25 | buf, err := ioutil.ReadAll(r.Body) 26 | if err != nil { 27 | return nil, err 28 | } 29 | defer r.Body.Close() 30 | 31 | return buf, nil 32 | } 33 | 34 | func (r *Response) JSON(f interface{}) error { 35 | buf, err := r.Text() 36 | if err != nil { 37 | return err 38 | } 39 | 40 | return json.Unmarshal(buf, &f) 41 | } 42 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/nilReporter.go: -------------------------------------------------------------------------------- 1 | package convey 2 | 3 | import ( 4 | "github.com/smartystreets/goconvey/convey/reporting" 5 | ) 6 | 7 | type nilReporter struct{} 8 | 9 | func (self *nilReporter) BeginStory(story *reporting.StoryReport) {} 10 | func (self *nilReporter) Enter(scope *reporting.ScopeReport) {} 11 | func (self *nilReporter) Report(report *reporting.AssertionResult) {} 12 | func (self *nilReporter) Exit() {} 13 | func (self *nilReporter) EndStory() {} 14 | func (self *nilReporter) Write(p []byte) (int, error) { return len(p), nil } 15 | func newNilReporter() *nilReporter { return &nilReporter{} } 16 | -------------------------------------------------------------------------------- /pkg/request/client_mock.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | type MockClient struct { 4 | Client 5 | 6 | Method chan string 7 | URL chan string 8 | Parameters chan []Parameter 9 | 10 | OutResponse chan *Response 11 | OutError error 12 | } 13 | 14 | func NewMockClient(l int) *MockClient { 15 | return &MockClient{ 16 | Method: make(chan string, 1), 17 | URL: make(chan string, 1), 18 | Parameters: make(chan []Parameter, 1), 19 | 20 | OutResponse: make(chan *Response, l), 21 | OutError: nil, 22 | } 23 | } 24 | 25 | func (mc *MockClient) Perform(method, url string, params ...Parameter) (*Response, error) { 26 | mc.Method <- method 27 | mc.URL <- url 28 | mc.Parameters <- params 29 | 30 | return <-mc.OutResponse, mc.OutError 31 | } 32 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/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 | -------------------------------------------------------------------------------- /pkg/request/request.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | import "net/http" 4 | 5 | type Request struct { 6 | Method, URL string 7 | 8 | Headers http.Header 9 | } 10 | 11 | // Normalize converts request.Request to http.Request 12 | // Currently request pkg is a wrapper for http pkg 13 | func (r *Request) Normalize() *http.Request { 14 | req, err := http.NewRequest(r.Method, r.URL, nil) 15 | if err != nil { 16 | panic(err) 17 | } 18 | 19 | req.Header = r.Headers 20 | 21 | return req 22 | } 23 | 24 | // Parameter is an optional argument expected by the request API 25 | type Parameter func(*Request) 26 | 27 | func Header(key string, values ...string) Parameter { 28 | return func(r *Request) { 29 | r.Headers.Del(key) 30 | 31 | for _, v := range values { 32 | r.Headers.Add(key, v) 33 | } 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/hook/hook.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/Sirupsen/logrus" 5 | "github.com/Sirupsen/logrus/hooks/airbrake" 6 | ) 7 | 8 | var log = logrus.New() 9 | 10 | func init() { 11 | log.Formatter = new(logrus.TextFormatter) // default 12 | log.Hooks.Add(airbrake.NewHook("https://example.com", "xyz", "development")) 13 | } 14 | 15 | func main() { 16 | log.WithFields(logrus.Fields{ 17 | "animal": "walrus", 18 | "size": 10, 19 | }).Info("A group of walrus emerges from the ocean") 20 | 21 | log.WithFields(logrus.Fields{ 22 | "omg": true, 23 | "number": 122, 24 | }).Warn("The group's number increased tremendously!") 25 | 26 | log.WithFields(logrus.Fields{ 27 | "omg": true, 28 | "number": 100, 29 | }).Fatal("The ice breaks!") 30 | } 31 | -------------------------------------------------------------------------------- /docs/providers.md: -------------------------------------------------------------------------------- 1 | ## Google Compute Engine 2 | In `GCE`, you can use multiple user-data file (script or cloud-config), 3 | through `gcloud` utility as such: 4 | `gcloud compute instances add-metadata atomic --zone us-central1-a --metadata-from-file user-data=cloud-config.yaml` 5 | 6 | **Note:** At the moment when providing multiple user-data files, 7 | the order of consuming those files are non-deterministic. 8 | 9 | ## OpenStack 10 | In 'OpenStack' you can either use, the meta-data service that 11 | receives cloud-config files through command-line or 12 | you can use `Config-Drive` disk images for configuration. 13 | 14 | ## Amazon Elastic Compute Cloud 15 | You can use `Flamingo` in `EC2`, to provide meta-data or 16 | user-data please [see](http://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-instance-metadata.html). 17 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/jtolds/gls/id_pool.go: -------------------------------------------------------------------------------- 1 | package gls 2 | 3 | // though this could probably be better at keeping ids smaller, the goal of 4 | // this class is to keep a registry of the smallest unique integer ids 5 | // per-process possible 6 | 7 | import ( 8 | "sync" 9 | ) 10 | 11 | type idPool struct { 12 | mtx sync.Mutex 13 | released []uint 14 | max_id uint 15 | } 16 | 17 | func (p *idPool) Acquire() (id uint) { 18 | p.mtx.Lock() 19 | defer p.mtx.Unlock() 20 | if len(p.released) > 0 { 21 | id = p.released[len(p.released)-1] 22 | p.released = p.released[:len(p.released)-1] 23 | return id 24 | } 25 | id = p.max_id 26 | p.max_id++ 27 | return id 28 | } 29 | 30 | func (p *idPool) Release(id uint) { 31 | p.mtx.Lock() 32 | defer p.mtx.Unlock() 33 | p.released = append(p.released, id) 34 | } 35 | -------------------------------------------------------------------------------- /pkg/request/api.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | func Get(url string, params ...Parameter) (*Response, error) { 4 | return DefaultClient.Perform("GET", url, params...) 5 | } 6 | 7 | func Put(url string, params ...Parameter) (*Response, error) { 8 | return DefaultClient.Perform("PUT", url, params...) 9 | } 10 | 11 | func Post(url string, params ...Parameter) (*Response, error) { 12 | return DefaultClient.Perform("POST", url, params...) 13 | } 14 | 15 | func Head(url string, params ...Parameter) (*Response, error) { 16 | return DefaultClient.Perform("HEAD", url, params...) 17 | } 18 | 19 | func Delete(url string, params ...Parameter) (*Response, error) { 20 | return DefaultClient.Perform("DELETE", url, params...) 21 | } 22 | 23 | func Options(url string, params ...Parameter) (*Response, error) { 24 | return DefaultClient.Perform("OPTIONS", url, params...) 25 | } 26 | -------------------------------------------------------------------------------- /pkg/datasrc/userdata/cloudconfig/test_configs/runcmd.yaml: -------------------------------------------------------------------------------- 1 | #cloud-config 2 | 3 | # run commands 4 | # runcmd contains a list of either lists or a string 5 | # each item will be executed in order at rc.local like level with 6 | # output to the console 7 | # - if the item is a list, the items will be properly executed as if 8 | # passed to execve(3) (with the first arg as the command). 9 | # - if the item is a string, it will be simply written to the file and 10 | # will be interpreted by 'sh' 11 | # 12 | # Note, that the list has to be proper yaml, so you have to escape 13 | # any characters yaml would eat (':' can be problematic) 14 | 15 | runcmd: 16 | - [ ls, -l, / ] 17 | - [ sh, -xc, "echo $(date) ': hello world!'" ] 18 | - [ sh, -c, echo "=========hello world'=========" ] 19 | - ls -l /root 20 | - [ wget, "http://slashdot.org", -O, /tmp/index.html ] 21 | 22 | -------------------------------------------------------------------------------- /pkg/request/response_test.go: -------------------------------------------------------------------------------- 1 | package request_test 2 | 3 | import ( 4 | "net/http" 5 | "testing" 6 | 7 | . "github.com/smartystreets/goconvey/convey" 8 | . "github.com/tmrts/flamingo/pkg/util/testutil" 9 | 10 | "github.com/tmrts/flamingo/pkg/request" 11 | "github.com/tmrts/flamingo/pkg/util/mock" 12 | ) 13 | 14 | func TestTextToJSON(t *testing.T) { 15 | Convey("Given a RESTful response", t, func() { 16 | mockBody := mock.NewReadCloser("{\"response\": [1,2,3]}") 17 | 18 | r := &request.Response{ 19 | &http.Response{Body: mockBody}, 20 | } 21 | 22 | Convey("It should convert it into given JSON struct", func() { 23 | var x struct { 24 | Response []int 25 | } 26 | 27 | err := r.JSON(&x) 28 | So(err, ShouldBeNil) 29 | 30 | So(x.Response, ShouldConsistOf, 1, 2, 3) 31 | So(mockBody.IsClosed, ShouldBeTrue) 32 | }) 33 | }) 34 | } 35 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/gotest.go: -------------------------------------------------------------------------------- 1 | package reporting 2 | 3 | type gotestReporter struct{ test T } 4 | 5 | func (self *gotestReporter) BeginStory(story *StoryReport) { 6 | self.test = story.Test 7 | } 8 | 9 | func (self *gotestReporter) Enter(scope *ScopeReport) {} 10 | 11 | func (self *gotestReporter) Report(r *AssertionResult) { 12 | if !passed(r) { 13 | self.test.Fail() 14 | } 15 | } 16 | 17 | func (self *gotestReporter) Exit() {} 18 | 19 | func (self *gotestReporter) EndStory() { 20 | self.test = nil 21 | } 22 | 23 | func (self *gotestReporter) Write(content []byte) (written int, err error) { 24 | return len(content), nil // no-op 25 | } 26 | 27 | func NewGoTestReporter() *gotestReporter { 28 | return new(gotestReporter) 29 | } 30 | 31 | func passed(r *AssertionResult) bool { 32 | return r.Error == nil && r.Failure == "" 33 | } 34 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/Makefile: -------------------------------------------------------------------------------- 1 | # This Makefile pulls the latest oglematchers (with dependencies), 2 | # rewrites the imports to match this location, 3 | # and ensures that all the tests pass. 4 | 5 | go: clean clone rewrite test 6 | 7 | clean: 8 | rm -rf ogle* 9 | rm -rf reqtrace 10 | 11 | clone: 12 | git clone https://github.com/jacobsa/ogletest.git && rm -rf ogletest/.git 13 | git clone https://github.com/jacobsa/oglemock.git && rm -rf oglemock/.git 14 | git clone https://github.com/jacobsa/oglematchers.git && rm -rf oglematchers/.git 15 | git clone https://github.com/jacobsa/reqtrace.git && rm -rf reqtrace/.git 16 | 17 | rewrite: 18 | grep -rl --exclude Makefile 'github.com/jacobsa' . | xargs sed -i '' 's#github.com/jacobsa#github.com/smartystreets/assertions/internal#g' 19 | 20 | test: 21 | go test github.com/smartystreets/assertions/... 22 | -------------------------------------------------------------------------------- /pkg/datasrc/userdata/cloudconfig/test_configs/write_files.yaml: -------------------------------------------------------------------------------- 1 | #cloud-config 2 | # 3 | # This is the configuration syntax that the write_files module 4 | # will know how to understand. encoding can be given b64 or gzip or (gz+b64). 5 | # The content will be decoded accordingly and then written to the path that is 6 | # provided. 7 | # 8 | # Note: Content strings here are truncated for example purposes. 9 | write_files: 10 | - encoding: b64 11 | content: STRING_FILE_CONTENT 12 | owner: some_user:some_group 13 | path: /etc/sysconfig/selinux 14 | permissions: '0644' 15 | - content: | 16 | # My new /etc/sysconfig/samba file 17 | 18 | SMBDOPTIONS="-D" 19 | path: /etc/sysconfig/samba 20 | - encoding: gzip 21 | content: !!binary | 22 | H4sIAIDb/U8C/1NW1E/KzNMvzuBKTc7IV8hIzcnJVyjPL8pJ4QIA6N+MVxsAAAA= 23 | path: /usr/bin/hello 24 | permissions: '0755' 25 | -------------------------------------------------------------------------------- /pkg/distro/centos.go: -------------------------------------------------------------------------------- 1 | package distro 2 | 3 | import ( 4 | "github.com/tmrts/flamingo/pkg/sys" 5 | "github.com/tmrts/flamingo/pkg/sys/firewall/iptables" 6 | "github.com/tmrts/flamingo/pkg/sys/identity" 7 | "github.com/tmrts/flamingo/pkg/sys/initd/systemd" 8 | "github.com/tmrts/flamingo/pkg/sys/nss" 9 | ) 10 | 11 | // CentOS returns the distribution implementation of CentOS 12 | // operating system that uses the given sys.Executor. 13 | func CentOS(exec sys.Executor) ContextConsumer { 14 | return &Implementation{ 15 | Executor: exec, 16 | 17 | ID: identity.NewManager(exec), 18 | NSS: &nss.Server{exec}, 19 | Firewall: &iptables.Implementation{exec}, 20 | //FileSystem: &file.System{exec}, 21 | //Sysconf: conf.Manager hostname, timedate, etc. sysctl for CentOS 22 | Initd: &systemd.Implementation{ 23 | UnitDir: "/etc/systemd/userexec", 24 | Exec: exec, 25 | }, 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Godeps/Godeps.json: -------------------------------------------------------------------------------- 1 | { 2 | "ImportPath": "github.com/tmrts/flamingo", 3 | "GoVersion": "go1.4.2", 4 | "Packages": [ 5 | "./..." 6 | ], 7 | "Deps": [ 8 | { 9 | "ImportPath": "github.com/Sirupsen/logrus", 10 | "Comment": "v0.8.6-7-g9c060de", 11 | "Rev": "9c060de643590dae45da9d7c26276463bfc46fa0" 12 | }, 13 | { 14 | "ImportPath": "github.com/jtolds/gls", 15 | "Rev": "9a4a02dbe491bef4bab3c24fd9f3087d6c4c6690" 16 | }, 17 | { 18 | "ImportPath": "github.com/smartystreets/assertions", 19 | "Comment": "1.5.0-390-g6427400", 20 | "Rev": "6427400a39401722b896971821c0d69f8a31818f" 21 | }, 22 | { 23 | "ImportPath": "github.com/smartystreets/goconvey/convey", 24 | "Comment": "1.5.0-402-gb903fa1", 25 | "Rev": "b903fa1aa6daa8eee319b8bdcff2296f61bb5388" 26 | }, 27 | { 28 | "ImportPath": "gopkg.in/yaml.v2", 29 | "Rev": "7ad95dd0798a40da1ccdff6dff35fd177b5edf40" 30 | } 31 | ] 32 | } 33 | -------------------------------------------------------------------------------- /pkg/sys/executor_test.go: -------------------------------------------------------------------------------- 1 | package sys_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | 8 | "github.com/tmrts/flamingo/pkg/sys" 9 | ) 10 | 11 | func TestExecutesACommand(t *testing.T) { 12 | Convey("Given a command and a list of arguments", t, func() { 13 | cmd, args := "echo", []string{"-n", "fi fye fo fum"} 14 | 15 | Convey("It should execute the command and return its output", func() { 16 | out, err := sys.DefaultExecutor.Execute(cmd, args...) 17 | So(err, ShouldBeNil) 18 | 19 | So(out, ShouldEqual, "fi fye fo fum") 20 | }) 21 | }) 22 | } 23 | 24 | func TestExecutesAnInvalidCommand(t *testing.T) { 25 | Convey("Given an erroneous command", t, func() { 26 | cmd := "tHiScOmMaNdDoEsNtExIsT" 27 | 28 | Convey("It should return the stderr as a new error", func() { 29 | _, err := sys.DefaultExecutor.Execute(cmd) 30 | So(err, ShouldNotBeNil) 31 | }) 32 | }) 33 | } 34 | -------------------------------------------------------------------------------- /pkg/sys/nss/passwd_test.go: -------------------------------------------------------------------------------- 1 | package nss_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | 8 | "github.com/tmrts/flamingo/pkg/sys/nss" 9 | ) 10 | 11 | func TestPasswdDatabaseEntryRetrieval(t *testing.T) { 12 | Convey("Given an nss server and a user name", t, func() { 13 | uname := "root" 14 | 15 | server := &nss.Server{ 16 | Exec: &fakeExecutor{ 17 | expectedCmd: "getent", 18 | expectedResult: "root:x:0:0:root:/root:/bin/bash", 19 | }, 20 | } 21 | 22 | Convey("It should query the NSS passwd database and get its entry", func() { 23 | root, err := nss.GetPasswdEntry(server, uname) 24 | So(err, ShouldBeNil) 25 | 26 | So(root.UserName, ShouldEqual, "root") 27 | 28 | So(root.UID, ShouldEqual, 0) 29 | So(root.GID, ShouldEqual, 0) 30 | 31 | So(root.HomeDir, ShouldEqual, "/root") 32 | 33 | So(root.IsSystemAccount, ShouldBeTrue) 34 | }) 35 | }) 36 | } 37 | -------------------------------------------------------------------------------- /pkg/sys/nss/shadow.go: -------------------------------------------------------------------------------- 1 | package nss 2 | 3 | import "strings" 4 | 5 | // ShadowEntry is the representation of Name Switch Service 6 | // 'shadow' database entry fields. 7 | type ShadowEntry struct { 8 | UserName string 9 | PasswordHash string 10 | ChangedAgo string 11 | ChangedBefore string 12 | ExpiryPeriod string 13 | DisabledSince string 14 | } 15 | 16 | // Parses NSS UserShadowDatabase Entry. 17 | func parseShadowEntry(shadowEntry string) *ShadowEntry { 18 | userShadowInfo := strings.Split(shadowEntry, ":") 19 | 20 | return &ShadowEntry{ 21 | UserName: userShadowInfo[0], 22 | PasswordHash: userShadowInfo[1], 23 | } 24 | } 25 | 26 | // ShadowEntry queries the NSS User Shadow Database. 27 | func GetShadowEntry(s Service, key string) (*ShadowEntry, error) { 28 | ent, err := s.GetEntryFrom(UserShadowDatabase, key) 29 | if err != nil { 30 | return nil, err 31 | } 32 | 33 | return parseShadowEntry(ent), nil 34 | } 35 | -------------------------------------------------------------------------------- /pkg/sys/script.go: -------------------------------------------------------------------------------- 1 | package sys 2 | 3 | import ( 4 | "io/ioutil" 5 | "os" 6 | ) 7 | 8 | // HasShabang checks whether the named file is a script by checking the shabang directive 9 | func FileHasShabang(filename string) (bool, error) { 10 | f, err := os.Open(filename) 11 | if err != nil { 12 | return false, err 13 | } else { 14 | defer f.Close() 15 | } 16 | 17 | twoBytes := make([]byte, 2) 18 | 19 | _, err = f.Read(twoBytes) 20 | if err != nil { 21 | return false, err 22 | } 23 | 24 | return twoBytes[0] == '#' && twoBytes[1] == '!', nil 25 | } 26 | 27 | // WriteScript writes the content of the byte slice into the named file 28 | func WriteScript(filename string, contents []byte) error { 29 | // TODO: Variable environment preparation (e.g. temporarily Chdir) 30 | // BUG: The contents are appended if file/script already exists. 31 | // Arbitrary code could be execution can be performed. 32 | return ioutil.WriteFile(filename, contents, 0744) 33 | } 34 | -------------------------------------------------------------------------------- /pkg/datasrc/provider/provider.go: -------------------------------------------------------------------------------- 1 | // Package provider contains the interface for a data source provider 2 | package provider 3 | 4 | import ( 5 | "fmt" 6 | 7 | "github.com/tmrts/flamingo/pkg/datasrc/metadata" 8 | "github.com/tmrts/flamingo/pkg/datasrc/userdata" 9 | ) 10 | 11 | // FormatURL is the meta-data service url as a format string 12 | // to be replaced by Version. 13 | // Example: 14 | // var u FormatURL = "http://169.256.169.256/metadata/%v/%v" 15 | // fmt.Printf(u.Fill("latest", "hostname")) -> http://169.256.169.256/metadata/latest/hostname" 16 | type FormatURL string 17 | 18 | // Fill method is a wrapper around fmt.Sprintf to fill format URLs. 19 | func (u FormatURL) Fill(values ...interface{}) string { 20 | return fmt.Sprintf(string(u), values...) 21 | } 22 | 23 | // Interface is the interface that represents the ability to 24 | // provide both user-data and meta-data information. 25 | type Interface interface { 26 | metadata.Provider 27 | userdata.Provider 28 | } 29 | -------------------------------------------------------------------------------- /pkg/request/rest_test.go: -------------------------------------------------------------------------------- 1 | package request_test 2 | 3 | import ( 4 | "io/ioutil" 5 | "net/http" 6 | "testing" 7 | 8 | . "github.com/smartystreets/goconvey/convey" 9 | 10 | "github.com/tmrts/flamingo/pkg/request" 11 | "github.com/tmrts/flamingo/pkg/util/testutil" 12 | ) 13 | 14 | func TestRESTfulClient(t *testing.T) { 15 | Convey("Given a URL and a REST client", t, func() { 16 | server := testutil.NewMockServer(func(w http.ResponseWriter, r *http.Request) { 17 | buf, _ := ioutil.ReadFile("test_data/some.json") 18 | w.Write(buf) 19 | }) 20 | 21 | Convey("When the client requests the contents", func() { 22 | response, err := request.Get(server.URL) 23 | So(err, ShouldBeNil) 24 | 25 | Convey("Then the response should be the raw contents of the response", func() { 26 | var data map[string]interface{} 27 | 28 | err := response.JSON(&data) 29 | So(err, ShouldBeNil) 30 | 31 | So(data["isJSON"], ShouldBeTrue) 32 | }) 33 | }) 34 | }) 35 | } 36 | -------------------------------------------------------------------------------- /pkg/sys/nss/group_test.go: -------------------------------------------------------------------------------- 1 | package nss_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | 8 | "github.com/tmrts/flamingo/pkg/sys/nss" 9 | "github.com/tmrts/flamingo/pkg/util/testutil" 10 | ) 11 | 12 | func TestGroupDatabaseEntryRetrieval(t *testing.T) { 13 | Convey("Given an nss server and a group name", t, func() { 14 | gname := "root" 15 | 16 | server := &nss.Server{ 17 | Exec: &fakeExecutor{ 18 | expectedCmd: "getent", 19 | expectedResult: "root:x:0:user1,user2,user3", 20 | }, 21 | } 22 | 23 | Convey("It should query the NSS group database and get its entry", func() { 24 | root, err := nss.GetGroupEntry(server, gname) 25 | So(err, ShouldBeNil) 26 | 27 | So(root.GroupName, ShouldEqual, "root") 28 | 29 | So(root.GID, ShouldEqual, 0) 30 | 31 | So(root.IsSystemGroup, ShouldBeTrue) 32 | 33 | So(root.Members, testutil.ShouldSetEqual, []string{"user1", "user2", "user3"}) 34 | }) 35 | }) 36 | } 37 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.passing_test: -------------------------------------------------------------------------------- 1 | [----------] Running tests from PassingTest 2 | [ RUN ] PassingTest.EmptyTestMethod 3 | [ OK ] PassingTest.EmptyTestMethod 4 | [ RUN ] PassingTest.SuccessfullMatches 5 | [ OK ] PassingTest.SuccessfullMatches 6 | [ RUN ] PassingTest.ExpectAliases 7 | [ OK ] PassingTest.ExpectAliases 8 | [ RUN ] PassingTest.AssertAliases 9 | [ OK ] PassingTest.AssertAliases 10 | [ RUN ] PassingTest.SlowTest 11 | [ OK ] PassingTest.SlowTest (1234ms) 12 | [----------] Finished with tests from PassingTest 13 | [----------] Running tests from PassingTestWithHelpers 14 | SetUpTestSuite ran. 15 | [ RUN ] PassingTestWithHelpers.EmptyTestMethod 16 | SetUp ran. 17 | TearDown ran. 18 | [ OK ] PassingTestWithHelpers.EmptyTestMethod 19 | TearDownTestSuite ran. 20 | [----------] Finished with tests from PassingTestWithHelpers 21 | PASS 22 | ok somepkg 1.234s 23 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.filtered_test: -------------------------------------------------------------------------------- 1 | [----------] Running tests from PartiallyFilteredTest 2 | [ RUN ] PartiallyFilteredTest.PassingTestBar 3 | [ OK ] PartiallyFilteredTest.PassingTestBar 4 | [ RUN ] PartiallyFilteredTest.PartiallyFilteredTestBar 5 | filtered_test.go:49: 6 | Expected: has substring "blah" 7 | Actual: taco 8 | 9 | [ FAILED ] PartiallyFilteredTest.PartiallyFilteredTestBar 10 | [ RUN ] PartiallyFilteredTest.PartiallyFilteredTestBaz 11 | filtered_test.go:53: 12 | Expected: less than 17 13 | Actual: 18 14 | 15 | [ FAILED ] PartiallyFilteredTest.PartiallyFilteredTestBaz 16 | [----------] Finished with tests from PartiallyFilteredTest 17 | [----------] Running tests from CompletelyFilteredTest 18 | SetUpTestSuite run! 19 | TearDownTestSuite run! 20 | [----------] Finished with tests from CompletelyFilteredTest 21 | --- FAIL: TestSomething (1.23s) 22 | FAIL 23 | exit status 1 24 | FAIL somepkg 1.234s 25 | -------------------------------------------------------------------------------- /pkg/datasrc/provider/ec2/test_metadata/2009-04-04.json: -------------------------------------------------------------------------------- 1 | { 2 | "ami-id": "ami-00000001", 3 | "ami-launch-index": 0, 4 | "ami-manifest-path": "FIXME", 5 | "block-device-mapping": { 6 | "ami": "sda1", 7 | "ephemeral0": "sda2", 8 | "root": "/dev/sda1", 9 | "swap": "sda3" 10 | }, 11 | "hostname": "centos.ec2", 12 | "instance-action": "none", 13 | "instance-id": "i-00000001", 14 | "instance-type": "m1.tiny", 15 | "kernel-id": "aki-00000002", 16 | "local-hostname": "centos.ec2", 17 | "local-ipv4": "10.240.51.29", 18 | "placement": { 19 | "availability-zone": "nova" 20 | }, 21 | "public-hostname": "centos.ec2", 22 | "public-ipv4": "104.155.21.99", 23 | "public-keys": { 24 | "0": { 25 | "openssh-key": "ssh-rsa OPENSSH_KEY" 26 | } 27 | }, 28 | "ramdisk-id": "ari-00000003", 29 | "reservation-id": "r-7lfps8wj", 30 | "security-groups": [ 31 | "default" 32 | ] 33 | } 34 | -------------------------------------------------------------------------------- /pkg/sys/initd/manager.go: -------------------------------------------------------------------------------- 1 | // initd provides interfaces and implementations for system initialization daemons 2 | package initd 3 | 4 | // Component represents a file that can be used with 5 | // an initd.Manager (e.g. systemd unit, upstart script, etc.) 6 | type Component interface { 7 | Name() string 8 | Path() string 9 | } 10 | 11 | // Manager interface represents a system Manager that manipulates 12 | // the system boot events such as systemd, sysV-init, or upstart. 13 | type Manager interface { 14 | // ReloadDaemon reloads the system Manager daemon. 15 | ReloadDaemon() error 16 | 17 | // CreateComponent creates a component with the given name 18 | // and contents and returns an object representing the created component. 19 | CreateComponent(name, contents string) (Component, error) 20 | 21 | Validate(Component) error 22 | Install(Component) error 23 | Disable(Component) error 24 | Start(Component) error 25 | Reload(Component) error 26 | Stop(Component) error 27 | Extend(Component) error 28 | } 29 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/golden.mock_test: -------------------------------------------------------------------------------- 1 | [----------] Running tests from MockTest 2 | [ RUN ] MockTest.ExpectationSatisfied 3 | [ OK ] MockTest.ExpectationSatisfied 4 | [ RUN ] MockTest.MockExpectationNotSatisfied 5 | /some/path/mock_test.go:56: 6 | Unsatisfied expectation; expected At to be called at least 1 times; called 0 times. 7 | 8 | [ FAILED ] MockTest.MockExpectationNotSatisfied 9 | [ RUN ] MockTest.ExpectCallForUnknownMethod 10 | /some/path/mock_test.go:61: 11 | Unknown method: FooBar 12 | 13 | [ FAILED ] MockTest.ExpectCallForUnknownMethod 14 | [ RUN ] MockTest.UnexpectedCall 15 | /some/path/mock_test.go:65: 16 | Unexpected call to At with args: [11 23] 17 | 18 | [ FAILED ] MockTest.UnexpectedCall 19 | [ RUN ] MockTest.InvokeFunction 20 | [ OK ] MockTest.InvokeFunction 21 | [----------] Finished with tests from MockTest 22 | --- FAIL: TestSomething (1.23s) 23 | FAIL 24 | exit status 1 25 | FAIL somepkg 1.234s 26 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # 0.8.6 2 | 3 | * hooks/raven: allow passing an initialized client 4 | 5 | # 0.8.5 6 | 7 | * logrus/core: revert #208 8 | 9 | # 0.8.4 10 | 11 | * formatter/text: fix data race (#218) 12 | 13 | # 0.8.3 14 | 15 | * logrus/core: fix entry log level (#208) 16 | * logrus/core: improve performance of text formatter by 40% 17 | * logrus/core: expose `LevelHooks` type 18 | * logrus/core: add support for DragonflyBSD and NetBSD 19 | * formatter/text: print structs more verbosely 20 | 21 | # 0.8.2 22 | 23 | * logrus: fix more Fatal family functions 24 | 25 | # 0.8.1 26 | 27 | * logrus: fix not exiting on `Fatalf` and `Fatalln` 28 | 29 | # 0.8.0 30 | 31 | * logrus: defaults to stderr instead of stdout 32 | * hooks/sentry: add special field for `*http.Request` 33 | * formatter/text: ignore Windows for colors 34 | 35 | # 0.7.3 36 | 37 | * formatter/\*: allow configuration of timestamp layout 38 | 39 | # 0.7.2 40 | 41 | * formatter/text: Add configuration option for time format (#158) 42 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/doc_test.go: -------------------------------------------------------------------------------- 1 | package assertions 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "testing" 7 | ) 8 | 9 | func TestPassingAssertion(t *testing.T) { 10 | fake := &FakeT{buffer: new(bytes.Buffer)} 11 | assertion := New(fake) 12 | passed := assertion.So(1, ShouldEqual, 1) 13 | 14 | if !passed { 15 | t.Error("Assertion failed when it should have passed.") 16 | } 17 | if fake.buffer.Len() > 0 { 18 | t.Error("Unexpected error message was printed.") 19 | } 20 | } 21 | 22 | func TestFailingAssertion(t *testing.T) { 23 | fake := &FakeT{buffer: new(bytes.Buffer)} 24 | assertion := New(fake) 25 | passed := assertion.So(1, ShouldEqual, 2) 26 | 27 | if passed { 28 | t.Error("Assertion passed when it should have failed.") 29 | } 30 | if fake.buffer.Len() == 0 { 31 | t.Error("Expected error message not printed.") 32 | } 33 | } 34 | 35 | type FakeT struct { 36 | buffer *bytes.Buffer 37 | } 38 | 39 | func (this *FakeT) Error(args ...interface{}) { 40 | fmt.Fprint(this.buffer, args...) 41 | } 42 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/dot.go: -------------------------------------------------------------------------------- 1 | package reporting 2 | 3 | import "fmt" 4 | 5 | type dot struct{ out *Printer } 6 | 7 | func (self *dot) BeginStory(story *StoryReport) {} 8 | 9 | func (self *dot) Enter(scope *ScopeReport) {} 10 | 11 | func (self *dot) Report(report *AssertionResult) { 12 | if report.Error != nil { 13 | fmt.Print(redColor) 14 | self.out.Insert(dotError) 15 | } else if report.Failure != "" { 16 | fmt.Print(yellowColor) 17 | self.out.Insert(dotFailure) 18 | } else if report.Skipped { 19 | fmt.Print(yellowColor) 20 | self.out.Insert(dotSkip) 21 | } else { 22 | fmt.Print(greenColor) 23 | self.out.Insert(dotSuccess) 24 | } 25 | fmt.Print(resetColor) 26 | } 27 | 28 | func (self *dot) Exit() {} 29 | 30 | func (self *dot) EndStory() {} 31 | 32 | func (self *dot) Write(content []byte) (written int, err error) { 33 | return len(content), nil // no-op 34 | } 35 | 36 | func NewDotReporter(out *Printer) *dot { 37 | self := new(dot) 38 | self.out = out 39 | return self 40 | } 41 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglemock/generate/test_cases/renamed_pkg/renamed_pkg.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | // A package that calls itself something different than its package path would 17 | // have you believe. 18 | package tony 19 | 20 | type SomeUint8Alias uint8 21 | 22 | type SomeInterface interface { 23 | DoFoo(a int) int 24 | } 25 | -------------------------------------------------------------------------------- /pkg/sys/nss/gshadow_test.go: -------------------------------------------------------------------------------- 1 | package nss_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | 8 | "github.com/tmrts/flamingo/pkg/sys/nss" 9 | "github.com/tmrts/flamingo/pkg/util/testutil" 10 | ) 11 | 12 | func TestGroupShadowDatabaseEntryRetrieval(t *testing.T) { 13 | Convey("Given an nss server and a group name", t, func() { 14 | gname := "root" 15 | 16 | server := &nss.Server{ 17 | Exec: &fakeExecutor{ 18 | expectedCmd: "getent", 19 | expectedResult: "root:$4$SALT$PASSWORD_HASH:admin1,admin2:user1,user2", 20 | }, 21 | } 22 | 23 | Convey("It should query the NSS gshadow database and get its entry", func() { 24 | root, err := nss.GetGroupShadowEntry(server, gname) 25 | So(err, ShouldBeNil) 26 | 27 | So(root.GroupName, ShouldEqual, "root") 28 | 29 | So(root.PasswordHash, ShouldEqual, "$4$SALT$PASSWORD_HASH") 30 | 31 | So(root.Admins, testutil.ShouldSetEqual, []string{"admin1", "admin2"}) 32 | 33 | So(root.Members, testutil.ShouldSetEqual, []string{"user1", "user2"}) 34 | }) 35 | }) 36 | } 37 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/dot_test.go: -------------------------------------------------------------------------------- 1 | package reporting 2 | 3 | import ( 4 | "errors" 5 | "testing" 6 | ) 7 | 8 | func TestDotReporterAssertionPrinting(t *testing.T) { 9 | monochrome() 10 | file := newMemoryFile() 11 | printer := NewPrinter(file) 12 | reporter := NewDotReporter(printer) 13 | 14 | reporter.Report(NewSuccessReport()) 15 | reporter.Report(NewFailureReport("failed")) 16 | reporter.Report(NewErrorReport(errors.New("error"))) 17 | reporter.Report(NewSkipReport()) 18 | 19 | expected := dotSuccess + dotFailure + dotError + dotSkip 20 | 21 | if file.buffer != expected { 22 | t.Errorf("\nExpected: '%s'\nActual: '%s'", expected, file.buffer) 23 | } 24 | } 25 | 26 | func TestDotReporterOnlyReportsAssertions(t *testing.T) { 27 | monochrome() 28 | file := newMemoryFile() 29 | printer := NewPrinter(file) 30 | reporter := NewDotReporter(printer) 31 | 32 | reporter.BeginStory(nil) 33 | reporter.Enter(nil) 34 | reporter.Exit() 35 | reporter.EndStory() 36 | 37 | if file.buffer != "" { 38 | t.Errorf("\nExpected: '(blank)'\nActual: '%s'", file.buffer) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglematchers/any.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | // Any returns a matcher that matches any value. 19 | func Any() Matcher { 20 | return &anyMatcher{} 21 | } 22 | 23 | type anyMatcher struct { 24 | } 25 | 26 | func (m *anyMatcher) Description() string { 27 | return "is anything" 28 | } 29 | 30 | func (m *anyMatcher) Matches(c interface{}) error { 31 | return nil 32 | } 33 | -------------------------------------------------------------------------------- /pkg/sys/nss/gshadow.go: -------------------------------------------------------------------------------- 1 | package nss 2 | 3 | import "strings" 4 | 5 | // GroupShadowEntry is the representation of Name Switch Service 6 | // 'gshadow' database entry fields. 7 | type GroupShadowEntry struct { 8 | GroupName string 9 | PasswordHash string 10 | Admins []string 11 | Members []string 12 | } 13 | 14 | func parseGroupShadowEntry(groupEntry string) *GroupShadowEntry { 15 | groupInfo := strings.Split(groupEntry, ":") 16 | 17 | groupAdmins := strings.Split(groupInfo[2], ",") 18 | groupMembers := strings.Split(groupInfo[3], ",") 19 | 20 | return &GroupShadowEntry{ 21 | GroupName: groupInfo[0], 22 | PasswordHash: groupInfo[1], 23 | Admins: groupAdmins, 24 | Members: groupMembers, 25 | } 26 | } 27 | 28 | // GetGroup queries the Name Switch Service 'gshadow' Database. 29 | // It returns the parsed 'gshadow' entry belonging to given group key. 30 | func GetGroupShadowEntry(s Service, groupKey string) (*GroupShadowEntry, error) { 31 | shadowEntry, err := s.GetEntryFrom(GroupShadowDatabase, groupKey) 32 | if err != nil { 33 | return nil, err 34 | } 35 | 36 | return parseGroupShadowEntry(shadowEntry), nil 37 | } 38 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/jtolds/gls/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2013, Space Monkey, Inc. 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of 4 | this software and associated documentation files (the "Software"), to deal in 5 | the Software without restriction, including without limitation the rights to 6 | use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of 7 | the Software, and to permit persons to whom the Software is furnished to do so, 8 | subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS 15 | FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR 16 | COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER 17 | IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN 18 | CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 19 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/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 | -------------------------------------------------------------------------------- /pkg/sys/initd/manager_mock.go: -------------------------------------------------------------------------------- 1 | package initd 2 | 3 | type mockManager struct { 4 | Component chan Component 5 | } 6 | 7 | func NewMockManager() Manager { 8 | return &mockManager{ 9 | Component: make(chan Component), 10 | } 11 | } 12 | 13 | func (mm *mockManager) ReloadDaemon() error { 14 | return nil 15 | } 16 | 17 | func (mm *mockManager) CreateComponent(name, contents string) (Component, error) { 18 | return nil, nil 19 | } 20 | 21 | func (mm *mockManager) Start(c Component) error { 22 | mm.Component <- c 23 | return nil 24 | } 25 | 26 | func (mm *mockManager) Stop(c Component) error { 27 | mm.Component <- c 28 | return nil 29 | } 30 | 31 | func (mm *mockManager) Disable(c Component) error { 32 | mm.Component <- c 33 | return nil 34 | } 35 | 36 | func (mm *mockManager) Extend(c Component) error { 37 | mm.Component <- c 38 | return nil 39 | } 40 | 41 | func (mm *mockManager) Install(c Component) error { 42 | mm.Component <- c 43 | return nil 44 | } 45 | 46 | func (mm *mockManager) Reload(c Component) error { 47 | mm.Component <- c 48 | return nil 49 | } 50 | 51 | func (mm *mockManager) Validate(c Component) error { 52 | mm.Component <- c 53 | return nil 54 | } 55 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/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 | -------------------------------------------------------------------------------- /pkg/sys/nss/shadow_test.go: -------------------------------------------------------------------------------- 1 | package nss_test 2 | 3 | import ( 4 | "fmt" 5 | "testing" 6 | 7 | . "github.com/smartystreets/goconvey/convey" 8 | 9 | "github.com/tmrts/flamingo/pkg/sys/nss" 10 | ) 11 | 12 | type fakeExecutor struct { 13 | expectedCmd string 14 | expectedResult string 15 | } 16 | 17 | func (fe *fakeExecutor) Execute(e string, args ...string) (string, error) { 18 | if e != fe.expectedCmd { 19 | return "", fmt.Errorf("Execute(%q) -> expected: %q, got: %q", e, e, fe.expectedCmd) 20 | } 21 | 22 | return fe.expectedResult, nil 23 | } 24 | 25 | func TestShadowDatabaseEntryRetrieval(t *testing.T) { 26 | Convey("Given an nss server and a user name", t, func() { 27 | uname := "root" 28 | 29 | server := &nss.Server{ 30 | Exec: &fakeExecutor{ 31 | expectedCmd: "getent", 32 | expectedResult: "root:$4$SALT$PASSWORD_HASH:16590:0:99999:7::::", 33 | }, 34 | } 35 | 36 | Convey("It should query the NSS shadow database and get its entry", func() { 37 | root, err := nss.GetShadowEntry(server, uname) 38 | So(err, ShouldBeNil) 39 | 40 | So(root.UserName, ShouldEqual, "root") 41 | So(root.PasswordHash, ShouldEqual, "$4$SALT$PASSWORD_HASH") 42 | }) 43 | }) 44 | } 45 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/examples/basic/basic.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/Sirupsen/logrus" 5 | ) 6 | 7 | var log = logrus.New() 8 | 9 | func init() { 10 | log.Formatter = new(logrus.JSONFormatter) 11 | log.Formatter = new(logrus.TextFormatter) // default 12 | log.Level = logrus.DebugLevel 13 | } 14 | 15 | func main() { 16 | defer func() { 17 | err := recover() 18 | if err != nil { 19 | log.WithFields(logrus.Fields{ 20 | "omg": true, 21 | "err": err, 22 | "number": 100, 23 | }).Fatal("The ice breaks!") 24 | } 25 | }() 26 | 27 | log.WithFields(logrus.Fields{ 28 | "animal": "walrus", 29 | "number": 8, 30 | }).Debug("Started observing beach") 31 | 32 | log.WithFields(logrus.Fields{ 33 | "animal": "walrus", 34 | "size": 10, 35 | }).Info("A group of walrus emerges from the ocean") 36 | 37 | log.WithFields(logrus.Fields{ 38 | "omg": true, 39 | "number": 122, 40 | }).Warn("The group's number increased tremendously!") 41 | 42 | log.WithFields(logrus.Fields{ 43 | "temperature": -4, 44 | }).Debug("Temperature changes") 45 | 46 | log.WithFields(logrus.Fields{ 47 | "animal": "orca", 48 | "size": 9009, 49 | }).Panic("It's over 9000!") 50 | } 51 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/gotest/utils.go: -------------------------------------------------------------------------------- 1 | // Package gotest contains internal functionality. Although this package 2 | // contains one or more exported names it is not intended for public 3 | // consumption. See the examples package for how to use this project. 4 | package gotest 5 | 6 | import ( 7 | "fmt" 8 | "runtime" 9 | "strings" 10 | ) 11 | 12 | func FormatExternalFileAndLine() string { 13 | file, line, _ := ResolveExternalCaller() 14 | if line == -1 { 15 | return "" // panic? 16 | } 17 | return fmt.Sprintf("%s:%d", file, line) 18 | } 19 | 20 | func ResolveExternalCaller() (file string, line int, name string) { 21 | var caller_id uintptr 22 | callers := runtime.Callers(0, callStack) 23 | 24 | for x := 0; x < callers; x++ { 25 | caller_id, file, line, _ = runtime.Caller(x) 26 | if strings.HasSuffix(file, "_test.go") || strings.HasSuffix(file, "_tests.go") { 27 | name = runtime.FuncForPC(caller_id).Name() 28 | return 29 | } 30 | } 31 | file, line, name = "", -1, "" 32 | return // panic? 33 | } 34 | 35 | const maxStackDepth = 100 // This had better be enough... 36 | 37 | var callStack []uintptr = make([]uintptr, maxStackDepth, maxStackDepth) 38 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/serializer_test.go: -------------------------------------------------------------------------------- 1 | package assertions 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | "testing" 7 | 8 | "github.com/smartystreets/goconvey/convey/reporting" 9 | ) 10 | 11 | func TestSerializerCreatesSerializedVersionOfAssertionResult(t *testing.T) { 12 | thing1 := Thing1{"Hi"} 13 | thing2 := Thing2{"Bye"} 14 | message := "Super-hip failure message." 15 | serializer := newSerializer() 16 | 17 | actualResult := serializer.serialize(thing1, thing2, message) 18 | 19 | expectedResult, _ := json.Marshal(reporting.FailureView{ 20 | Message: message, 21 | Expected: fmt.Sprintf("%+v", thing1), 22 | Actual: fmt.Sprintf("%+v", thing2), 23 | }) 24 | 25 | if actualResult != string(expectedResult) { 26 | t.Errorf("\nExpected: %s\nActual: %s", string(expectedResult), actualResult) 27 | } 28 | 29 | actualResult = serializer.serializeDetailed(thing1, thing2, message) 30 | expectedResult, _ = json.Marshal(reporting.FailureView{ 31 | Message: message, 32 | Expected: fmt.Sprintf("%#v", thing1), 33 | Actual: fmt.Sprintf("%#v", thing2), 34 | }) 35 | if actualResult != string(expectedResult) { 36 | t.Errorf("\nExpected: %s\nActual: %s", string(expectedResult), actualResult) 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/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 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/entry_test.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | "testing" 7 | 8 | "github.com/stretchr/testify/assert" 9 | ) 10 | 11 | func TestEntryPanicln(t *testing.T) { 12 | errBoom := fmt.Errorf("boom time") 13 | 14 | defer func() { 15 | p := recover() 16 | assert.NotNil(t, p) 17 | 18 | switch pVal := p.(type) { 19 | case *Entry: 20 | assert.Equal(t, "kaboom", pVal.Message) 21 | assert.Equal(t, errBoom, pVal.Data["err"]) 22 | default: 23 | t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal) 24 | } 25 | }() 26 | 27 | logger := New() 28 | logger.Out = &bytes.Buffer{} 29 | entry := NewEntry(logger) 30 | entry.WithField("err", errBoom).Panicln("kaboom") 31 | } 32 | 33 | func TestEntryPanicf(t *testing.T) { 34 | errBoom := fmt.Errorf("boom again") 35 | 36 | defer func() { 37 | p := recover() 38 | assert.NotNil(t, p) 39 | 40 | switch pVal := p.(type) { 41 | case *Entry: 42 | assert.Equal(t, "kaboom true", pVal.Message) 43 | assert.Equal(t, errBoom, pVal.Data["err"]) 44 | default: 45 | t.Fatalf("want type *Entry, got %T: %#v", pVal, pVal) 46 | } 47 | }() 48 | 49 | logger := New() 50 | logger.Out = &bytes.Buffer{} 51 | entry := NewEntry(logger) 52 | entry.WithField("err", errBoom).Panicf("kaboom %v", true) 53 | } 54 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/airbrake/airbrake.go: -------------------------------------------------------------------------------- 1 | package airbrake 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | 7 | "github.com/Sirupsen/logrus" 8 | "github.com/tobi/airbrake-go" 9 | ) 10 | 11 | // AirbrakeHook to send exceptions to an exception-tracking service compatible 12 | // with the Airbrake API. 13 | type airbrakeHook struct { 14 | APIKey string 15 | Endpoint string 16 | Environment string 17 | } 18 | 19 | func NewHook(endpoint, apiKey, env string) *airbrakeHook { 20 | return &airbrakeHook{ 21 | APIKey: apiKey, 22 | Endpoint: endpoint, 23 | Environment: env, 24 | } 25 | } 26 | 27 | func (hook *airbrakeHook) Fire(entry *logrus.Entry) error { 28 | airbrake.ApiKey = hook.APIKey 29 | airbrake.Endpoint = hook.Endpoint 30 | airbrake.Environment = hook.Environment 31 | 32 | var notifyErr error 33 | err, ok := entry.Data["error"].(error) 34 | if ok { 35 | notifyErr = err 36 | } else { 37 | notifyErr = errors.New(entry.Message) 38 | } 39 | 40 | airErr := airbrake.Notify(notifyErr) 41 | if airErr != nil { 42 | return fmt.Errorf("Failed to send error to Airbrake: %s", airErr) 43 | } 44 | 45 | return nil 46 | } 47 | 48 | func (hook *airbrakeHook) Levels() []logrus.Level { 49 | return []logrus.Level{ 50 | logrus.ErrorLevel, 51 | logrus.FatalLevel, 52 | logrus.PanicLevel, 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglematchers/has_same_type_as.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | import ( 19 | "fmt" 20 | "reflect" 21 | ) 22 | 23 | // HasSameTypeAs returns a matcher that matches values with exactly the same 24 | // type as the supplied prototype. 25 | func HasSameTypeAs(p interface{}) Matcher { 26 | expected := reflect.TypeOf(p) 27 | pred := func(c interface{}) error { 28 | actual := reflect.TypeOf(c) 29 | if actual != expected { 30 | return fmt.Errorf("which has type %v", actual) 31 | } 32 | 33 | return nil 34 | } 35 | 36 | return NewMatcher(pred, fmt.Sprintf("has type %v", expected)) 37 | } 38 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/reporter.go: -------------------------------------------------------------------------------- 1 | package reporting 2 | 3 | import "io" 4 | 5 | type Reporter interface { 6 | BeginStory(story *StoryReport) 7 | Enter(scope *ScopeReport) 8 | Report(r *AssertionResult) 9 | Exit() 10 | EndStory() 11 | io.Writer 12 | } 13 | 14 | type reporters struct{ collection []Reporter } 15 | 16 | func (self *reporters) BeginStory(s *StoryReport) { self.foreach(func(r Reporter) { r.BeginStory(s) }) } 17 | func (self *reporters) Enter(s *ScopeReport) { self.foreach(func(r Reporter) { r.Enter(s) }) } 18 | func (self *reporters) Report(a *AssertionResult) { self.foreach(func(r Reporter) { r.Report(a) }) } 19 | func (self *reporters) Exit() { self.foreach(func(r Reporter) { r.Exit() }) } 20 | func (self *reporters) EndStory() { self.foreach(func(r Reporter) { r.EndStory() }) } 21 | 22 | func (self *reporters) Write(contents []byte) (written int, err error) { 23 | self.foreach(func(r Reporter) { 24 | written, err = r.Write(contents) 25 | }) 26 | return written, err 27 | } 28 | 29 | func (self *reporters) foreach(action func(Reporter)) { 30 | for _, r := range self.collection { 31 | action(r) 32 | } 33 | } 34 | 35 | func NewReporters(collection ...Reporter) *reporters { 36 | self := new(reporters) 37 | self.collection = collection 38 | return self 39 | } 40 | -------------------------------------------------------------------------------- /docs/config-drive.md: -------------------------------------------------------------------------------- 1 | # Distribution via Config Drive 2 | 3 | `Flamingo` supports configuration through `OpenStack` [Config-Drive](config-drive) 4 | disk images. 5 | 6 | [config-drive]: http://docs.openstack.org/user-guide/content/enable_config_drive.html#config_drive_contents 7 | 8 | ## Contents and Format 9 | 10 | The image should be a single FAT or ISO9660 file system with the label 11 | `config-2` and the configuration data should be located at 12 | `openstack/latest/user_data`. 13 | 14 | For example, to wrap up a config named `user_data` in a config drive image: 15 | 16 | ```sh 17 | mkdir -p /tmp/new-drive/openstack/latest 18 | cp user_data /tmp/new-drive/openstack/latest/user_data 19 | mkisofs -R -V config-2 -o configdrive.iso /tmp/new-drive 20 | rm -r /tmp/new-drive 21 | ``` 22 | 23 | If on OS X, replace the `mkisofs` invocation with: 24 | 25 | ```sh 26 | hdiutil makehybrid -iso -joliet -default-volume-name config-2 -o configdrive.iso /tmp/new-drive 27 | ``` 28 | 29 | ## QEMU virtfs 30 | 31 | One exception to the above, when using QEMU it is possible to skip creating an 32 | image and use a plain directory containing the same contents: 33 | 34 | ```sh 35 | qemu-system-x86_64 \ 36 | -fsdev local,id=conf,security_model=none,readonly,path=/tmp/new-drive \ 37 | -device virtio-9p-pci,fsdev=conf,mount_tag=config-2 \ 38 | [usual qemu options here...] 39 | ``` 40 | -------------------------------------------------------------------------------- /pkg/request/client.go: -------------------------------------------------------------------------------- 1 | package request 2 | 3 | import ( 4 | "fmt" 5 | "net/http" 6 | "strings" 7 | 8 | "github.com/tmrts/flamingo/pkg/flog" 9 | ) 10 | 11 | var DefaultClient = ClientImplementation{http.DefaultClient} 12 | 13 | type Client interface { 14 | Get(string, ...Parameter) (*Response, error) 15 | } 16 | 17 | type ClientImplementation struct { 18 | HTTPClient *http.Client 19 | } 20 | 21 | func (c *ClientImplementation) performRequest(r *Request) (*Response, error) { 22 | req := r.Normalize() 23 | 24 | resp, err := c.HTTPClient.Do(req) 25 | if err != nil { 26 | return nil, err 27 | } 28 | 29 | if !strings.HasPrefix(resp.Status, "20") { 30 | flog.Debug("Failed to get a proper HTTP response", 31 | flog.Fields{ 32 | Error: err, 33 | Event: "performRequest", 34 | }, 35 | flog.Details{ 36 | "url": r.URL, 37 | "method": r.Method, 38 | "headers": r.Headers, 39 | }, 40 | ) 41 | return nil, fmt.Errorf("request: bad status code %v", resp.StatusCode) 42 | } 43 | 44 | return &Response{resp}, nil 45 | } 46 | 47 | func (c *ClientImplementation) Perform(method, url string, params ...Parameter) (*Response, error) { 48 | req := &Request{ 49 | URL: url, 50 | Method: method, 51 | Headers: http.Header{}, 52 | } 53 | 54 | for _, parametrize := range params { 55 | parametrize(req) 56 | } 57 | 58 | return c.performRequest(req) 59 | } 60 | -------------------------------------------------------------------------------- /pkg/datasrc/provider/openstack/metadata.go: -------------------------------------------------------------------------------- 1 | package openstack 2 | 3 | import ( 4 | "strings" 5 | 6 | "github.com/tmrts/flamingo/pkg/datasrc/metadata" 7 | "github.com/tmrts/flamingo/pkg/sys/ssh" 8 | ) 9 | 10 | type file struct { 11 | ContentPath string `json:"content_path"` 12 | Path string `json:"content_path"` 13 | } 14 | 15 | type Metadata struct { 16 | Name string `json:"name"` 17 | UUID string `json:"uuid"` 18 | Hostname string `json:"hostname"` 19 | ProjectID string `json:"project_id"` 20 | LaunchIndex int `json:"launch_index"` 21 | AvailabilityZone string `json:"availability_zone"` 22 | PublicKeys map[string]string `json:"public_keys"` 23 | Meta map[string]string `json:"meta"` 24 | Files []file `json:"files"` 25 | } 26 | 27 | // Digest extracts the important parts of meta-data and returns it. 28 | func (md *Metadata) Digest() metadata.Digest { 29 | sshKeys := make(map[string][]ssh.Key) 30 | 31 | for usr, rawKeys := range md.PublicKeys { 32 | keys := strings.Split(rawKeys, "\n") 33 | 34 | for _, key := range keys { 35 | if key != "" { 36 | sshKeys[usr] = append(sshKeys[usr], ssh.Key(key)) 37 | } 38 | } 39 | } 40 | 41 | return metadata.Digest{ 42 | Hostname: md.Hostname, 43 | SSHKeys: sshKeys, 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /pkg/sys/nss/group.go: -------------------------------------------------------------------------------- 1 | package nss 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | ) 7 | 8 | // GroupEntry is the representation of Name Switch Service 9 | // 'group' database entry fields. 10 | type GroupEntry struct { 11 | GroupName string 12 | GID int 13 | IsSystemGroup bool 14 | 15 | Members []string 16 | } 17 | 18 | // Parses NSS GroupDatabase Entry. 19 | // Example: 20 | // group:x:1:user1,user2 is turned into: 21 | // Group { 22 | // Name: "group", 23 | // GID: "1", 24 | // Members: []string {"user1", "user2"}, 25 | // IsSystemAccount: true, 26 | // } 27 | func parseGroupEntry(groupEntry string) *GroupEntry { 28 | groupInfo := strings.Split(groupEntry, ":") 29 | groupID, _ := strconv.Atoi(groupInfo[2]) 30 | 31 | groupMembers := strings.Split(groupInfo[3], ",") 32 | 33 | return &GroupEntry{ 34 | GroupName: groupInfo[0], 35 | GID: groupID, 36 | IsSystemGroup: groupID < 1000, 37 | Members: groupMembers, 38 | } 39 | } 40 | 41 | // GetGroup queries the Name Switch Service 'group' Database for 42 | // a given group key. Group key is usually the name of that group. 43 | // It returns the parsed group entry. 44 | func GetGroupEntry(s Service, groupKey string) (*GroupEntry, error) { 45 | entry, err := s.GetEntryFrom(GroupDatabase, groupKey) 46 | if err != nil { 47 | return nil, err 48 | } 49 | 50 | return parseGroupEntry(entry), nil 51 | } 52 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/formatters/logstash/logstash_test.go: -------------------------------------------------------------------------------- 1 | package logstash 2 | 3 | import ( 4 | "bytes" 5 | "encoding/json" 6 | "github.com/Sirupsen/logrus" 7 | "github.com/stretchr/testify/assert" 8 | "testing" 9 | ) 10 | 11 | func TestLogstashFormatter(t *testing.T) { 12 | assert := assert.New(t) 13 | 14 | lf := LogstashFormatter{Type: "abc"} 15 | 16 | fields := logrus.Fields{ 17 | "message": "def", 18 | "level": "ijk", 19 | "type": "lmn", 20 | "one": 1, 21 | "pi": 3.14, 22 | "bool": true, 23 | } 24 | 25 | entry := logrus.WithFields(fields) 26 | entry.Message = "msg" 27 | entry.Level = logrus.InfoLevel 28 | 29 | b, _ := lf.Format(entry) 30 | 31 | var data map[string]interface{} 32 | dec := json.NewDecoder(bytes.NewReader(b)) 33 | dec.UseNumber() 34 | dec.Decode(&data) 35 | 36 | // base fields 37 | assert.Equal(json.Number("1"), data["@version"]) 38 | assert.NotEmpty(data["@timestamp"]) 39 | assert.Equal("abc", data["type"]) 40 | assert.Equal("msg", data["message"]) 41 | assert.Equal("info", data["level"]) 42 | 43 | // substituted fields 44 | assert.Equal("def", data["fields.message"]) 45 | assert.Equal("ijk", data["fields.level"]) 46 | assert.Equal("lmn", data["fields.type"]) 47 | 48 | // formats 49 | assert.Equal(json.Number("1"), data["one"]) 50 | assert.Equal(json.Number("3.14"), data["pi"]) 51 | assert.Equal(true, data["bool"]) 52 | } 53 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/LICENSE.md: -------------------------------------------------------------------------------- 1 | Copyright (c) 2015 SmartyStreets, LLC 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy 4 | of this software and associated documentation files (the "Software"), to deal 5 | in the Software without restriction, including without limitation the rights 6 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 7 | copies of the Software, and to permit persons to whom the Software is 8 | furnished to do so, subject to the following conditions: 9 | 10 | The above copyright notice and this permission notice shall be included in all 11 | copies or substantial portions of the Software. 12 | 13 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 14 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 15 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 16 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 17 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 18 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 19 | SOFTWARE. 20 | 21 | NOTE: Various optional and subordinate components carry their own licensing 22 | requirements and restrictions. Use of those components is subject to the terms 23 | and conditions outlined the respective license of each component. 24 | -------------------------------------------------------------------------------- /pkg/datasrc/metadata/metadata.go: -------------------------------------------------------------------------------- 1 | package metadata 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | 7 | "github.com/tmrts/flamingo/pkg/sys/ssh" 8 | ) 9 | 10 | // Version is represents the version of a meta-data. 11 | type Version string 12 | 13 | // Interface represents the meta-data object returned 14 | // by data sources that can be summarized into a meta-data digest. 15 | type Interface interface { 16 | Digest() Digest 17 | } 18 | 19 | type Provider interface { 20 | FetchMetadata() (*Digest, error) 21 | } 22 | 23 | // Digest contains the parts of a meta-data object that are 24 | // used by Flamingo for contextualization of the instance. 25 | type Digest struct { 26 | Hostname string 27 | 28 | NetworkInterfaces []NetworkInterface 29 | 30 | SSHKeys map[string][]ssh.Key 31 | } 32 | 33 | func (d *Digest) String() string { 34 | return fmt.Sprintf("\nHostname: %v\nInterfaces: %v\n", d.Hostname, d.NetworkInterfaces) 35 | } 36 | 37 | func (d *Digest) PrimaryNetworkInterface() *NetworkInterface { 38 | return &d.NetworkInterfaces[0] 39 | } 40 | 41 | type NetworkInterface struct { 42 | NetworkName string 43 | 44 | PrivateIP net.IP 45 | 46 | PublicIPs []net.IP 47 | } 48 | 49 | func (i NetworkInterface) String() string { 50 | return fmt.Sprintf("\nNetworkName: %v\nPrivateIP: %v\nPublicIPs: %v\n", i.NetworkName, i.PrivateIP, i.PublicIPs) 51 | } 52 | 53 | type Disk struct { 54 | Mode string 55 | Type string 56 | DeviceName string 57 | } 58 | -------------------------------------------------------------------------------- /pkg/sys/executor_mock.go: -------------------------------------------------------------------------------- 1 | package sys 2 | 3 | type MockExecutor struct { 4 | Exec chan string 5 | Args chan []string 6 | 7 | OutStr chan string 8 | OutErr chan error 9 | } 10 | 11 | func NewMockExecutor() *MockExecutor { 12 | return &MockExecutor{ 13 | Exec: make(chan string, 1), 14 | Args: make(chan []string, 1), 15 | 16 | OutStr: make(chan string, 1), 17 | OutErr: make(chan error, 1), 18 | } 19 | } 20 | 21 | func (me *MockExecutor) Execute(exec string, args ...string) (string, error) { 22 | me.Exec <- exec 23 | me.Args <- args 24 | 25 | return <-me.OutStr, <-me.OutErr 26 | } 27 | 28 | type StubExecutor struct { 29 | Exec chan string 30 | Args chan []string 31 | 32 | out string 33 | err error 34 | } 35 | 36 | func NewStubExecutor(out string, err error) *StubExecutor { 37 | return &StubExecutor{ 38 | Exec: make(chan string, 1), 39 | Args: make(chan []string, 1), 40 | 41 | out: out, 42 | err: err, 43 | } 44 | } 45 | 46 | func (se *StubExecutor) Execute(exec string, args ...string) (string, error) { 47 | se.Exec <- exec 48 | se.Args <- args 49 | 50 | return se.out, se.err 51 | } 52 | 53 | type funcExecutor func(string, ...string) (string, error) 54 | 55 | func (f funcExecutor) Execute(cmd string, args ...string) (string, error) { 56 | return f(cmd, args...) 57 | } 58 | 59 | func NewFuncExecutor(fn func(string, ...string) (string, error)) Executor { 60 | var exec funcExecutor = fn 61 | 62 | return exec 63 | } 64 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglemock/mock_object.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglemock 17 | 18 | // MockObject is an interface that mock object implementations must conform to 19 | // in order to register expectations with and hand off calls to a 20 | // MockController. Users should not interact with this interface directly. 21 | type MockObject interface { 22 | // Oglemock_Id returns an identifier for the mock object that is guaranteed 23 | // to be unique within the process at least until the mock object is garbage 24 | // collected. 25 | Oglemock_Id() uintptr 26 | 27 | // Oglemock_Description returns a description of the mock object that may be 28 | // helpful in test failure messages. 29 | Oglemock_Description() string 30 | } 31 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglemock/error_reporter.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglemock 17 | 18 | // ErrorReporter is an interface that wraps methods for reporting errors that 19 | // should cause test failures. 20 | type ErrorReporter interface { 21 | // Report that some failure (e.g. an unsatisfied expectation) occurred. If 22 | // known, fileName and lineNumber should contain information about where it 23 | // occurred. The test may continue if the test framework supports it. 24 | ReportError(fileName string, lineNumber int, err error) 25 | 26 | // Like ReportError, but the test should be halted immediately. It is assumed 27 | // that this method does not return. 28 | ReportFatalError(fileName string, lineNumber int, err error) 29 | } 30 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/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 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglematchers/transform_description.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | // transformDescription returns a matcher that is equivalent to the supplied 19 | // one, except that it has the supplied description instead of the one attached 20 | // to the existing matcher. 21 | func transformDescription(m Matcher, newDesc string) Matcher { 22 | return &transformDescriptionMatcher{newDesc, m} 23 | } 24 | 25 | type transformDescriptionMatcher struct { 26 | desc string 27 | wrappedMatcher Matcher 28 | } 29 | 30 | func (m *transformDescriptionMatcher) Description() string { 31 | return m.desc 32 | } 33 | 34 | func (m *transformDescriptionMatcher) Matches(c interface{}) error { 35 | return m.wrappedMatcher.Matches(c) 36 | } 37 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/no_cases.test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers_test 17 | 18 | import ( 19 | "fmt" 20 | . "github.com/smartystreets/assertions/internal/ogletest" 21 | "testing" 22 | ) 23 | 24 | func TestNoCases(t *testing.T) { RunTests(t) } 25 | 26 | //////////////////////////////////////////////////////////////////////// 27 | // Helpers 28 | //////////////////////////////////////////////////////////////////////// 29 | 30 | type NoCasesTest struct { 31 | } 32 | 33 | func init() { RegisterTestSuite(&NoCasesTest{}) } 34 | 35 | func (t *NoCasesTest) SetUpTestSuite() { 36 | fmt.Println("SetUpTestSuite run!") 37 | } 38 | 39 | func (t *NoCasesTest) TearDownTestSuite() { 40 | fmt.Println("TearDownTestSuite run!") 41 | } 42 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/focused_execution_test.go: -------------------------------------------------------------------------------- 1 | package convey 2 | 3 | import "testing" 4 | 5 | func TestFocusOnlyAtTopLevel(t *testing.T) { 6 | output := prepare() 7 | 8 | FocusConvey("hi", t, func() { 9 | output += "done" 10 | }) 11 | 12 | expectEqual(t, "done", output) 13 | } 14 | 15 | func TestFocus(t *testing.T) { 16 | output := prepare() 17 | 18 | FocusConvey("hi", t, func() { 19 | output += "1" 20 | 21 | Convey("bye", func() { 22 | output += "2" 23 | }) 24 | }) 25 | 26 | expectEqual(t, "1", output) 27 | } 28 | 29 | func TestNestedFocus(t *testing.T) { 30 | output := prepare() 31 | 32 | FocusConvey("hi", t, func() { 33 | output += "1" 34 | 35 | Convey("This shouldn't run", func() { 36 | output += "boink!" 37 | }) 38 | 39 | FocusConvey("This should run", func() { 40 | output += "2" 41 | 42 | FocusConvey("The should run too", func() { 43 | output += "3" 44 | 45 | }) 46 | 47 | Convey("The should NOT run", func() { 48 | output += "blah blah blah!" 49 | }) 50 | }) 51 | }) 52 | 53 | expectEqual(t, "123", output) 54 | } 55 | 56 | func TestForgotTopLevelFocus(t *testing.T) { 57 | output := prepare() 58 | 59 | Convey("1", t, func() { 60 | output += "1" 61 | 62 | FocusConvey("This will be run because the top-level lacks Focus", func() { 63 | output += "2" 64 | }) 65 | 66 | Convey("3", func() { 67 | output += "3" 68 | }) 69 | }) 70 | 71 | expectEqual(t, "1213", output) 72 | } 73 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/formatters/logstash/logstash.go: -------------------------------------------------------------------------------- 1 | package logstash 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | 7 | "github.com/Sirupsen/logrus" 8 | ) 9 | 10 | // Formatter generates json in logstash format. 11 | // Logstash site: http://logstash.net/ 12 | type LogstashFormatter struct { 13 | Type string // if not empty use for logstash type field. 14 | 15 | // TimestampFormat sets the format used for timestamps. 16 | TimestampFormat string 17 | } 18 | 19 | func (f *LogstashFormatter) Format(entry *logrus.Entry) ([]byte, error) { 20 | entry.Data["@version"] = 1 21 | 22 | if f.TimestampFormat == "" { 23 | f.TimestampFormat = logrus.DefaultTimestampFormat 24 | } 25 | 26 | entry.Data["@timestamp"] = entry.Time.Format(f.TimestampFormat) 27 | 28 | // set message field 29 | v, ok := entry.Data["message"] 30 | if ok { 31 | entry.Data["fields.message"] = v 32 | } 33 | entry.Data["message"] = entry.Message 34 | 35 | // set level field 36 | v, ok = entry.Data["level"] 37 | if ok { 38 | entry.Data["fields.level"] = v 39 | } 40 | entry.Data["level"] = entry.Level.String() 41 | 42 | // set type field 43 | if f.Type != "" { 44 | v, ok = entry.Data["type"] 45 | if ok { 46 | entry.Data["fields.type"] = v 47 | } 48 | entry.Data["type"] = f.Type 49 | } 50 | 51 | serialized, err := json.Marshal(entry.Data) 52 | if err != nil { 53 | return nil, fmt.Errorf("Failed to marshal fields to JSON, %v", err) 54 | } 55 | return append(serialized, '\n'), nil 56 | } 57 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/printer.go: -------------------------------------------------------------------------------- 1 | package reporting 2 | 3 | import ( 4 | "fmt" 5 | "io" 6 | "strings" 7 | ) 8 | 9 | type Printer struct { 10 | out io.Writer 11 | prefix string 12 | } 13 | 14 | func (self *Printer) Println(message string, values ...interface{}) { 15 | formatted := self.format(message, values...) + newline 16 | self.out.Write([]byte(formatted)) 17 | } 18 | 19 | func (self *Printer) Print(message string, values ...interface{}) { 20 | formatted := self.format(message, values...) 21 | self.out.Write([]byte(formatted)) 22 | } 23 | 24 | func (self *Printer) Insert(text string) { 25 | self.out.Write([]byte(text)) 26 | } 27 | 28 | func (self *Printer) format(message string, values ...interface{}) string { 29 | var formatted string 30 | if len(values) == 0 { 31 | formatted = self.prefix + message 32 | } else { 33 | formatted = self.prefix + fmt.Sprintf(message, values...) 34 | } 35 | indented := strings.Replace(formatted, newline, newline+self.prefix, -1) 36 | return strings.TrimRight(indented, space) 37 | } 38 | 39 | func (self *Printer) Indent() { 40 | self.prefix += pad 41 | } 42 | 43 | func (self *Printer) Dedent() { 44 | if len(self.prefix) >= padLength { 45 | self.prefix = self.prefix[:len(self.prefix)-padLength] 46 | } 47 | } 48 | 49 | func NewPrinter(out io.Writer) *Printer { 50 | self := new(Printer) 51 | self.out = out 52 | return self 53 | } 54 | 55 | const space = " " 56 | const pad = space + space 57 | const padLength = len(pad) 58 | -------------------------------------------------------------------------------- /pkg/sys/nss/passwd.go: -------------------------------------------------------------------------------- 1 | package nss 2 | 3 | import ( 4 | "strconv" 5 | "strings" 6 | ) 7 | 8 | // PasswdEntry is the representation of Name Switch Service 9 | // 'passwd' database entry fields. 10 | type PasswdEntry struct { 11 | UserName string 12 | UID int 13 | GID int 14 | GECOS string 15 | HomeDir string 16 | DefaultShell string 17 | IsSystemAccount bool 18 | } 19 | 20 | // Parses NSS PasswdDatabase Entry. 21 | // Example: 22 | // user:x:1000:1000:A normal user.:/home/user:/bin/bash is turned into: 23 | // User { 24 | // Name: "group", 25 | // UID: "1000", 26 | // PrimaryGroup: "1000", 27 | // Description: "A normal user", 28 | // HomeDir: "/home/user", 29 | // DefaultShell: "/bin/bash", 30 | // IsSystemAccount: false, 31 | // } 32 | func parsePasswdEntry(passwdEntry string) *PasswdEntry { 33 | userInfo := strings.Split(passwdEntry, ":") 34 | userID, _ := strconv.Atoi(userInfo[2]) 35 | groupID, _ := strconv.Atoi(userInfo[3]) 36 | 37 | return &PasswdEntry{ 38 | UserName: userInfo[0], 39 | UID: userID, 40 | GID: groupID, 41 | GECOS: userInfo[4], 42 | HomeDir: userInfo[5], 43 | DefaultShell: userInfo[5], 44 | IsSystemAccount: userID < 1000, 45 | } 46 | } 47 | 48 | func GetPasswdEntry(s Service, key string) (*PasswdEntry, error) { 49 | ent, err := s.GetEntryFrom(UserDatabase, key) 50 | if err != nil { 51 | return nil, err 52 | } 53 | 54 | return parsePasswdEntry(ent), nil 55 | } 56 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglematchers/has_substr.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | import ( 19 | "errors" 20 | "fmt" 21 | "reflect" 22 | "strings" 23 | ) 24 | 25 | // HasSubstr returns a matcher that matches strings containing s as a 26 | // substring. 27 | func HasSubstr(s string) Matcher { 28 | return NewMatcher( 29 | func(c interface{}) error { return hasSubstr(s, c) }, 30 | fmt.Sprintf("has substring \"%s\"", s)) 31 | } 32 | 33 | func hasSubstr(needle string, c interface{}) error { 34 | v := reflect.ValueOf(c) 35 | if v.Kind() != reflect.String { 36 | return NewFatalError("which is not a string") 37 | } 38 | 39 | // Perform the substring search. 40 | haystack := v.String() 41 | if strings.Contains(haystack, needle) { 42 | return nil 43 | } 44 | 45 | return errors.New("") 46 | } 47 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglemock/action.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglemock 17 | 18 | import ( 19 | "reflect" 20 | ) 21 | 22 | // Action represents an action to be taken in response to a call to a mock 23 | // method. 24 | type Action interface { 25 | // Set the signature of the function with which this action is being used. 26 | // This must be called before Invoke is called. 27 | SetSignature(signature reflect.Type) error 28 | 29 | // Invoke runs the specified action, given the arguments to the mock method. 30 | // It returns zero or more values that may be treated as the return values of 31 | // the method. If the action doesn't return any values, it may return the nil 32 | // slice. 33 | // 34 | // You must call SetSignature before calling Invoke. 35 | Invoke(methodArgs []interface{}) []interface{} 36 | } 37 | -------------------------------------------------------------------------------- /pkg/datasrc/provider/openstack/openstack.go: -------------------------------------------------------------------------------- 1 | package openstack 2 | 3 | import ( 4 | "github.com/tmrts/flamingo/pkg/datasrc/metadata" 5 | "github.com/tmrts/flamingo/pkg/datasrc/provider" 6 | "github.com/tmrts/flamingo/pkg/datasrc/userdata" 7 | "github.com/tmrts/flamingo/pkg/request" 8 | ) 9 | 10 | const ( 11 | LatestSupportedMetadataVersion string = "2012-08-10" 12 | 13 | MetadataURL provider.FormatURL = "http://169.254.169.254/openstack/%s/%s" 14 | ) 15 | 16 | type MetadataService struct { 17 | URL provider.FormatURL 18 | } 19 | 20 | // FetchMetadata retrieves meta_data.json from OpenStack Metadata 21 | // service and parses it. 22 | func (s *MetadataService) FetchMetadata() (*metadata.Digest, error) { 23 | var m Metadata 24 | 25 | url := s.URL.Fill(LatestSupportedMetadataVersion, "meta_data.json") 26 | response, err := request.Get(url) 27 | if err != nil { 28 | return nil, err 29 | } 30 | 31 | err = response.JSON(&m) 32 | if err != nil { 33 | return nil, err 34 | } 35 | 36 | digest := m.Digest() 37 | 38 | return &digest, nil 39 | } 40 | 41 | // FetchMetadata retrieves meta_data.json from OpenStack Metadata 42 | // service and parses it. 43 | func (s *MetadataService) FetchUserdata() (userdata.Map, error) { 44 | url := s.URL.Fill(LatestSupportedMetadataVersion, "user_data") 45 | response, err := request.Get(url) 46 | if err != nil { 47 | return nil, err 48 | } 49 | 50 | buf, err := response.Text() 51 | if err != nil { 52 | return nil, err 53 | } 54 | 55 | u := userdata.Map{ 56 | "user-data": string(buf), 57 | } 58 | 59 | return u, nil 60 | } 61 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglematchers/greater_than.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | import ( 19 | "fmt" 20 | "reflect" 21 | ) 22 | 23 | // GreaterThan returns a matcher that matches integer, floating point, or 24 | // strings values v such that v > x. Comparison is not defined between numeric 25 | // and string types, but is defined between all integer and floating point 26 | // types. 27 | // 28 | // x must itself be an integer, floating point, or string type; otherwise, 29 | // GreaterThan will panic. 30 | func GreaterThan(x interface{}) Matcher { 31 | desc := fmt.Sprintf("greater than %v", x) 32 | 33 | // Special case: make it clear that strings are strings. 34 | if reflect.TypeOf(x).Kind() == reflect.String { 35 | desc = fmt.Sprintf("greater than \"%s\"", x) 36 | } 37 | 38 | return transformDescription(Not(LessOrEqual(x)), desc) 39 | } 40 | -------------------------------------------------------------------------------- /pkg/sys/initd/systemd/systemd_test.go: -------------------------------------------------------------------------------- 1 | package systemd_test 2 | 3 | import ( 4 | "os" 5 | "testing" 6 | 7 | . "github.com/smartystreets/goconvey/convey" 8 | . "github.com/tmrts/flamingo/pkg/util/testutil" 9 | 10 | "github.com/tmrts/flamingo/pkg/sys" 11 | "github.com/tmrts/flamingo/pkg/sys/initd/systemd" 12 | ) 13 | 14 | func TestSystemdInitManager(t *testing.T) { 15 | Convey("Given a systemd implementation", t, func() { 16 | exec := sys.NewStubExecutor("", nil) 17 | sysd := &systemd.Implementation{ 18 | UnitDir: os.TempDir(), 19 | Exec: exec, 20 | } 21 | 22 | Convey("Given a systemd unit", func() { 23 | testUnit := systemd.NewUnit("testUnit", "here") 24 | 25 | Convey("It should enable the component", func() { 26 | sysd.Install(testUnit) 27 | 28 | So(<-exec.Exec, ShouldEqual, "systemctl") 29 | So(<-exec.Args, ShouldConsistOf, "enable", "--system", testUnit.Name()) 30 | }) 31 | 32 | Convey("It should disable the component", func() { 33 | sysd.Disable(testUnit) 34 | 35 | So(<-exec.Exec, ShouldEqual, "systemctl") 36 | So(<-exec.Args, ShouldConsistOf, "disable", testUnit.Name()) 37 | }) 38 | 39 | Convey("It should start the component", func() { 40 | sysd.Start(testUnit) 41 | 42 | So(<-exec.Exec, ShouldEqual, "systemctl") 43 | So(<-exec.Args, ShouldConsistOf, "start", testUnit.Name()) 44 | }) 45 | 46 | Convey("It should stop the component", func() { 47 | sysd.Stop(testUnit) 48 | 49 | So(<-exec.Exec, ShouldEqual, "systemctl") 50 | So(<-exec.Args, ShouldConsistOf, "stop", testUnit.Name()) 51 | }) 52 | }) 53 | }) 54 | } 55 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/papertrail.go: -------------------------------------------------------------------------------- 1 | package logrus_papertrail 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "os" 7 | "time" 8 | 9 | "github.com/Sirupsen/logrus" 10 | ) 11 | 12 | const ( 13 | format = "Jan 2 15:04:05" 14 | ) 15 | 16 | // PapertrailHook to send logs to a logging service compatible with the Papertrail API. 17 | type PapertrailHook struct { 18 | Host string 19 | Port int 20 | AppName string 21 | UDPConn net.Conn 22 | } 23 | 24 | // NewPapertrailHook creates a hook to be added to an instance of logger. 25 | func NewPapertrailHook(host string, port int, appName string) (*PapertrailHook, error) { 26 | conn, err := net.Dial("udp", fmt.Sprintf("%s:%d", host, port)) 27 | return &PapertrailHook{host, port, appName, conn}, err 28 | } 29 | 30 | // Fire is called when a log event is fired. 31 | func (hook *PapertrailHook) Fire(entry *logrus.Entry) error { 32 | date := time.Now().Format(format) 33 | msg, _ := entry.String() 34 | payload := fmt.Sprintf("<22> %s %s: %s", date, hook.AppName, msg) 35 | 36 | bytesWritten, err := hook.UDPConn.Write([]byte(payload)) 37 | if err != nil { 38 | fmt.Fprintf(os.Stderr, "Unable to send log line to Papertrail via UDP. Wrote %d bytes before error: %v", bytesWritten, err) 39 | return err 40 | } 41 | 42 | return nil 43 | } 44 | 45 | // Levels returns the available logging levels. 46 | func (hook *PapertrailHook) Levels() []logrus.Level { 47 | return []logrus.Level{ 48 | logrus.PanicLevel, 49 | logrus.FatalLevel, 50 | logrus.ErrorLevel, 51 | logrus.WarnLevel, 52 | logrus.InfoLevel, 53 | logrus.DebugLevel, 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglematchers/greater_or_equal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | import ( 19 | "fmt" 20 | "reflect" 21 | ) 22 | 23 | // GreaterOrEqual returns a matcher that matches integer, floating point, or 24 | // strings values v such that v >= x. Comparison is not defined between numeric 25 | // and string types, but is defined between all integer and floating point 26 | // types. 27 | // 28 | // x must itself be an integer, floating point, or string type; otherwise, 29 | // GreaterOrEqual will panic. 30 | func GreaterOrEqual(x interface{}) Matcher { 31 | desc := fmt.Sprintf("greater than or equal to %v", x) 32 | 33 | // Special case: make it clear that strings are strings. 34 | if reflect.TypeOf(x).Kind() == reflect.String { 35 | desc = fmt.Sprintf("greater than or equal to \"%s\"", x) 36 | } 37 | 38 | return transformDescription(Not(LessThan(x)), desc) 39 | } 40 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/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 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglematchers/new_matcher.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | // Create a matcher with the given description and predicate function, which 19 | // will be invoked to handle calls to Matchers. 20 | // 21 | // Using this constructor may be a convenience over defining your own type that 22 | // implements Matcher if you do not need any logic in your Description method. 23 | func NewMatcher( 24 | predicate func(interface{}) error, 25 | description string) Matcher { 26 | return &predicateMatcher{ 27 | predicate: predicate, 28 | description: description, 29 | } 30 | } 31 | 32 | type predicateMatcher struct { 33 | predicate func(interface{}) error 34 | description string 35 | } 36 | 37 | func (pm *predicateMatcher) Matches(c interface{}) error { 38 | return pm.predicate(c) 39 | } 40 | 41 | func (pm *predicateMatcher) Description() string { 42 | return pm.description 43 | } 44 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/ogletest/assert_that.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package ogletest 17 | 18 | import ( 19 | "github.com/smartystreets/assertions/internal/oglematchers" 20 | ) 21 | 22 | func assertThat( 23 | x interface{}, 24 | m oglematchers.Matcher, 25 | depth int, 26 | errorParts []interface{}) { 27 | passed := expectThat(x, m, depth+1, errorParts) 28 | if !passed { 29 | AbortTest() 30 | } 31 | } 32 | 33 | // AssertThat is identical to ExpectThat, except that in the event of failure 34 | // it halts the currently running test immediately. It is thus useful for 35 | // things like bounds checking: 36 | // 37 | // someSlice := [...] 38 | // AssertEq(1, len(someSlice)) // Protects next line from panicking. 39 | // ExpectEq("taco", someSlice[0]) 40 | // 41 | func AssertThat( 42 | x interface{}, 43 | m oglematchers.Matcher, 44 | errorParts ...interface{}) { 45 | assertThat(x, m, 1, errorParts) 46 | } 47 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/problems_test.go: -------------------------------------------------------------------------------- 1 | package reporting 2 | 3 | import ( 4 | "strings" 5 | "testing" 6 | ) 7 | 8 | func TestNoopProblemReporterActions(t *testing.T) { 9 | file, reporter := setup() 10 | reporter.BeginStory(nil) 11 | reporter.Enter(nil) 12 | reporter.Exit() 13 | expected := "" 14 | actual := file.String() 15 | if expected != actual { 16 | t.Errorf("Expected: '(blank)'\nActual: '%s'", actual) 17 | } 18 | } 19 | 20 | func TestReporterPrintsFailuresAndErrorsAtTheEndOfTheStory(t *testing.T) { 21 | file, reporter := setup() 22 | reporter.Report(NewFailureReport("failed")) 23 | reporter.Report(NewErrorReport("error")) 24 | reporter.Report(NewSuccessReport()) 25 | reporter.EndStory() 26 | 27 | result := file.String() 28 | if !strings.Contains(result, "Errors:\n") { 29 | t.Errorf("Expected errors, found none.") 30 | } 31 | if !strings.Contains(result, "Failures:\n") { 32 | t.Errorf("Expected failures, found none.") 33 | } 34 | 35 | // Each stack trace looks like: `* /path/to/file.go`, so look for `* `. 36 | // With go 1.4+ there is a line in some stack traces that looks like this: 37 | // `testing.(*M).Run(0x2082d60a0, 0x25b7c0)` 38 | // So we can't just look for "*" anymore. 39 | problemCount := strings.Count(result, "* ") 40 | if problemCount != 2 { 41 | t.Errorf("Expected one failure and one error (total of 2 '*' characters). Got %d", problemCount) 42 | } 43 | } 44 | 45 | func setup() (file *memoryFile, reporter *problem) { 46 | monochrome() 47 | file = newMemoryFile() 48 | printer := NewPrinter(file) 49 | reporter = NewProblemReporter(printer) 50 | return 51 | } 52 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/bugsnag/bugsnag_test.go: -------------------------------------------------------------------------------- 1 | package logrus_bugsnag 2 | 3 | import ( 4 | "encoding/json" 5 | "errors" 6 | "io/ioutil" 7 | "net/http" 8 | "net/http/httptest" 9 | "testing" 10 | "time" 11 | 12 | "github.com/Sirupsen/logrus" 13 | "github.com/bugsnag/bugsnag-go" 14 | ) 15 | 16 | type notice struct { 17 | Events []struct { 18 | Exceptions []struct { 19 | Message string `json:"message"` 20 | } `json:"exceptions"` 21 | } `json:"events"` 22 | } 23 | 24 | func TestNoticeReceived(t *testing.T) { 25 | msg := make(chan string, 1) 26 | expectedMsg := "foo" 27 | 28 | ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 29 | var notice notice 30 | data, _ := ioutil.ReadAll(r.Body) 31 | if err := json.Unmarshal(data, ¬ice); err != nil { 32 | t.Error(err) 33 | } 34 | _ = r.Body.Close() 35 | 36 | msg <- notice.Events[0].Exceptions[0].Message 37 | })) 38 | defer ts.Close() 39 | 40 | hook := &bugsnagHook{} 41 | 42 | bugsnag.Configure(bugsnag.Configuration{ 43 | Endpoint: ts.URL, 44 | ReleaseStage: "production", 45 | APIKey: "12345678901234567890123456789012", 46 | Synchronous: true, 47 | }) 48 | 49 | log := logrus.New() 50 | log.Hooks.Add(hook) 51 | 52 | log.WithFields(logrus.Fields{ 53 | "error": errors.New(expectedMsg), 54 | }).Error("Bugsnag will not see this string") 55 | 56 | select { 57 | case received := <-msg: 58 | if received != expectedMsg { 59 | t.Errorf("Unexpected message received: %s", received) 60 | } 61 | case <-time.After(time.Second): 62 | t.Error("Timed out; no notice received by Bugsnag API") 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglemock/do_all.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglemock 17 | 18 | import ( 19 | "fmt" 20 | "reflect" 21 | ) 22 | 23 | // Create an Action that invokes the supplied actions one after another. The 24 | // return values from the final action are used; others are ignored. 25 | func DoAll(first Action, others ...Action) Action { 26 | return &doAll{ 27 | wrapped: append([]Action{first}, others...), 28 | } 29 | } 30 | 31 | type doAll struct { 32 | wrapped []Action 33 | } 34 | 35 | func (a *doAll) SetSignature(signature reflect.Type) (err error) { 36 | for i, w := range a.wrapped { 37 | err = w.SetSignature(signature) 38 | if err != nil { 39 | err = fmt.Errorf("Action %v: %v", i, err) 40 | return 41 | } 42 | } 43 | 44 | return 45 | } 46 | 47 | func (a *doAll) Invoke(methodArgs []interface{}) (rets []interface{}) { 48 | for _, w := range a.wrapped { 49 | rets = w.Invoke(methodArgs) 50 | } 51 | 52 | return 53 | } 54 | -------------------------------------------------------------------------------- /pkg/util/arg_test.go: -------------------------------------------------------------------------------- 1 | package util_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | 8 | "github.com/tmrts/flamingo/pkg/util" 9 | "github.com/tmrts/flamingo/pkg/util/testutil" 10 | ) 11 | 12 | func TestStructToArgsConversion(t *testing.T) { 13 | Convey("Given a struct with `flag` tags", t, func() { 14 | fakeUserInfo := struct { 15 | UserID string `flag:"uid"` 16 | Comment string `flag:"comment"` 17 | IsSystemAccount bool `flag:"system"` 18 | Items []string `flag:"items"` 19 | }{ 20 | UserID: "990", 21 | Comment: "This is a Comment.", 22 | IsSystemAccount: true, 23 | Items: []string{"item1", "item2", "item3"}, 24 | } 25 | 26 | Convey("It should serialize the struct into flag form with the given flag tags", func() { 27 | argSlice := util.GetArgumentFormOfStruct(fakeUserInfo) 28 | 29 | expectedArgs := []string{ 30 | "--uid=990", 31 | "--system", 32 | "--comment=This is a Comment.", 33 | "--items=item1,item2,item3", 34 | } 35 | 36 | So(argSlice, testutil.ShouldSetEqual, expectedArgs) 37 | }) 38 | }) 39 | 40 | Convey("Given an uninitialized struct with `flag` tags", t, func() { 41 | fakeUserInfo := struct { 42 | IsAvailable bool `flag:"available"` 43 | Item string `flag:"item"` 44 | Items []string `flag:"items"` 45 | UserID int `flag:"id"` 46 | UserIDs []int `flag:"ids"` 47 | }{} 48 | 49 | Convey("It should return an empty slice", func() { 50 | argSlice := util.GetArgumentFormOfStruct(fakeUserInfo) 51 | 52 | So(argSlice, ShouldBeEmpty) 53 | }) 54 | }) 55 | } 56 | -------------------------------------------------------------------------------- /pkg/sys/nss/service_test.go: -------------------------------------------------------------------------------- 1 | package nss_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | 8 | "github.com/tmrts/flamingo/pkg/sys" 9 | "github.com/tmrts/flamingo/pkg/sys/nss" 10 | "github.com/tmrts/flamingo/pkg/util/rand" 11 | ) 12 | 13 | func TestNSSErrors(t *testing.T) { 14 | Convey("Given an NSS server", t, func() { 15 | server := nss.New(sys.DefaultExecutor) 16 | 17 | Convey("When queried with a wrong database", func() { 18 | var ( 19 | db nss.Database = "InvalidDatabase" 20 | key string = "some_entry" 21 | ) 22 | 23 | Convey("It should return an error message containing: Unknown database", func() { 24 | _, err := server.GetEntryFrom(db, key) 25 | So(err, ShouldNotBeNil) 26 | 27 | So(err.Error(), ShouldContainSubstring, "Unknown database") 28 | }) 29 | }) 30 | 31 | Convey("When queried with a non-existent user", func() { 32 | var ( 33 | db nss.Database = nss.UserDatabase 34 | key string = rand.String(10) 35 | ) 36 | 37 | Convey("It should return an error message containing: Key could not be found", func() { 38 | _, err := server.GetEntryFrom(db, key) 39 | 40 | So(err, ShouldNotBeNil) 41 | 42 | So(err.Error(), ShouldContainSubstring, "Key could not be found") 43 | }) 44 | }) 45 | }) 46 | } 47 | 48 | func TestUserIDLookup(t *testing.T) { 49 | Convey("Given a user name", t, func() { 50 | uname := "root" 51 | 52 | Convey("It should get the UID and GID of the user", func() { 53 | uid, gid, err := nss.GetIDsForUser(uname) 54 | 55 | So(err, ShouldBeNil) 56 | 57 | So(uid, ShouldEqual, 0) 58 | So(gid, ShouldEqual, 0) 59 | }) 60 | }) 61 | } 62 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/papertrail/README.md: -------------------------------------------------------------------------------- 1 | # Papertrail Hook for Logrus :walrus: 2 | 3 | [Papertrail](https://papertrailapp.com) provides hosted log management. Once stored in Papertrail, you can [group](http://help.papertrailapp.com/kb/how-it-works/groups/) your logs on various dimensions, [search](http://help.papertrailapp.com/kb/how-it-works/search-syntax) them, and trigger [alerts](http://help.papertrailapp.com/kb/how-it-works/alerts). 4 | 5 | In most deployments, you'll want to send logs to Papertrail via their [remote_syslog](http://help.papertrailapp.com/kb/configuration/configuring-centralized-logging-from-text-log-files-in-unix/) daemon, which requires no application-specific configuration. This hook is intended for relatively low-volume logging, likely in managed cloud hosting deployments where installing `remote_syslog` is not possible. 6 | 7 | ## Usage 8 | 9 | You can find your Papertrail UDP port on your [Papertrail account page](https://papertrailapp.com/account/destinations). Substitute it below for `YOUR_PAPERTRAIL_UDP_PORT`. 10 | 11 | For `YOUR_APP_NAME`, substitute a short string that will readily identify your application or service in the logs. 12 | 13 | ```go 14 | import ( 15 | "log/syslog" 16 | "github.com/Sirupsen/logrus" 17 | "github.com/Sirupsen/logrus/hooks/papertrail" 18 | ) 19 | 20 | func main() { 21 | log := logrus.New() 22 | hook, err := logrus_papertrail.NewPapertrailHook("logs.papertrailapp.com", YOUR_PAPERTRAIL_UDP_PORT, YOUR_APP_NAME) 23 | 24 | if err == nil { 25 | log.Hooks.Add(hook) 26 | } 27 | } 28 | ``` 29 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/unexported.test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers_test 17 | 18 | import ( 19 | . "github.com/smartystreets/assertions/internal/oglematchers" 20 | . "github.com/smartystreets/assertions/internal/ogletest" 21 | "testing" 22 | ) 23 | 24 | //////////////////////////////////////////////////////////////////////// 25 | // Helpers 26 | //////////////////////////////////////////////////////////////////////// 27 | 28 | type UnexportedTest struct { 29 | } 30 | 31 | func init() { RegisterTestSuite(&UnexportedTest{}) } 32 | func TestUnexportedTest(t *testing.T) { RunTests(t) } 33 | 34 | func (t *UnexportedTest) someUnexportedMethod() { 35 | } 36 | 37 | //////////////////////////////////////////////////////////////////////// 38 | // Tests 39 | //////////////////////////////////////////////////////////////////////// 40 | 41 | func (t *UnexportedTest) SomeTest() { 42 | ExpectThat(3, Equals(4)) 43 | } 44 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/hooks/syslog/syslog.go: -------------------------------------------------------------------------------- 1 | package logrus_syslog 2 | 3 | import ( 4 | "fmt" 5 | "github.com/Sirupsen/logrus" 6 | "log/syslog" 7 | "os" 8 | ) 9 | 10 | // SyslogHook to send logs via syslog. 11 | type SyslogHook struct { 12 | Writer *syslog.Writer 13 | SyslogNetwork string 14 | SyslogRaddr string 15 | } 16 | 17 | // Creates a hook to be added to an instance of logger. This is called with 18 | // `hook, err := NewSyslogHook("udp", "localhost:514", syslog.LOG_DEBUG, "")` 19 | // `if err == nil { log.Hooks.Add(hook) }` 20 | func NewSyslogHook(network, raddr string, priority syslog.Priority, tag string) (*SyslogHook, error) { 21 | w, err := syslog.Dial(network, raddr, priority, tag) 22 | return &SyslogHook{w, network, raddr}, err 23 | } 24 | 25 | func (hook *SyslogHook) Fire(entry *logrus.Entry) error { 26 | line, err := entry.String() 27 | if err != nil { 28 | fmt.Fprintf(os.Stderr, "Unable to read entry, %v", err) 29 | return err 30 | } 31 | 32 | switch entry.Level { 33 | case logrus.PanicLevel: 34 | return hook.Writer.Crit(line) 35 | case logrus.FatalLevel: 36 | return hook.Writer.Crit(line) 37 | case logrus.ErrorLevel: 38 | return hook.Writer.Err(line) 39 | case logrus.WarnLevel: 40 | return hook.Writer.Warning(line) 41 | case logrus.InfoLevel: 42 | return hook.Writer.Info(line) 43 | case logrus.DebugLevel: 44 | return hook.Writer.Debug(line) 45 | default: 46 | return nil 47 | } 48 | } 49 | 50 | func (hook *SyslogHook) Levels() []logrus.Level { 51 | return []logrus.Level{ 52 | logrus.PanicLevel, 53 | logrus.FatalLevel, 54 | logrus.ErrorLevel, 55 | logrus.WarnLevel, 56 | logrus.InfoLevel, 57 | logrus.DebugLevel, 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglemock/generate/test_cases/complicated_pkg/complicated_pkg.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | // Package complicated_pkg contains an interface with lots of interesting 17 | // cases, for use in integration testing. 18 | package complicated_pkg 19 | 20 | import ( 21 | "github.com/smartystreets/assertions/internal/oglemock/generate/test_cases/renamed_pkg" 22 | "image" 23 | "io" 24 | "net" 25 | ) 26 | 27 | type Byte uint8 28 | 29 | type ComplicatedThing interface { 30 | Channels(a chan chan<- <-chan net.Conn) chan int 31 | Pointers(a *int, b *net.Conn, c **io.Reader) (*int, error) 32 | Functions(a func(int, image.Image) int) func(string, int) net.Conn 33 | Maps(a map[string]*int) (map[int]*string, error) 34 | Arrays(a [3]string) ([3]int, error) 35 | Slices(a []string) ([]int, error) 36 | NamedScalarType(a Byte) ([]Byte, error) 37 | EmptyInterface(a interface{}) (interface{}, error) 38 | RenamedPackage(a tony.SomeUint8Alias) 39 | Variadic(a int, b ...net.Conn) int 40 | } 41 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglematchers/less_or_equal.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | import ( 19 | "fmt" 20 | "reflect" 21 | ) 22 | 23 | // LessOrEqual returns a matcher that matches integer, floating point, or 24 | // strings values v such that v <= x. Comparison is not defined between numeric 25 | // and string types, but is defined between all integer and floating point 26 | // types. 27 | // 28 | // x must itself be an integer, floating point, or string type; otherwise, 29 | // LessOrEqual will panic. 30 | func LessOrEqual(x interface{}) Matcher { 31 | desc := fmt.Sprintf("less than or equal to %v", x) 32 | 33 | // Special case: make it clear that strings are strings. 34 | if reflect.TypeOf(x).Kind() == reflect.String { 35 | desc = fmt.Sprintf("less than or equal to \"%s\"", x) 36 | } 37 | 38 | // Put LessThan last so that its error messages will be used in the event of 39 | // failure. 40 | return transformDescription(AnyOf(Equals(x), LessThan(x)), desc) 41 | } 42 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglemock/sample/mock_io/mock_io.go: -------------------------------------------------------------------------------- 1 | // This file was auto-generated using createmock. See the following page for 2 | // more information: 3 | // 4 | // https://github.com/smartystreets/assertions/internal/oglemock 5 | // 6 | 7 | package mock_io 8 | 9 | import ( 10 | fmt "fmt" 11 | oglemock "github.com/smartystreets/assertions/internal/oglemock" 12 | io "io" 13 | runtime "runtime" 14 | unsafe "unsafe" 15 | ) 16 | 17 | type MockReader interface { 18 | io.Reader 19 | oglemock.MockObject 20 | } 21 | 22 | type mockReader struct { 23 | controller oglemock.Controller 24 | description string 25 | } 26 | 27 | func NewMockReader( 28 | c oglemock.Controller, 29 | desc string) MockReader { 30 | return &mockReader{ 31 | controller: c, 32 | description: desc, 33 | } 34 | } 35 | 36 | func (m *mockReader) Oglemock_Id() uintptr { 37 | return uintptr(unsafe.Pointer(m)) 38 | } 39 | 40 | func (m *mockReader) Oglemock_Description() string { 41 | return m.description 42 | } 43 | 44 | func (m *mockReader) Read(p0 []uint8) (o0 int, o1 error) { 45 | // Get a file name and line number for the caller. 46 | _, file, line, _ := runtime.Caller(1) 47 | 48 | // Hand the call off to the controller, which does most of the work. 49 | retVals := m.controller.HandleMethodCall( 50 | m, 51 | "Read", 52 | file, 53 | line, 54 | []interface{}{p0}) 55 | 56 | if len(retVals) != 2 { 57 | panic(fmt.Sprintf("mockReader.Read: invalid return values: %v", retVals)) 58 | } 59 | 60 | // o0 int 61 | if retVals[0] != nil { 62 | o0 = retVals[0].(int) 63 | } 64 | 65 | // o1 error 66 | if retVals[1] != nil { 67 | o1 = retVals[1].(error) 68 | } 69 | 70 | return 71 | } 72 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglematchers/not.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | import ( 19 | "errors" 20 | "fmt" 21 | ) 22 | 23 | // Not returns a matcher that inverts the set of values matched by the wrapped 24 | // matcher. It does not transform the result for values for which the wrapped 25 | // matcher returns a fatal error. 26 | func Not(m Matcher) Matcher { 27 | return ¬Matcher{m} 28 | } 29 | 30 | type notMatcher struct { 31 | wrapped Matcher 32 | } 33 | 34 | func (m *notMatcher) Matches(c interface{}) (err error) { 35 | err = m.wrapped.Matches(c) 36 | 37 | // Did the wrapped matcher say yes? 38 | if err == nil { 39 | return errors.New("") 40 | } 41 | 42 | // Did the wrapped matcher return a fatal error? 43 | if _, isFatal := err.(*FatalError); isFatal { 44 | return err 45 | } 46 | 47 | // The wrapped matcher returned a non-fatal error. 48 | return nil 49 | } 50 | 51 | func (m *notMatcher) Description() string { 52 | return fmt.Sprintf("not(%s)", m.wrapped.Description()) 53 | } 54 | -------------------------------------------------------------------------------- /flamingo.spec: -------------------------------------------------------------------------------- 1 | Name: flamingo 2 | Version: 0.2.0 3 | Release: 3 4 | Group: System Environment/Daemons 5 | Summary: Cloud Instance Contextualization Tool 6 | License: Apache 2.0 7 | URL: http://github.com/tmrts/flamingo 8 | Source0: https://github.com/tmrts/%{name}/archive/v%{version}.tar.gz#/%{name}-v%{version}.tar.gz 9 | 10 | Buildroot: %{_tmppath}/%{name}-%{version}-%(%{__id_u} -n) 11 | Packager: Tamer Tas 12 | 13 | Requires(post): nss 14 | Requires(post): libssh2 15 | Requires(post): iptables 16 | Requires(post): shadow-utils 17 | Requires(post): systemd 18 | BuildRequires: systemd 19 | 20 | %description 21 | Flamingo is a lightweight contextualization tool that handles 22 | initialization of cloud instances. 23 | 24 | Instances in the cloud needs to be initialized(contextualized). 25 | Contextualization includes User, group, network, systemd, and disk configurations. 26 | 27 | Flamingo is written in Go and it's main focus points are: 28 | 29 | * Speed 30 | * Lightweight 31 | * Extensibility 32 | 33 | %prep 34 | %setup -qn %{name}-%{version} 35 | 36 | %install 37 | install -d -m 755 %{buildroot}/bin 38 | install -d -m 755 %{buildroot}/etc/systemd/system/ 39 | 40 | install -m 700 %{_builddir}/%{name}-%{version}/bin/%{name} %{buildroot}/bin 41 | install -m 700 %{_builddir}/%{name}-%{version}/unit/%{name}.service %{buildroot}/etc/systemd/system/ 42 | 43 | %clean 44 | rm -rf %{buildroot} 45 | 46 | %post 47 | systemctl enable --system /etc/systemd/system/%{name}.service 48 | 49 | %files 50 | /bin/* 51 | /etc/systemd/system/* 52 | 53 | %changelog 54 | * Wed Aug 12 2015 Flamingo 0.2.0 55 | - Openstack, EC2 Cloud Provider Support. Couple of Bug Fixes 56 | * Mon Aug 03 2015 Flamingo 0.1.0 57 | - Initial RPM release. 58 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglematchers/any_test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers_test 17 | 18 | import ( 19 | . "github.com/smartystreets/assertions/internal/oglematchers" 20 | . "github.com/smartystreets/assertions/internal/ogletest" 21 | ) 22 | 23 | //////////////////////////////////////////////////////////////////////// 24 | // Helpers 25 | //////////////////////////////////////////////////////////////////////// 26 | 27 | type AnyTest struct { 28 | } 29 | 30 | func init() { RegisterTestSuite(&AnyTest{}) } 31 | 32 | //////////////////////////////////////////////////////////////////////// 33 | // Tests 34 | //////////////////////////////////////////////////////////////////////// 35 | 36 | func (t *AnyTest) Description() { 37 | m := Any() 38 | ExpectEq("is anything", m.Description()) 39 | } 40 | 41 | func (t *AnyTest) Matches() { 42 | var err error 43 | m := Any() 44 | 45 | err = m.Matches(nil) 46 | ExpectEq(nil, err) 47 | 48 | err = m.Matches(17) 49 | ExpectEq(nil, err) 50 | 51 | err = m.Matches("taco") 52 | ExpectEq(nil, err) 53 | } 54 | -------------------------------------------------------------------------------- /pkg/sys/ssh/test_keys/test_rsa: -------------------------------------------------------------------------------- 1 | -----BEGIN RSA PRIVATE KEY----- 2 | MIIEpQIBAAKCAQEA1HQiFdxLm/SLITlBAjX0wqrqM2DkkhIiyb9EEJqYqmCumaMa 3 | PiilWUyXVvocdzccntVt6ZHE21HGaFpmypi7YmxmbxP2sOPpqB1thD8Z/cMcsCPD 4 | 4DF6jnkDd8jYPNdT39izTnyTbOiKQ2LjBtr6DlUE/jBWTIRW6HnJ+zDZSKiDdt1X 5 | nzsPGce8e7ifbB8MnX2HWr9GugkZ0k/uxGm8vSNyY2QQyXWEZPV/xwzKLbEk8dJr 6 | 4QR1ddJC6wm6z3Js/8yzjindyMWDYrm9fqlwEPjL5NbVKnbX9Veqx+gMw27FXNeC 7 | xWOKtx++NYwSo+nDzcqjfrsQ5fLkhaPcp+qcCQIDAQABAoIBAQCQQDIMicFEqOv2 8 | qPs81wnTS10teXJ4w5ufRCCg7XcO6AplAtuErPBoC5sOUVAWmfLy3ZN9bZ4uE/4V 9 | SJxWnxFMKLH8ZZ+wR2+U2DZN/tJU/K9z4TTT+oRuTDhQkqxP0xx99pL4jZlD7zhB 10 | vNjNBM2YAZ4cQRG3bnvb6SV9SpOdwp96pZU3O3L0pV/Gqle3MFqI8VivBRtY5NMj 11 | qLKdhQ6o3gsDvFVT/LKC2Uclj3YRWPR4koo/Us+XA1LO6tc4MRPPCr7yoyT8qI3f 12 | NUuCAYAZmg68vwyKzaHEto5a07qXg+/7lOsMvh0tHL9tbd+ivQJ6/hxCJn2bSIN8 13 | fgE6TMFJAoGBAP3aYSLeIBlAKWL00lBaRUZlWe20g57swfNSymGNp+Xk//TcxAEn 14 | VAULnmaVVRYDK5JhiltERELwrSJuE5eEzxnJrJop3jlVnyNsEvu2ti9o57c6Go9V 15 | UcTQM/FtUizC/ait9YYnRrdzeX/w5udE0apgcdQTIuxpj5mUucIAvFWTAoGBANZA 16 | HowDHLg+5Ma+Movb/XTXJ495zx2xl9qucdQaGOe2dMU12x2uM10WGX6dsAr2txuD 17 | KKAbKZ9wLPO9SGT5YUSwo7fJ7btBj6Q1Ljbt1YgXfcEU7UIsq8YZFzvWQ7Cllhtu 18 | hhVqURkcZwOQFVwP2QERkhGuwFW40UCgM60LOglzAoGBAM1Xmh2PWp2yVggTDBEt 19 | hD4We/EZhSLIV3dRcB4LbVY8sINNFUvtmTxfkqlegK5GsDc/qaB8D0+qyhJAwp5d 20 | Mv2kMneeCIGObiVEJfLxcFvXWyDO4m8xT+yJkornqIJG1NNerG3xVXXN9el1YAKR 21 | m5xbWZh4RlbAaQWN1dlFqRL7AoGAERWn2e5dmeuZ/qcoDLMMMQb/JpfGBk4lF9EV 22 | Tp6OIdwQz7ENuf4sJl4exlP4t8cYrt70nF/OH+KoEv+jCDpCoWGcjIlTpb0CoUuE 23 | Vej9QA7vfjgW+1HomLFjgugBGdL6d1GG66pAsUnshQI2UdMJsOYfyb0vpSZJuWeM 24 | 912P0TUCgYEAn4JRjLjcbfF+YOXJlz9niAGgbj2A4WAswFAS7ykOVdMvOYhFENNV 25 | iYsCvlbYAKkG5T8GkaDsK+3Yu7W92+rQG9YuWtasb2ASvQ066kR7rW/0m2kE66Sk 26 | qINz//Omdf22CKJbp0gCebtF/CYIJZlsPxE+/21wMlTicVuRpvwi9+o= 27 | -----END RSA PRIVATE KEY----- 28 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglemock/generate/test_cases/golden.renamed_pkg.go: -------------------------------------------------------------------------------- 1 | // This file was auto-generated using createmock. See the following page for 2 | // more information: 3 | // 4 | // https://github.com/smartystreets/assertions/internal/oglemock 5 | // 6 | 7 | package some_pkg 8 | 9 | import ( 10 | fmt "fmt" 11 | oglemock "github.com/smartystreets/assertions/internal/oglemock" 12 | tony "github.com/smartystreets/assertions/internal/oglemock/generate/test_cases/renamed_pkg" 13 | runtime "runtime" 14 | unsafe "unsafe" 15 | ) 16 | 17 | type MockSomeInterface interface { 18 | tony.SomeInterface 19 | oglemock.MockObject 20 | } 21 | 22 | type mockSomeInterface struct { 23 | controller oglemock.Controller 24 | description string 25 | } 26 | 27 | func NewMockSomeInterface( 28 | c oglemock.Controller, 29 | desc string) MockSomeInterface { 30 | return &mockSomeInterface{ 31 | controller: c, 32 | description: desc, 33 | } 34 | } 35 | 36 | func (m *mockSomeInterface) Oglemock_Id() uintptr { 37 | return uintptr(unsafe.Pointer(m)) 38 | } 39 | 40 | func (m *mockSomeInterface) Oglemock_Description() string { 41 | return m.description 42 | } 43 | 44 | func (m *mockSomeInterface) DoFoo(p0 int) (o0 int) { 45 | // Get a file name and line number for the caller. 46 | _, file, line, _ := runtime.Caller(1) 47 | 48 | // Hand the call off to the controller, which does most of the work. 49 | retVals := m.controller.HandleMethodCall( 50 | m, 51 | "DoFoo", 52 | file, 53 | line, 54 | []interface{}{p0}) 55 | 56 | if len(retVals) != 1 { 57 | panic(fmt.Sprintf("mockSomeInterface.DoFoo: invalid return values: %v", retVals)) 58 | } 59 | 60 | // o0 int 61 | if retVals[0] != nil { 62 | o0 = retVals[0].(int) 63 | } 64 | 65 | return 66 | } 67 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/run_twice.test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers_test 17 | 18 | import ( 19 | . "github.com/smartystreets/assertions/internal/oglematchers" 20 | . "github.com/smartystreets/assertions/internal/ogletest" 21 | "testing" 22 | ) 23 | 24 | //////////////////////////////////////////////////////////////////////// 25 | // Helpers 26 | //////////////////////////////////////////////////////////////////////// 27 | 28 | type RunTwiceTest struct { 29 | } 30 | 31 | func init() { RegisterTestSuite(&RunTwiceTest{}) } 32 | 33 | // Set up two helpers that call RunTests. The test should still only be run 34 | // once. 35 | func TestOgletest(t *testing.T) { RunTests(t) } 36 | func TestOgletest2(t *testing.T) { RunTests(t) } 37 | 38 | //////////////////////////////////////////////////////////////////////// 39 | // Tests 40 | //////////////////////////////////////////////////////////////////////// 41 | 42 | func (t *RunTwiceTest) PassingMethod() { 43 | } 44 | 45 | func (t *RunTwiceTest) FailingMethod() { 46 | ExpectThat(17, Equals(17.5)) 47 | } 48 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglematchers/error.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | // Error returns a matcher that matches non-nil values implementing the 19 | // built-in error interface for whom the return value of Error() matches the 20 | // supplied matcher. 21 | // 22 | // For example: 23 | // 24 | // err := errors.New("taco burrito") 25 | // 26 | // Error(Equals("taco burrito")) // matches err 27 | // Error(HasSubstr("taco")) // matches err 28 | // Error(HasSubstr("enchilada")) // doesn't match err 29 | // 30 | func Error(m Matcher) Matcher { 31 | return &errorMatcher{m} 32 | } 33 | 34 | type errorMatcher struct { 35 | wrappedMatcher Matcher 36 | } 37 | 38 | func (m *errorMatcher) Description() string { 39 | return "error " + m.wrappedMatcher.Description() 40 | } 41 | 42 | func (m *errorMatcher) Matches(c interface{}) error { 43 | // Make sure that c is an error. 44 | e, ok := c.(error) 45 | if !ok { 46 | return NewFatalError("which is not an error") 47 | } 48 | 49 | // Pass on the error text to the wrapped matcher. 50 | return m.wrappedMatcher.Matches(e.Error()) 51 | } 52 | -------------------------------------------------------------------------------- /pkg/datasrc/userdata/userdata.go: -------------------------------------------------------------------------------- 1 | package userdata 2 | 3 | import ( 4 | "errors" 5 | "strings" 6 | 7 | "github.com/tmrts/flamingo/pkg/datasrc/userdata/cloudconfig" 8 | ) 9 | 10 | // Errors regarding the user-data file types. 11 | var ( 12 | ErrNotACloudConfigFile = errors.New("userdata: not a cloud-config file") 13 | ErrNotAScriptFile = errors.New("userdata: not a user-data script file") 14 | ) 15 | 16 | // Map contains the user-data attributes given by the provider. 17 | type Map map[string]string 18 | 19 | // IsScript checks whether the given content belongs to a script file. 20 | func IsScript(content string) error { 21 | if !strings.HasPrefix(content, "#! ") { 22 | return ErrNotAScriptFile 23 | } 24 | 25 | return nil 26 | } 27 | 28 | // Scripts return a new map containing only the contents 29 | // that are valid scripts. 30 | func (m Map) Scripts() map[string]string { 31 | scripts := make(map[string]string) 32 | 33 | for k, v := range m { 34 | if err := IsScript(v); err == nil { 35 | scripts[k] = v 36 | } 37 | } 38 | 39 | return scripts 40 | } 41 | 42 | // IsCloudConfig checks whether the given content belongs to a cloud-config file. 43 | func IsCloudConfig(content string) error { 44 | if !strings.HasPrefix(content, "#cloud-config\n") { 45 | return cloudconfig.ErrNotACloudConfigFile 46 | } 47 | 48 | return nil 49 | } 50 | 51 | // CloudConfigs return a new map containing only the contents 52 | // that are valid cloud-config files. 53 | func (m Map) CloudConfigs() map[string]string { 54 | confs := make(map[string]string) 55 | 56 | for k, v := range m { 57 | if err := IsCloudConfig(v); err == nil { 58 | confs[k] = v 59 | } 60 | } 61 | 62 | return confs 63 | } 64 | 65 | // Provider retrieves user-data attributes from the meta-data server 66 | // and returns a Map. 67 | type Provider interface { 68 | FetchUserdata() (Map, error) 69 | } 70 | -------------------------------------------------------------------------------- /pkg/datasrc/provider/ec2/metadata.go: -------------------------------------------------------------------------------- 1 | package ec2 2 | 3 | import ( 4 | "net" 5 | 6 | "github.com/tmrts/flamingo/pkg/datasrc/metadata" 7 | "github.com/tmrts/flamingo/pkg/sys/ssh" 8 | ) 9 | 10 | type Metadata struct { 11 | instanceAction string `json:"instance-action"` 12 | instanceID string `json:"instance-id"` 13 | instanceType string `json:"instance-type"` 14 | kernelID string `json:"kernel-id"` 15 | localHostname string `json:"local-hostname"` 16 | publicHostname string `json:"public-hostname"` 17 | aMIID string `json:"ami-id"` 18 | aMILaunchIndex string `json:"ami-launch-index"` 19 | aMIManifestPath string `json:"ami-manifest-path"` 20 | blockDeviceMapping string `json:"block-device-mapping"` 21 | ramDiskID string `json:"ramdisk-id"` 22 | reservationID string `json:"reservation-id"` 23 | securityGroups []string `json:"security-groups"` 24 | placement interface{} `json:"placement"` 25 | 26 | Hostname string `json:"hostname"` 27 | LocalIPv4 net.IP `json:"local-ipv4"` 28 | PublicIPv4 net.IP `json:"public-ipv4"` 29 | PublicKeys map[string]string `json:"public-keys"` 30 | } 31 | 32 | // Digest extracts the important parts of meta-data and returns it. 33 | func (m *Metadata) Digest() metadata.Digest { 34 | sshKeys := make(map[string][]ssh.Key) 35 | 36 | for _, publicKey := range m.PublicKeys { 37 | sshKeys["root"] = append(sshKeys["root"], ssh.Key(publicKey)) 38 | } 39 | 40 | primaryNetworkInterface := metadata.NetworkInterface{ 41 | PrivateIP: m.LocalIPv4, 42 | PublicIPs: []net.IP{m.PublicIPv4}, 43 | } 44 | 45 | return metadata.Digest{ 46 | Hostname: m.Hostname, 47 | SSHKeys: sshKeys, 48 | 49 | NetworkInterfaces: []metadata.NetworkInterface{ 50 | primaryNetworkInterface, 51 | }, 52 | } 53 | } 54 | -------------------------------------------------------------------------------- /pkg/file/directory_test.go: -------------------------------------------------------------------------------- 1 | package file_test 2 | 3 | import ( 4 | "os" 5 | "strconv" 6 | "syscall" 7 | "testing" 8 | 9 | . "github.com/smartystreets/goconvey/convey" 10 | 11 | "github.com/tmrts/flamingo/pkg/file" 12 | "github.com/tmrts/flamingo/pkg/sys/nss" 13 | ) 14 | 15 | func TestEnsureDirectoryExists(t *testing.T) { 16 | Convey("Given a unique dir name, a user name and file permissions", t, func() { 17 | currentUser, err := nss.GetCurrentUser() 18 | So(err, ShouldBeNil) 19 | 20 | dirname, err := file.UniqueName("/tmp", "filetests") 21 | So(err, ShouldBeNil) 22 | 23 | perms := os.FileMode(0600) 24 | 25 | userID, _ := strconv.Atoi(currentUser.Uid) 26 | groupID, _ := strconv.Atoi(currentUser.Gid) 27 | 28 | Convey("It should create a new directory with the given permissions if it doesn't exist", func() { 29 | err := file.EnsureDirectoryExists(dirname, perms, userID, groupID) 30 | So(err, ShouldBeNil) 31 | defer os.Remove(dirname) 32 | 33 | fi, err := os.Lstat(dirname) 34 | So(err, ShouldBeNil) 35 | 36 | So(fi.IsDir(), ShouldBeTrue) 37 | 38 | uid := strconv.Itoa(int(fi.Sys().(*syscall.Stat_t).Uid)) 39 | So(currentUser.Uid, ShouldEqual, uid) 40 | 41 | gid := strconv.Itoa(int(fi.Sys().(*syscall.Stat_t).Gid)) 42 | So(currentUser.Gid, ShouldEqual, gid) 43 | }) 44 | 45 | Convey("It should change the ownership and the file permissions if it exists", func() { 46 | err := file.EnsureDirectoryExists(dirname, perms, userID, groupID) 47 | So(err, ShouldBeNil) 48 | defer os.Remove(dirname) 49 | 50 | fi, err := os.Lstat(dirname) 51 | So(err, ShouldBeNil) 52 | 53 | So(fi.IsDir(), ShouldBeTrue) 54 | 55 | uid := strconv.Itoa(int(fi.Sys().(*syscall.Stat_t).Uid)) 56 | So(currentUser.Uid, ShouldEqual, uid) 57 | 58 | gid := strconv.Itoa(int(fi.Sys().(*syscall.Stat_t).Gid)) 59 | So(currentUser.Gid, ShouldEqual, gid) 60 | }) 61 | }) 62 | } 63 | -------------------------------------------------------------------------------- /pkg/datasrc/provider/gce/gce.go: -------------------------------------------------------------------------------- 1 | package gce 2 | 3 | import ( 4 | "github.com/tmrts/flamingo/pkg/datasrc/metadata" 5 | "github.com/tmrts/flamingo/pkg/datasrc/provider" 6 | "github.com/tmrts/flamingo/pkg/datasrc/userdata" 7 | "github.com/tmrts/flamingo/pkg/request" 8 | ) 9 | 10 | const ( 11 | LatestSupportedMetadataVersion = "v1" 12 | 13 | MetadataURL provider.FormatURL = "http://metadata.google.internal/computeMetadata/%s/%s/?recursive=true" 14 | ) 15 | 16 | type MetadataService struct { 17 | URL provider.FormatURL 18 | } 19 | 20 | func (s *MetadataService) fetchMetadata() (*Metadata, error) { 21 | // currently only supported metadata version is "v1" 22 | version := "v1" 23 | /* 24 | *if _, ok := s.supportedversions[v]; ok != true { 25 | * return nil, fmt.errorf("metadata: version %v for %v is not supported", v, s.name) 26 | *} 27 | */ 28 | 29 | var m Metadata 30 | 31 | instanceurl := s.URL.Fill(version, "instance") 32 | response, err := request.Get(instanceurl, request.Header("Metadata-Flavor", "Google")) 33 | if err != nil { 34 | return nil, err 35 | } 36 | 37 | err = response.JSON(&m.Instance) 38 | if err != nil { 39 | return nil, err 40 | } 41 | 42 | projecturl := s.URL.Fill(version, "project") 43 | response, err = request.Get(projecturl, request.Header("Metadata-Flavor", "Google")) 44 | if err != nil { 45 | return nil, err 46 | } 47 | 48 | err = response.JSON(&m.Project) 49 | return &m, err 50 | } 51 | 52 | func (s *MetadataService) FetchMetadata() (*metadata.Digest, error) { 53 | m, err := s.fetchMetadata() 54 | if err != nil { 55 | return nil, err 56 | } 57 | 58 | digest := m.Digest() 59 | 60 | return &digest, nil 61 | } 62 | 63 | // FetchUserdata retrieves userdata files from Google Compute Engine metadata service 64 | func (s *MetadataService) FetchUserdata() (userdata.Map, error) { 65 | m, err := s.fetchMetadata() 66 | return m.Instance.Attributes, err 67 | } 68 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/problems.go: -------------------------------------------------------------------------------- 1 | package reporting 2 | 3 | import "fmt" 4 | 5 | type problem struct { 6 | out *Printer 7 | errors []*AssertionResult 8 | failures []*AssertionResult 9 | } 10 | 11 | func (self *problem) BeginStory(story *StoryReport) {} 12 | 13 | func (self *problem) Enter(scope *ScopeReport) {} 14 | 15 | func (self *problem) Report(report *AssertionResult) { 16 | if report.Error != nil { 17 | self.errors = append(self.errors, report) 18 | } else if report.Failure != "" { 19 | self.failures = append(self.failures, report) 20 | } 21 | } 22 | 23 | func (self *problem) Exit() {} 24 | 25 | func (self *problem) EndStory() { 26 | self.show(self.showErrors, redColor) 27 | self.show(self.showFailures, yellowColor) 28 | self.prepareForNextStory() 29 | } 30 | func (self *problem) show(display func(), color string) { 31 | fmt.Print(color) 32 | display() 33 | fmt.Print(resetColor) 34 | self.out.Dedent() 35 | } 36 | func (self *problem) showErrors() { 37 | for i, e := range self.errors { 38 | if i == 0 { 39 | self.out.Println("\nErrors:\n") 40 | self.out.Indent() 41 | } 42 | self.out.Println(errorTemplate, e.File, e.Line, e.Error, e.StackTrace) 43 | } 44 | } 45 | func (self *problem) showFailures() { 46 | for i, f := range self.failures { 47 | if i == 0 { 48 | self.out.Println("\nFailures:\n") 49 | self.out.Indent() 50 | } 51 | self.out.Println(failureTemplate, f.File, f.Line, f.Failure) 52 | } 53 | } 54 | 55 | func (self *problem) Write(content []byte) (written int, err error) { 56 | return len(content), nil // no-op 57 | } 58 | 59 | func NewProblemReporter(out *Printer) *problem { 60 | self := new(problem) 61 | self.out = out 62 | self.prepareForNextStory() 63 | return self 64 | } 65 | func (self *problem) prepareForNextStory() { 66 | self.errors = []*AssertionResult{} 67 | self.failures = []*AssertionResult{} 68 | } 69 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/gotest_test.go: -------------------------------------------------------------------------------- 1 | package reporting 2 | 3 | import "testing" 4 | 5 | func TestReporterReceivesSuccessfulReport(t *testing.T) { 6 | reporter := NewGoTestReporter() 7 | test := new(fakeTest) 8 | reporter.BeginStory(NewStoryReport(test)) 9 | reporter.Report(NewSuccessReport()) 10 | 11 | if test.failed { 12 | t.Errorf("Should have have marked test as failed--the report reflected success.") 13 | } 14 | } 15 | 16 | func TestReporterReceivesFailureReport(t *testing.T) { 17 | reporter := NewGoTestReporter() 18 | test := new(fakeTest) 19 | reporter.BeginStory(NewStoryReport(test)) 20 | reporter.Report(NewFailureReport("This is a failure.")) 21 | 22 | if !test.failed { 23 | t.Errorf("Test should have been marked as failed (but it wasn't).") 24 | } 25 | } 26 | 27 | func TestReporterReceivesErrorReport(t *testing.T) { 28 | reporter := NewGoTestReporter() 29 | test := new(fakeTest) 30 | reporter.BeginStory(NewStoryReport(test)) 31 | reporter.Report(NewErrorReport("This is an error.")) 32 | 33 | if !test.failed { 34 | t.Errorf("Test should have been marked as failed (but it wasn't).") 35 | } 36 | } 37 | 38 | func TestReporterIsResetAtTheEndOfTheStory(t *testing.T) { 39 | defer catch(t) 40 | reporter := NewGoTestReporter() 41 | test := new(fakeTest) 42 | reporter.BeginStory(NewStoryReport(test)) 43 | reporter.EndStory() 44 | 45 | reporter.Report(NewSuccessReport()) 46 | } 47 | 48 | func TestReporterNoopMethods(t *testing.T) { 49 | reporter := NewGoTestReporter() 50 | reporter.Enter(NewScopeReport("title")) 51 | reporter.Exit() 52 | } 53 | 54 | func catch(t *testing.T) { 55 | if r := recover(); r != nil { 56 | t.Log("Getting to this point means we've passed (because we caught a panic appropriately).") 57 | } 58 | } 59 | 60 | type fakeTest struct { 61 | failed bool 62 | } 63 | 64 | func (self *fakeTest) Fail() { 65 | self.failed = true 66 | } 67 | -------------------------------------------------------------------------------- /pkg/sys/firewall/iptables/iptables.go: -------------------------------------------------------------------------------- 1 | package iptables 2 | 3 | import ( 4 | "fmt" 5 | "os/exec" 6 | "strings" 7 | 8 | "github.com/tmrts/flamingo/pkg/sys" 9 | "github.com/tmrts/flamingo/pkg/sys/firewall" 10 | "github.com/tmrts/flamingo/pkg/util" 11 | ) 12 | 13 | type Target string 14 | 15 | const ( 16 | AcceptTarget Target = "ACCEPT" 17 | ReturnTarget Target = "RETURN" 18 | DropTarget Target = "DROP" 19 | ) 20 | 21 | type Operation string 22 | 23 | const ( 24 | Append Operation = "append" 25 | Delete Operation = "delete" 26 | Insert Operation = "insert" 27 | Check Operation = "check" 28 | ) 29 | 30 | type Implementation struct { 31 | sys.Executor 32 | } 33 | 34 | type Rule struct { 35 | Source []string `flag:"source"` 36 | Destination []string `flag:"destination"` 37 | 38 | FromInterface string `flag:"in-interface"` 39 | ToInterface string `flag:"out-interface"` 40 | 41 | IsSyncPackage bool `flag:"syn"` 42 | 43 | Protocol string `flag:"protocol"` 44 | 45 | Target Target `flag:"jump"` 46 | } 47 | 48 | func (r *Rule) FlagForm() []string { 49 | return util.GetFlagFormOfStruct(*r) 50 | } 51 | 52 | func (r *Rule) String() string { 53 | return strings.Join(r.FlagForm(), " ") 54 | } 55 | 56 | func (impl *Implementation) CheckDependencies() error { 57 | _, err := exec.LookPath("iptables") 58 | if err != nil { 59 | return fmt.Errorf("iptables: 'iptables' executable could not be found") 60 | } 61 | 62 | return nil 63 | } 64 | 65 | func (impl *Implementation) Perform(op Operation, c firewall.Chain, r *Rule) error { 66 | if r.Target == "" { 67 | return fmt.Errorf("iptables: rule doesnt have a target") 68 | } 69 | 70 | table := fmt.Sprintf("--table=%v", c.Table) 71 | action := fmt.Sprintf("--%v=%v", op, c.Name) 72 | 73 | args := []string{"--wait", table, action} 74 | 75 | args = append(args, r.FlagForm()...) 76 | 77 | _, err := impl.Execute("iptables", args...) 78 | 79 | return err 80 | } 81 | -------------------------------------------------------------------------------- /pkg/flog/log.go: -------------------------------------------------------------------------------- 1 | // Package flog implements logging utilities for flamingo 2 | package flog 3 | 4 | import "github.com/Sirupsen/logrus" 5 | 6 | type Parameter interface { 7 | Convert() map[string]interface{} 8 | } 9 | 10 | type Fields struct { 11 | Event string 12 | Error error 13 | } 14 | 15 | func (f Fields) Convert() map[string]interface{} { 16 | fields := map[string]interface{}{} 17 | 18 | if f.Event != "" { 19 | fields["event"] = f.Event 20 | } 21 | 22 | if f.Error != nil { 23 | fields["error"] = f.Error 24 | } 25 | 26 | return fields 27 | } 28 | 29 | type Details map[string]interface{} 30 | 31 | func (d Details) Convert() map[string]interface{} { 32 | return d 33 | } 34 | 35 | type DebugFields map[string]interface{} 36 | 37 | func (d DebugFields) Convert() map[string]interface{} { 38 | // TODO(tmrts): Handle debug information 39 | return map[string]interface{}{} 40 | } 41 | 42 | func transform(params []Parameter) logrus.Fields { 43 | logrusFields := logrus.Fields{} 44 | 45 | for _, p := range params { 46 | fieldMap := p.Convert() 47 | 48 | for k, v := range fieldMap { 49 | logrusFields[k] = v 50 | } 51 | } 52 | 53 | return logrusFields 54 | } 55 | 56 | func Debug(msg string, params ...Parameter) { 57 | f := transform(params) 58 | 59 | logrus.WithFields(f).Debug(msg) 60 | } 61 | 62 | func Info(msg string, params ...Parameter) { 63 | f := transform(params) 64 | 65 | logrus.WithFields(f).Info(msg) 66 | } 67 | 68 | func Warn(msg string, params ...Parameter) { 69 | f := transform(params) 70 | 71 | logrus.WithFields(f).Warning(msg) 72 | } 73 | 74 | func Error(msg string, params ...Parameter) { 75 | f := transform(params) 76 | 77 | logrus.WithFields(f).Error(msg) 78 | } 79 | 80 | func Fatal(msg string, params ...Parameter) { 81 | f := transform(params) 82 | 83 | logrus.WithFields(f).Fatal(msg) 84 | } 85 | 86 | func Panic(msg string, params ...Parameter) { 87 | f := transform(params) 88 | 89 | logrus.WithFields(f).Panic(msg) 90 | } 91 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/Sirupsen/logrus/text_formatter_test.go: -------------------------------------------------------------------------------- 1 | package logrus 2 | 3 | import ( 4 | "bytes" 5 | "errors" 6 | "testing" 7 | "time" 8 | ) 9 | 10 | func TestQuoting(t *testing.T) { 11 | tf := &TextFormatter{DisableColors: true} 12 | 13 | checkQuoting := func(q bool, value interface{}) { 14 | b, _ := tf.Format(WithField("test", value)) 15 | idx := bytes.Index(b, ([]byte)("test=")) 16 | cont := bytes.Contains(b[idx+5:], []byte{'"'}) 17 | if cont != q { 18 | if q { 19 | t.Errorf("quoting expected for: %#v", value) 20 | } else { 21 | t.Errorf("quoting not expected for: %#v", value) 22 | } 23 | } 24 | } 25 | 26 | checkQuoting(false, "abcd") 27 | checkQuoting(false, "v1.0") 28 | checkQuoting(false, "1234567890") 29 | checkQuoting(true, "/foobar") 30 | checkQuoting(true, "x y") 31 | checkQuoting(true, "x,y") 32 | checkQuoting(false, errors.New("invalid")) 33 | checkQuoting(true, errors.New("invalid argument")) 34 | } 35 | 36 | func TestTimestampFormat(t *testing.T) { 37 | checkTimeStr := func(format string) { 38 | customFormatter := &TextFormatter{DisableColors: true, TimestampFormat: format} 39 | customStr, _ := customFormatter.Format(WithField("test", "test")) 40 | timeStart := bytes.Index(customStr, ([]byte)("time=")) 41 | timeEnd := bytes.Index(customStr, ([]byte)("level=")) 42 | timeStr := customStr[timeStart+5 : timeEnd-1] 43 | if timeStr[0] == '"' && timeStr[len(timeStr)-1] == '"' { 44 | timeStr = timeStr[1 : len(timeStr)-1] 45 | } 46 | if format == "" { 47 | format = time.RFC3339 48 | } 49 | _, e := time.Parse(format, (string)(timeStr)) 50 | if e != nil { 51 | t.Errorf("time string \"%s\" did not match provided time format \"%s\": %s", timeStr, format, e) 52 | } 53 | } 54 | 55 | checkTimeStr("2006-01-02T15:04:05.000000000Z07:00") 56 | checkTimeStr("Mon Jan _2 15:04:05 2006") 57 | checkTimeStr("") 58 | } 59 | 60 | // TODO add tests for sorting etc., this requires a parser for the text 61 | // formatter output. 62 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/ogletest/test_cases/stop.test.go: -------------------------------------------------------------------------------- 1 | // Copyright 2015 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers_test 17 | 18 | import ( 19 | "fmt" 20 | "testing" 21 | 22 | . "github.com/smartystreets/assertions/internal/ogletest" 23 | ) 24 | 25 | func TestStop(t *testing.T) { RunTests(t) } 26 | 27 | //////////////////////////////////////////////////////////////////////// 28 | // Boilerplate 29 | //////////////////////////////////////////////////////////////////////// 30 | 31 | type StopTest struct { 32 | } 33 | 34 | var _ TearDownInterface = &StopTest{} 35 | var _ TearDownTestSuiteInterface = &StopTest{} 36 | 37 | func init() { RegisterTestSuite(&StopTest{}) } 38 | 39 | func (t *StopTest) TearDown() { 40 | fmt.Println("TearDown running.") 41 | } 42 | 43 | func (t *StopTest) TearDownTestSuite() { 44 | fmt.Println("TearDownTestSuite running.") 45 | } 46 | 47 | //////////////////////////////////////////////////////////////////////// 48 | // Tests 49 | //////////////////////////////////////////////////////////////////////// 50 | 51 | func (t *StopTest) First() { 52 | } 53 | 54 | func (t *StopTest) Second() { 55 | fmt.Println("About to call StopRunningTests.") 56 | StopRunningTests() 57 | fmt.Println("Called StopRunningTests.") 58 | } 59 | 60 | func (t *StopTest) Third() { 61 | } 62 | -------------------------------------------------------------------------------- /pkg/datasrc/provider/configdrive/configdrive.go: -------------------------------------------------------------------------------- 1 | // Handling configuration data passed via Config-Drive disk images. 2 | package configdrive 3 | 4 | import ( 5 | "encoding/json" 6 | "errors" 7 | "io/ioutil" 8 | "path/filepath" 9 | 10 | "github.com/tmrts/flamingo/pkg/datasrc/metadata" 11 | "github.com/tmrts/flamingo/pkg/datasrc/provider/openstack" 12 | "github.com/tmrts/flamingo/pkg/datasrc/userdata" 13 | "github.com/tmrts/flamingo/pkg/sys" 14 | ) 15 | 16 | var ( 17 | ErrUnableToLocateConfigDrive = errors.New("configdrive: couldn't locate the config drive device") 18 | ) 19 | 20 | // FindMountTarget finds the mount target location of the config drive device. 21 | // It finds the device labeled with 'LABEL=config-2', then gets the mount target 22 | // of that device. 23 | func FindMountTarget(e sys.Executor) (string, error) { 24 | dev, err := e.Execute("blkid", "-t LABEL='config-2'", "-odevice") 25 | if err != nil { 26 | return "", err 27 | } 28 | 29 | if dev == "" { 30 | return "", ErrUnableToLocateConfigDrive 31 | } 32 | 33 | return e.Execute("findmnt", "--raw", "--noheadings", "--output TARGET", dev) 34 | } 35 | 36 | type Mount struct { 37 | Path string 38 | } 39 | 40 | func (m Mount) FetchMetadata() (*metadata.Digest, error) { 41 | metadataPath := filepath.Join(m.Path, "openstack/2012-08-10/meta_data.json") 42 | buf, err := ioutil.ReadFile(metadataPath) 43 | if err != nil { 44 | return nil, err 45 | } 46 | 47 | var metadata openstack.Metadata 48 | if err := json.Unmarshal(buf, &metadata); err != nil { 49 | return nil, err 50 | } 51 | 52 | digest := metadata.Digest() 53 | 54 | return &digest, err 55 | } 56 | 57 | func (m Mount) FetchUserdata() (userdata.Map, error) { 58 | userdataPath := filepath.Join(m.Path, "openstack/2012-08-10/user_data") 59 | buf, err := ioutil.ReadFile(userdataPath) 60 | if err != nil { 61 | return nil, err 62 | } 63 | 64 | userdata := make(userdata.Map) 65 | 66 | userdata["user-data"] = string(buf) 67 | 68 | return userdata, err 69 | } 70 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/ogletest/srcutil/methods.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package srcutil 17 | 18 | import ( 19 | "fmt" 20 | "reflect" 21 | "runtime" 22 | "sort" 23 | ) 24 | 25 | func getLine(m reflect.Method) int { 26 | pc := m.Func.Pointer() 27 | 28 | f := runtime.FuncForPC(pc) 29 | if f == nil { 30 | panic(fmt.Sprintf("Couldn't get runtime func for method (pc=%d): %v", pc, m)) 31 | } 32 | 33 | _, line := f.FileLine(pc) 34 | return line 35 | } 36 | 37 | type sortableMethodSet []reflect.Method 38 | 39 | func (s sortableMethodSet) Len() int { 40 | return len(s) 41 | } 42 | 43 | func (s sortableMethodSet) Less(i, j int) bool { 44 | return getLine(s[i]) < getLine(s[j]) 45 | } 46 | 47 | func (s sortableMethodSet) Swap(i, j int) { 48 | s[i], s[j] = s[j], s[i] 49 | } 50 | 51 | // Given a type t, return all of the methods of t sorted such that source file 52 | // order is preserved. Order across files is undefined. Order within lines is 53 | // undefined. 54 | func GetMethodsInSourceOrder(t reflect.Type) []reflect.Method { 55 | // Build the list of methods. 56 | methods := sortableMethodSet{} 57 | for i := 0; i < t.NumMethod(); i++ { 58 | methods = append(methods, t.Method(i)) 59 | } 60 | 61 | // Sort it. 62 | sort.Sort(methods) 63 | 64 | return methods 65 | } 66 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/serializer.go: -------------------------------------------------------------------------------- 1 | package assertions 2 | 3 | import ( 4 | "encoding/json" 5 | "fmt" 6 | 7 | "github.com/smartystreets/goconvey/convey/reporting" 8 | ) 9 | 10 | type Serializer interface { 11 | serialize(expected, actual interface{}, message string) string 12 | serializeDetailed(expected, actual interface{}, message string) string 13 | } 14 | 15 | type failureSerializer struct{} 16 | 17 | func (self *failureSerializer) serializeDetailed(expected, actual interface{}, message string) string { 18 | view := self.format(expected, actual, message, "%#v") 19 | serialized, err := json.Marshal(view) 20 | if err != nil { 21 | return message 22 | } 23 | return string(serialized) 24 | } 25 | 26 | func (self *failureSerializer) serialize(expected, actual interface{}, message string) string { 27 | view := self.format(expected, actual, message, "%+v") 28 | serialized, err := json.Marshal(view) 29 | if err != nil { 30 | return message 31 | } 32 | return string(serialized) 33 | } 34 | 35 | func (self *failureSerializer) format(expected, actual interface{}, message string, format string) reporting.FailureView { 36 | return reporting.FailureView{ 37 | Message: message, 38 | Expected: fmt.Sprintf(format, expected), 39 | Actual: fmt.Sprintf(format, actual), 40 | } 41 | } 42 | 43 | func newSerializer() *failureSerializer { 44 | return &failureSerializer{} 45 | } 46 | 47 | /////////////////////////////////////////////////////// 48 | 49 | // noopSerializer just gives back the original message. This is useful when we are using 50 | // the assertions from a context other than the web UI, that requires the JSON structure 51 | // provided by the failureSerializer. 52 | type noopSerializer struct{} 53 | 54 | func (self *noopSerializer) serialize(expected, actual interface{}, message string) string { 55 | return message 56 | } 57 | func (self *noopSerializer) serializeDetailed(expected, actual interface{}, message string) string { 58 | return message 59 | } 60 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/utilities_for_test.go: -------------------------------------------------------------------------------- 1 | package assertions 2 | 3 | import ( 4 | "fmt" 5 | "path" 6 | "runtime" 7 | "strings" 8 | "testing" 9 | ) 10 | 11 | func pass(t *testing.T, result string) { 12 | if result != success { 13 | _, file, line, _ := runtime.Caller(1) 14 | base := path.Base(file) 15 | t.Errorf("Expectation should have passed but failed (see %s: line %d): '%s'", base, line, result) 16 | } 17 | } 18 | 19 | func fail(t *testing.T, actual string, expected string) { 20 | actual = format(actual) 21 | expected = format(expected) 22 | 23 | if actual != expected { 24 | if actual == "" { 25 | actual = "(empty)" 26 | } 27 | _, file, line, _ := runtime.Caller(1) 28 | base := path.Base(file) 29 | t.Errorf("Expectation should have failed but passed (see %s: line %d). \nExpected: %s\nActual: %s\n", 30 | base, line, expected, actual) 31 | } 32 | } 33 | func format(message string) string { 34 | message = strings.Replace(message, "\n", " ", -1) 35 | for strings.Contains(message, " ") { 36 | message = strings.Replace(message, " ", " ", -1) 37 | } 38 | return message 39 | } 40 | 41 | type Thing1 struct { 42 | a string 43 | } 44 | type Thing2 struct { 45 | a string 46 | } 47 | 48 | type Thinger interface { 49 | Hi() 50 | } 51 | 52 | type Thing struct{} 53 | 54 | func (self *Thing) Hi() {} 55 | 56 | type IntAlias int 57 | type StringAlias string 58 | type StringSliceAlias []string 59 | type StringStringMapAlias map[string]string 60 | 61 | /******** FakeSerialzier ********/ 62 | 63 | type fakeSerializer struct{} 64 | 65 | func (self *fakeSerializer) serialize(expected, actual interface{}, message string) string { 66 | return fmt.Sprintf("%v|%v|%s", expected, actual, message) 67 | } 68 | 69 | func (self *fakeSerializer) serializeDetailed(expected, actual interface{}, message string) string { 70 | return fmt.Sprintf("%v|%v|%s", expected, actual, message) 71 | } 72 | 73 | func newFakeSerializer() *fakeSerializer { 74 | return new(fakeSerializer) 75 | } 76 | -------------------------------------------------------------------------------- /pkg/datasrc/provider/openstack/openstack_test.go: -------------------------------------------------------------------------------- 1 | package openstack_test 2 | 3 | import ( 4 | "io/ioutil" 5 | "net/http" 6 | "path/filepath" 7 | "strings" 8 | "testing" 9 | 10 | . "github.com/smartystreets/goconvey/convey" 11 | "github.com/tmrts/flamingo/pkg/sys/ssh" 12 | . "github.com/tmrts/flamingo/pkg/util/testutil" 13 | 14 | "github.com/tmrts/flamingo/pkg/datasrc/provider" 15 | "github.com/tmrts/flamingo/pkg/datasrc/provider/openstack" 16 | ) 17 | 18 | const ( 19 | testMetadataDir = "test_metadata" 20 | ) 21 | 22 | func TestGoogleComputeMetadataRetrieval(t *testing.T) { 23 | Convey("Given a OpenStack meta-data service", t, func() { 24 | // mock OpenStack metadata server 25 | server := NewMockServer(func(w http.ResponseWriter, r *http.Request) { 26 | if strings.Contains(r.URL.String(), "2012-08-10/meta_data.json") { 27 | json_path := filepath.Join(testMetadataDir, "2012-08-10.json") 28 | 29 | buf, err := ioutil.ReadFile(json_path) 30 | if err != nil { 31 | http.Error(w, err.Error(), http.StatusBadRequest) 32 | return 33 | } 34 | 35 | w.Write(buf) 36 | } else if strings.Contains(r.URL.String(), "user_data") { 37 | w.Write([]byte("#cloud-config\n")) 38 | } else { 39 | http.Error(w, "requested resource is not found", http.StatusNotFound) 40 | } 41 | }) 42 | 43 | service := openstack.MetadataService{ 44 | URL: provider.FormatURL(server.URL + "/%v/%v"), 45 | } 46 | 47 | Convey("It should retrieve meta-data from OpenStack meta-data service", func() { 48 | digest, err := service.FetchMetadata() 49 | So(err, ShouldBeNil) 50 | 51 | So(digest.Hostname, ShouldEqual, "test.novalocal") 52 | 53 | So(digest.SSHKeys["mykey"], ShouldConsistOf, 54 | ssh.Key("ssh-rsa RSA_PUBLIC_KEY Generated by Nova")) 55 | }) 56 | 57 | Convey("It should retrieve user-data from OpenStack meta-data service", func() { 58 | userdata, err := service.FetchUserdata() 59 | So(err, ShouldBeNil) 60 | 61 | So(userdata["user-data"], ShouldEqual, "#cloud-config\n") 62 | }) 63 | 64 | }) 65 | } 66 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/init.go: -------------------------------------------------------------------------------- 1 | package convey 2 | 3 | import ( 4 | "flag" 5 | "os" 6 | 7 | "github.com/jtolds/gls" 8 | "github.com/smartystreets/assertions" 9 | "github.com/smartystreets/goconvey/convey/reporting" 10 | ) 11 | 12 | func init() { 13 | assertions.GoConveyMode(true) 14 | 15 | declareFlags() 16 | 17 | ctxMgr = gls.NewContextManager() 18 | } 19 | 20 | func declareFlags() { 21 | flag.BoolVar(&json, "json", false, "When true, emits results in JSON blocks. Default: 'false'") 22 | flag.BoolVar(&silent, "silent", false, "When true, all output from GoConvey is suppressed.") 23 | flag.BoolVar(&story, "story", false, "When true, emits story output, otherwise emits dot output. When not provided, this flag mirros the value of the '-test.v' flag") 24 | 25 | if noStoryFlagProvided() { 26 | story = verboseEnabled 27 | } 28 | 29 | // FYI: flag.Parse() is called from the testing package. 30 | } 31 | 32 | func noStoryFlagProvided() bool { 33 | return !story && !storyDisabled 34 | } 35 | 36 | func buildReporter() reporting.Reporter { 37 | switch { 38 | case testReporter != nil: 39 | return testReporter 40 | case json: 41 | return reporting.BuildJsonReporter() 42 | case silent: 43 | return reporting.BuildSilentReporter() 44 | case story: 45 | return reporting.BuildStoryReporter() 46 | default: 47 | return reporting.BuildDotReporter() 48 | } 49 | } 50 | 51 | var ( 52 | ctxMgr *gls.ContextManager 53 | 54 | // only set by internal tests 55 | testReporter reporting.Reporter 56 | ) 57 | 58 | var ( 59 | json bool 60 | silent bool 61 | story bool 62 | 63 | verboseEnabled = flagFound("-test.v=true") 64 | storyDisabled = flagFound("-story=false") 65 | ) 66 | 67 | // flagFound parses the command line args manually for flags defined in other 68 | // packages. Like the '-v' flag from the "testing" package, for instance. 69 | func flagFound(flagValue string) bool { 70 | for _, arg := range os.Args { 71 | if arg == flagValue { 72 | return true 73 | } 74 | } 75 | return false 76 | } 77 | -------------------------------------------------------------------------------- /pkg/sys/executor.go: -------------------------------------------------------------------------------- 1 | package sys 2 | 3 | import ( 4 | "errors" 5 | "fmt" 6 | "io/ioutil" 7 | "os/exec" 8 | ) 9 | 10 | // Executor is an interface representing the ability to execute given 11 | // a command and its arguments, and returning the output or the error. 12 | type Executor interface { 13 | Execute(string, ...string) (string, error) 14 | } 15 | 16 | type linux struct{} 17 | 18 | // Execute wraps the command execution pattern required in os/exec package. 19 | // The command is executed with the supplied arguments and the output is returned 20 | // to the caller. If an error occurs during the command execution, an error is 21 | // returned with the messages read from the stderr of the executed command. 22 | func (l *linux) Execute(executable string, args ...string) (string, error) { 23 | cmd := exec.Command(executable, args...) 24 | 25 | stdout, err := cmd.StdoutPipe() 26 | if err != nil { 27 | return "", err 28 | } 29 | 30 | stderr, err := cmd.StderrPipe() 31 | if err != nil { 32 | return "", err 33 | } 34 | 35 | if err := cmd.Start(); err != nil { 36 | return "", err 37 | } 38 | 39 | outBuf, err := ioutil.ReadAll(stdout) 40 | if err != nil { 41 | return "", err 42 | } 43 | out := string(outBuf) 44 | 45 | errBuf, err := ioutil.ReadAll(stderr) 46 | if err != nil { 47 | fmt.Println(errBuf) 48 | return "", err 49 | } 50 | errMsg := string(errBuf) 51 | 52 | if err := cmd.Wait(); err != nil { 53 | if errMsg != "" { 54 | return out, errors.New(errMsg) 55 | } 56 | 57 | return out, err 58 | } 59 | 60 | return out, nil 61 | } 62 | 63 | // DefaultExecutor is the default Executor and is used by Execute. 64 | var DefaultExecutor = &linux{} 65 | 66 | // Execute executes the given command along with its arguments and the output 67 | // is returned to the caller. If an error occurs during the command execution, 68 | // an error is returned with the messages read from the stderr of the executed command. 69 | func Execute(cmd string, args ...string) (string, error) { 70 | return DefaultExecutor.Execute(cmd, args...) 71 | } 72 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/story.go: -------------------------------------------------------------------------------- 1 | // TODO: in order for this reporter to be completely honest 2 | // we need to retrofit to be more like the json reporter such that: 3 | // 1. it maintains ScopeResult collections, which count assertions 4 | // 2. it reports only after EndStory(), so that all tick marks 5 | // are placed near the appropriate title. 6 | // 3. Under unit test 7 | 8 | package reporting 9 | 10 | import ( 11 | "fmt" 12 | "strings" 13 | ) 14 | 15 | type story struct { 16 | out *Printer 17 | titlesById map[string]string 18 | currentKey []string 19 | } 20 | 21 | func (self *story) BeginStory(story *StoryReport) {} 22 | 23 | func (self *story) Enter(scope *ScopeReport) { 24 | self.out.Indent() 25 | 26 | self.currentKey = append(self.currentKey, scope.Title) 27 | ID := strings.Join(self.currentKey, "|") 28 | 29 | if _, found := self.titlesById[ID]; !found { 30 | self.out.Println("") 31 | self.out.Print(scope.Title) 32 | self.out.Insert(" ") 33 | self.titlesById[ID] = scope.Title 34 | } 35 | } 36 | 37 | func (self *story) Report(report *AssertionResult) { 38 | if report.Error != nil { 39 | fmt.Print(redColor) 40 | self.out.Insert(error_) 41 | } else if report.Failure != "" { 42 | fmt.Print(yellowColor) 43 | self.out.Insert(failure) 44 | } else if report.Skipped { 45 | fmt.Print(yellowColor) 46 | self.out.Insert(skip) 47 | } else { 48 | fmt.Print(greenColor) 49 | self.out.Insert(success) 50 | } 51 | fmt.Print(resetColor) 52 | } 53 | 54 | func (self *story) Exit() { 55 | self.out.Dedent() 56 | self.currentKey = self.currentKey[:len(self.currentKey)-1] 57 | } 58 | 59 | func (self *story) EndStory() { 60 | self.titlesById = make(map[string]string) 61 | self.out.Println("\n") 62 | } 63 | 64 | func (self *story) Write(content []byte) (written int, err error) { 65 | return len(content), nil // no-op 66 | } 67 | 68 | func NewStoryReporter(out *Printer) *story { 69 | self := new(story) 70 | self.out = out 71 | self.titlesById = make(map[string]string) 72 | return self 73 | } 74 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglematchers/contains.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | import ( 19 | "fmt" 20 | "reflect" 21 | ) 22 | 23 | // Return a matcher that matches arrays slices with at least one element that 24 | // matches the supplied argument. If the argument x is not itself a Matcher, 25 | // this is equivalent to Contains(Equals(x)). 26 | func Contains(x interface{}) Matcher { 27 | var result containsMatcher 28 | var ok bool 29 | 30 | if result.elementMatcher, ok = x.(Matcher); !ok { 31 | result.elementMatcher = Equals(x) 32 | } 33 | 34 | return &result 35 | } 36 | 37 | type containsMatcher struct { 38 | elementMatcher Matcher 39 | } 40 | 41 | func (m *containsMatcher) Description() string { 42 | return fmt.Sprintf("contains: %s", m.elementMatcher.Description()) 43 | } 44 | 45 | func (m *containsMatcher) Matches(candidate interface{}) error { 46 | // The candidate must be a slice or an array. 47 | v := reflect.ValueOf(candidate) 48 | if v.Kind() != reflect.Slice && v.Kind() != reflect.Array { 49 | return NewFatalError("which is not a slice or array") 50 | } 51 | 52 | // Check each element. 53 | for i := 0; i < v.Len(); i++ { 54 | elem := v.Index(i) 55 | if matchErr := m.elementMatcher.Matches(elem.Interface()); matchErr == nil { 56 | return nil 57 | } 58 | } 59 | 60 | return fmt.Errorf("") 61 | } 62 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglematchers/pointee.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | import ( 19 | "errors" 20 | "fmt" 21 | "reflect" 22 | ) 23 | 24 | // Return a matcher that matches non-nil pointers whose pointee matches the 25 | // wrapped matcher. 26 | func Pointee(m Matcher) Matcher { 27 | return &pointeeMatcher{m} 28 | } 29 | 30 | type pointeeMatcher struct { 31 | wrapped Matcher 32 | } 33 | 34 | func (m *pointeeMatcher) Matches(c interface{}) (err error) { 35 | // Make sure the candidate is of the appropriate type. 36 | cv := reflect.ValueOf(c) 37 | if !cv.IsValid() || cv.Kind() != reflect.Ptr { 38 | return NewFatalError("which is not a pointer") 39 | } 40 | 41 | // Make sure the candidate is non-nil. 42 | if cv.IsNil() { 43 | return NewFatalError("") 44 | } 45 | 46 | // Defer to the wrapped matcher. Fix up empty errors so that failure messages 47 | // are more helpful than just printing a pointer for "Actual". 48 | pointee := cv.Elem().Interface() 49 | err = m.wrapped.Matches(pointee) 50 | if err != nil && err.Error() == "" { 51 | s := fmt.Sprintf("whose pointee is %v", pointee) 52 | 53 | if _, ok := err.(*FatalError); ok { 54 | err = NewFatalError(s) 55 | } else { 56 | err = errors.New(s) 57 | } 58 | } 59 | 60 | return err 61 | } 62 | 63 | func (m *pointeeMatcher) Description() string { 64 | return fmt.Sprintf("pointee(%s)", m.wrapped.Description()) 65 | } 66 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/reqtrace/README.md: -------------------------------------------------------------------------------- 1 | [![GoDoc](https://godoc.org/github.com/smartystreets/assertions/internal/reqtrace?status.svg)](https://godoc.org/github.com/smartystreets/assertions/internal/reqtrace) 2 | 3 | reqtrace is a package for simple request tracing. It requires nothing of its 4 | user except: 5 | 6 | * They must use [golang.org/x/net/context][context]. 7 | * They must add a single line to each function they want to be visible in 8 | traces. 9 | 10 | [context]: http://godoc.org/golang.org/x/net/context 11 | 12 | In particular, reqtrace is console-based and doesn't require an HTTP server. 13 | 14 | **Warning**: This package is still barebones and in its early days. I reserve 15 | the right to make backwards-incompatible changes to its API. But if it's useful 16 | to you in your current form, have at it. 17 | 18 | ## Use 19 | 20 | Call reqtrace.Trace anywhere you want to start a new root trace. (This is 21 | probably where you create your root context.) This returns a new context that 22 | you should pass to child operations, and a reporting function that you must use 23 | to inform reqtrace when the trace is complete. 24 | 25 | For example: 26 | 27 | ```Go 28 | func HandleRequest(r *someRequest) (err error) { 29 | ctx, report := reqtrace.Trace(context.Background(), "HandleRequest") 30 | defer func() { report(err) }() 31 | 32 | // Do two things for this request. 33 | DoSomething(ctx, r) 34 | DoSomethingElse(ctx, r) 35 | } 36 | ``` 37 | 38 | Within other functions that you want to show up in the trace, you 39 | reqtrace.StartSpan (or its more convenient sibling reqtrace.StartSpanWithError): 40 | 41 | ```Go 42 | func DoSomething(ctx context.Context, r *someRequest) (err error) { 43 | defer reqtrace.StartSpanWithError(&ctx, &err, "DoSomething")() 44 | 45 | // Process the request somehow using ctx. If downstream code also annotes 46 | // using reqtrace, reqtrace will know that its spans are descendants of 47 | // this one. 48 | CallAnotherLibrary(ctx, r.Param) 49 | } 50 | ``` 51 | 52 | When `--reqtrace.enable` is set, the completion of a trace will cause helpful 53 | ASCII art to be spit out. 54 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglematchers/matches_regexp.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglematchers 17 | 18 | import ( 19 | "errors" 20 | "fmt" 21 | "reflect" 22 | "regexp" 23 | ) 24 | 25 | // MatchesRegexp returns a matcher that matches strings and byte slices whose 26 | // contents match the supplied regular expression. The semantics are those of 27 | // regexp.Match. In particular, that means the match is not implicitly anchored 28 | // to the ends of the string: MatchesRegexp("bar") will match "foo bar baz". 29 | func MatchesRegexp(pattern string) Matcher { 30 | re, err := regexp.Compile(pattern) 31 | if err != nil { 32 | panic("MatchesRegexp: " + err.Error()) 33 | } 34 | 35 | return &matchesRegexpMatcher{re} 36 | } 37 | 38 | type matchesRegexpMatcher struct { 39 | re *regexp.Regexp 40 | } 41 | 42 | func (m *matchesRegexpMatcher) Description() string { 43 | return fmt.Sprintf("matches regexp \"%s\"", m.re.String()) 44 | } 45 | 46 | func (m *matchesRegexpMatcher) Matches(c interface{}) (err error) { 47 | v := reflect.ValueOf(c) 48 | isString := v.Kind() == reflect.String 49 | isByteSlice := v.Kind() == reflect.Slice && v.Elem().Kind() == reflect.Uint8 50 | 51 | err = errors.New("") 52 | 53 | switch { 54 | case isString: 55 | if m.re.MatchString(v.String()) { 56 | err = nil 57 | } 58 | 59 | case isByteSlice: 60 | if m.re.Match(v.Bytes()) { 61 | err = nil 62 | } 63 | 64 | default: 65 | err = NewFatalError("which is not a string or []byte") 66 | } 67 | 68 | return 69 | } 70 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/goconvey/convey/reporting/statistics.go: -------------------------------------------------------------------------------- 1 | package reporting 2 | 3 | import "fmt" 4 | 5 | func (self *statistics) BeginStory(story *StoryReport) {} 6 | 7 | func (self *statistics) Enter(scope *ScopeReport) {} 8 | 9 | func (self *statistics) Report(report *AssertionResult) { 10 | if !self.failing && report.Failure != "" { 11 | self.failing = true 12 | } 13 | if !self.erroring && report.Error != nil { 14 | self.erroring = true 15 | } 16 | if report.Skipped { 17 | self.skipped += 1 18 | } else { 19 | self.total++ 20 | } 21 | } 22 | 23 | func (self *statistics) Exit() {} 24 | 25 | func (self *statistics) EndStory() { 26 | if !self.suppressed { 27 | self.PrintSummary() 28 | } 29 | } 30 | 31 | func (self *statistics) Suppress() { 32 | self.suppressed = true 33 | } 34 | 35 | func (self *statistics) PrintSummary() { 36 | self.reportAssertions() 37 | self.reportSkippedSections() 38 | self.completeReport() 39 | } 40 | func (self *statistics) reportAssertions() { 41 | self.decideColor() 42 | self.out.Print("\n%d total %s", self.total, plural("assertion", self.total)) 43 | } 44 | func (self *statistics) decideColor() { 45 | if self.failing && !self.erroring { 46 | fmt.Print(yellowColor) 47 | } else if self.erroring { 48 | fmt.Print(redColor) 49 | } else { 50 | fmt.Print(greenColor) 51 | } 52 | } 53 | func (self *statistics) reportSkippedSections() { 54 | if self.skipped > 0 { 55 | fmt.Print(yellowColor) 56 | self.out.Print(" (one or more sections skipped)") 57 | } 58 | } 59 | func (self *statistics) completeReport() { 60 | fmt.Print(resetColor) 61 | self.out.Print("\n") 62 | self.out.Print("\n") 63 | } 64 | 65 | func (self *statistics) Write(content []byte) (written int, err error) { 66 | return len(content), nil // no-op 67 | } 68 | 69 | func NewStatisticsReporter(out *Printer) *statistics { 70 | self := statistics{} 71 | self.out = out 72 | return &self 73 | } 74 | 75 | type statistics struct { 76 | out *Printer 77 | total int 78 | failing bool 79 | erroring bool 80 | skipped int 81 | suppressed bool 82 | } 83 | 84 | func plural(word string, count int) string { 85 | if count == 1 { 86 | return word 87 | } 88 | return word + "s" 89 | } 90 | -------------------------------------------------------------------------------- /pkg/datasrc/datasource_test.go: -------------------------------------------------------------------------------- 1 | package datasrc_test 2 | 3 | import ( 4 | "io/ioutil" 5 | "net/http" 6 | "path/filepath" 7 | "strings" 8 | "testing" 9 | "time" 10 | 11 | . "github.com/smartystreets/goconvey/convey" 12 | 13 | "github.com/tmrts/flamingo/pkg/datasrc" 14 | "github.com/tmrts/flamingo/pkg/datasrc/provider" 15 | "github.com/tmrts/flamingo/pkg/datasrc/provider/gce" 16 | "github.com/tmrts/flamingo/pkg/util/testutil" 17 | ) 18 | 19 | func TestFetchsMetadata(t *testing.T) { 20 | Convey("Given a list of datasources and a timeout duration", t, func() { 21 | mockGCEServer := testutil.NewMockServer(func(w http.ResponseWriter, r *http.Request) { 22 | var json_path string 23 | if r.Header.Get("Metadata-Flavor") != "Google" { 24 | http.Error(w, "metadata header is not found", http.StatusBadRequest) 25 | return 26 | } 27 | 28 | testMetadataDir := "provider/gce/test_metadata" 29 | if strings.Contains(r.URL.String(), "project") { 30 | json_path = filepath.Join(testMetadataDir, "GCEv1_project.json") 31 | } else if strings.Contains(r.URL.String(), "instance") { 32 | json_path = filepath.Join(testMetadataDir, "GCEv1_instance.json") 33 | } else { 34 | http.Error(w, "requested resource is not found", http.StatusNotFound) 35 | return 36 | } 37 | 38 | buf, err := ioutil.ReadFile(json_path) 39 | if err != nil { 40 | http.Error(w, err.Error(), http.StatusBadRequest) 41 | return 42 | } 43 | 44 | w.Write(buf) 45 | }) 46 | 47 | mockGCEProvider := &gce.MetadataService{ 48 | URL: provider.FormatURL(mockGCEServer.URL + "/%v/%v"), 49 | } 50 | 51 | mockDataSources := map[string]datasrc.Provider{ 52 | "gce": mockGCEProvider, 53 | } 54 | 55 | timeout := time.Millisecond * 500 56 | 57 | Convey("It should find the available data source provider", func() { 58 | provider, err := datasrc.FindProvider(mockDataSources, timeout) 59 | So(err, ShouldBeNil) 60 | 61 | So(provider, ShouldEqual, mockGCEProvider) 62 | }) 63 | 64 | Convey("When datasources are unavailable it should timeout", func() { 65 | _, err := datasrc.FindProvider(map[string]datasrc.Provider{}, 0*time.Second) 66 | So(err, ShouldEqual, datasrc.ErrDatasourceRetrievalTimeout) 67 | }) 68 | }) 69 | } 70 | -------------------------------------------------------------------------------- /pkg/datasrc/provider/ec2/ec2_test.go: -------------------------------------------------------------------------------- 1 | package ec2_test 2 | 3 | import ( 4 | "net/http" 5 | "strings" 6 | "testing" 7 | 8 | . "github.com/smartystreets/goconvey/convey" 9 | . "github.com/tmrts/flamingo/pkg/util/testutil" 10 | 11 | "github.com/tmrts/flamingo/pkg/datasrc/provider" 12 | "github.com/tmrts/flamingo/pkg/datasrc/provider/ec2" 13 | "github.com/tmrts/flamingo/pkg/sys/ssh" 14 | ) 15 | 16 | const ( 17 | testMetadataDir = "test_metadata" 18 | ) 19 | 20 | func TestRetrievesDataFromEC2(t *testing.T) { 21 | Convey("Given an EC2 meta-data service", t, func() { 22 | // mock EC2 metadata server 23 | server := NewMockServer(func(w http.ResponseWriter, r *http.Request) { 24 | attributes := map[string]string{ 25 | "hostname": "centos.ec2", 26 | "local-ipv4": "10.240.51.29", 27 | "public-ipv4": "104.155.21.99", 28 | "public-keys/0/openssh-key": "ssh-rsa OPENSSH_KEY", 29 | } 30 | 31 | if strings.Contains(r.URL.String(), "/2009-04-04/meta-data/") { 32 | for attr, value := range attributes { 33 | if strings.HasSuffix(r.URL.String(), attr) { 34 | w.Write([]byte(value)) 35 | } 36 | } 37 | } else if strings.HasSuffix(r.URL.String(), "/2009-04-04/user-data") { 38 | w.Write([]byte("#cloud-config\n")) 39 | } else { 40 | http.Error(w, "requested resource is not found", http.StatusNotFound) 41 | } 42 | }) 43 | 44 | service := ec2.MetadataService{ 45 | URL: provider.FormatURL(server.URL + "/%v/%v/%v"), 46 | } 47 | 48 | Convey("It should retrieve meta-data from EC2 meta-data service", func() { 49 | digest, err := service.FetchMetadata() 50 | So(err, ShouldBeNil) 51 | 52 | So(digest.Hostname, ShouldEqual, "centos.ec2") 53 | 54 | ifc := digest.PrimaryNetworkInterface() 55 | So(ifc.PublicIPs[0].String(), ShouldEqual, "104.155.21.99") 56 | 57 | sshKeys := digest.SSHKeys 58 | 59 | So(sshKeys["root"], ShouldConsistOf, ssh.Key("ssh-rsa OPENSSH_KEY")) 60 | }) 61 | 62 | Convey("It should retrieve user-data from EC2 meta-data service", func() { 63 | userdata, err := service.FetchUserdata() 64 | So(err, ShouldBeNil) 65 | 66 | So(userdata["user-data"], ShouldEqual, "#cloud-config\n") 67 | }) 68 | 69 | }) 70 | } 71 | -------------------------------------------------------------------------------- /pkg/context/context_test.go: -------------------------------------------------------------------------------- 1 | package context_test 2 | 3 | import ( 4 | "errors" 5 | "testing" 6 | 7 | . "github.com/smartystreets/goconvey/convey" 8 | 9 | "github.com/tmrts/flamingo/pkg/context" 10 | ) 11 | 12 | type Signal int 13 | 14 | const ( 15 | Enter Signal = 1 + iota 16 | Exit 17 | Use 18 | ) 19 | 20 | type RandomNumberContext struct { 21 | EventChannel chan Signal 22 | 23 | seed int 24 | value int 25 | } 26 | 27 | // Enter prepares the resources to be used 28 | func (rnc *RandomNumberContext) Enter() error { 29 | rnc.value = rnc.seed 30 | 31 | rnc.EventChannel <- Enter 32 | 33 | return nil 34 | } 35 | 36 | // Exit cleans up after the context is used 37 | func (rnc *RandomNumberContext) Exit() error { 38 | rnc.value = 0 39 | 40 | rnc.EventChannel <- Exit 41 | return nil 42 | } 43 | 44 | // Use casts the given function to its own context function and calls it 45 | func (rnc *RandomNumberContext) Use(fn interface{}) error { 46 | closure := fn.(func(int) error) 47 | 48 | rnc.EventChannel <- Use 49 | return closure(rnc.value) 50 | } 51 | 52 | func TestUsingContexts(t *testing.T) { 53 | Convey("Given a context and a context use function", t, func() { 54 | NotEvenErr := errors.New("not a good number") 55 | 56 | checkIfEven := func(no int) error { 57 | if no%2 == 1 { 58 | return NotEvenErr 59 | } 60 | return nil 61 | } 62 | 63 | Convey("It should use the context in the order, Enter -> Use -> Exit", func() { 64 | ch := make(chan Signal) 65 | randomNumber := &RandomNumberContext{ 66 | seed: 2, 67 | EventChannel: ch, 68 | } 69 | 70 | errch := context.Using(randomNumber, checkIfEven) 71 | 72 | event1, event2, event3 := <-ch, <-ch, <-ch 73 | 74 | So(event1, ShouldEqual, Enter) 75 | So(event2, ShouldEqual, Use) 76 | So(event3, ShouldEqual, Exit) 77 | 78 | err := <-errch 79 | So(err, ShouldBeNil) 80 | }) 81 | 82 | Convey("It should propagate the errors encountered during use", func() { 83 | ch := make(chan Signal, 3) 84 | randomNumber := &RandomNumberContext{ 85 | seed: 3, 86 | EventChannel: ch, 87 | } 88 | errch := context.Using(randomNumber, checkIfEven) 89 | 90 | err := <-errch 91 | So(err, ShouldEqual, NotEvenErr) 92 | }) 93 | }) 94 | } 95 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/oglemock/invoke.go: -------------------------------------------------------------------------------- 1 | // Copyright 2012 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | package oglemock 17 | 18 | import ( 19 | "errors" 20 | "fmt" 21 | "reflect" 22 | ) 23 | 24 | // Create an Action that invokes the supplied function, returning whatever it 25 | // returns. The signature of the function must match that of the mocked method 26 | // exactly. 27 | func Invoke(f interface{}) Action { 28 | // Make sure f is a function. 29 | fv := reflect.ValueOf(f) 30 | fk := fv.Kind() 31 | 32 | if fk != reflect.Func { 33 | desc := "" 34 | if fk != reflect.Invalid { 35 | desc = fv.Type().String() 36 | } 37 | 38 | panic(fmt.Sprintf("Invoke: expected function, got %s", desc)) 39 | } 40 | 41 | return &invokeAction{fv} 42 | } 43 | 44 | type invokeAction struct { 45 | f reflect.Value 46 | } 47 | 48 | func (a *invokeAction) SetSignature(signature reflect.Type) error { 49 | // The signature must match exactly. 50 | ft := a.f.Type() 51 | if ft != signature { 52 | return errors.New(fmt.Sprintf("Invoke: expected %v, got %v", signature, ft)) 53 | } 54 | 55 | return nil 56 | } 57 | 58 | func (a *invokeAction) Invoke(vals []interface{}) []interface{} { 59 | // Create a slice of args for the function. 60 | in := make([]reflect.Value, len(vals)) 61 | for i, x := range vals { 62 | in[i] = reflect.ValueOf(x) 63 | } 64 | 65 | // Call the function and return its return values. 66 | out := a.f.Call(in) 67 | result := make([]interface{}, len(out)) 68 | for i, v := range out { 69 | result[i] = v.Interface() 70 | } 71 | 72 | return result 73 | } 74 | -------------------------------------------------------------------------------- /Godeps/_workspace/src/github.com/smartystreets/assertions/internal/ogletest/doc.go: -------------------------------------------------------------------------------- 1 | // Copyright 2011 Aaron Jacobs. All Rights Reserved. 2 | // Author: aaronjjacobs@gmail.com (Aaron Jacobs) 3 | // 4 | // Licensed under the Apache License, Version 2.0 (the "License"); 5 | // you may not use this file except in compliance with the License. 6 | // You may obtain a copy of the License at 7 | // 8 | // http://www.apache.org/licenses/LICENSE-2.0 9 | // 10 | // Unless required by applicable law or agreed to in writing, software 11 | // distributed under the License is distributed on an "AS IS" BASIS, 12 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 | // See the License for the specific language governing permissions and 14 | // limitations under the License. 15 | 16 | // Package ogletest provides a framework for writing expressive unit tests. It 17 | // integrates with the builtin testing package, so it works with the gotest 18 | // command. Unlike the testing package which offers only basic capabilities for 19 | // signalling failures, it offers ways to express expectations and get nice 20 | // failure messages automatically. 21 | // 22 | // For example: 23 | // 24 | // //////////////////////////////////////////////////////////////////////// 25 | // // testing package test 26 | // //////////////////////////////////////////////////////////////////////// 27 | // 28 | // someStr, err := ComputeSomeString() 29 | // if err != nil { 30 | // t.Errorf("ComputeSomeString: expected nil error, got %v", err) 31 | // } 32 | // 33 | // !strings.Contains(someStr, "foo") { 34 | // t.Errorf("ComputeSomeString: expected substring foo, got %v", someStr) 35 | // } 36 | // 37 | // //////////////////////////////////////////////////////////////////////// 38 | // // ogletest test 39 | // //////////////////////////////////////////////////////////////////////// 40 | // 41 | // someStr, err := ComputeSomeString() 42 | // ExpectEq(nil, err) 43 | // ExpectThat(someStr, HasSubstr("foo") 44 | // 45 | // Failure messages require no work from the user, and look like the following: 46 | // 47 | // foo_test.go:103: 48 | // Expected: has substring "foo" 49 | // Actual: "bar baz" 50 | // 51 | package ogletest 52 | -------------------------------------------------------------------------------- /pkg/sys/firewall/iptables/iptables_test.go: -------------------------------------------------------------------------------- 1 | package iptables_test 2 | 3 | import ( 4 | "testing" 5 | 6 | . "github.com/smartystreets/goconvey/convey" 7 | . "github.com/tmrts/flamingo/pkg/util/testutil" 8 | 9 | "github.com/tmrts/flamingo/pkg/sys" 10 | "github.com/tmrts/flamingo/pkg/sys/firewall" 11 | "github.com/tmrts/flamingo/pkg/sys/firewall/iptables" 12 | ) 13 | 14 | func TestAddingFirewallRules(t *testing.T) { 15 | Convey("Given an action, a target chain and a package filtering rule", t, func() { 16 | rule := &iptables.Rule{ 17 | Source: []string{"192.168.1.1", "192.168.1.2"}, 18 | Destination: []string{"192.168.1.3", "192.168.1.4"}, 19 | FromInterface: "eth0", 20 | ToInterface: "eth1", 21 | Protocol: "tcp", 22 | IsSyncPackage: true, 23 | Target: iptables.DropTarget, 24 | } 25 | 26 | action := iptables.Append 27 | 28 | chain := firewall.Chain{ 29 | Name: "INPUT", 30 | Table: firewall.Filter, 31 | } 32 | 33 | Convey("The firewall manager implementation should perform the action", func() { 34 | exec := sys.NewStubExecutor("", nil) 35 | fwllmgr := iptables.Implementation{exec} 36 | 37 | err := fwllmgr.Perform(action, chain, rule) 38 | So(err, ShouldBeNil) 39 | 40 | So(<-exec.Exec, ShouldEqual, "iptables") 41 | So(<-exec.Args, ShouldBeSuperSetOf, []string{ 42 | "--table=filter", 43 | "--append=INPUT", 44 | "--source=192.168.1.1,192.168.1.2", 45 | "--destination=192.168.1.3,192.168.1.4", 46 | "--in-interface=eth0", 47 | "--out-interface=eth1", 48 | "--protocol=tcp", 49 | "--jump=DROP", 50 | "--syn", 51 | }) 52 | }) 53 | }) 54 | 55 | Convey("When performing an operation", t, func() { 56 | exec := sys.NewStubExecutor("", nil) 57 | fwllmgr := iptables.Implementation{exec} 58 | 59 | chain := firewall.Chain{ 60 | Name: "INPUT", 61 | Table: firewall.Filter, 62 | } 63 | 64 | rule := &iptables.Rule{ 65 | Protocol: "tcp", 66 | Target: iptables.DropTarget, 67 | } 68 | 69 | Convey("The xtables lock should be acquired to prevent multiple updates at the same time", func() { 70 | err := fwllmgr.Perform(iptables.Append, chain, rule) 71 | So(err, ShouldBeNil) 72 | 73 | So(<-exec.Exec, ShouldEqual, "iptables") 74 | So(<-exec.Args, ShouldContain, "--wait") 75 | }) 76 | }) 77 | } 78 | --------------------------------------------------------------------------------