ansible-wrapper 0.1.2 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: c5d98c9b1e164d0509c09b64a132bdf51b8a6478
4
- data.tar.gz: 4057169e999f9cf5041eaa5bd8d378a8d4187d22
2
+ SHA256:
3
+ metadata.gz: ee765d2b80572fec0da1ec9ddc043211872330ed9a6f40fc062cb72d65c02c50
4
+ data.tar.gz: c849698d3def8e27a816ce340154aac9386b2f5d253e568d9560574472d250f9
5
5
  SHA512:
6
- metadata.gz: b1b58561ab5ca65cefdf80c8f7ba1e131385509db4e58975fa0dc7495af92e56c70b1090e339623c15127e97187648eb81b95280429fdafbb7f493c757a59d33
7
- data.tar.gz: bdf1a0f5974b2e1f7ee98dce419cc095a1a4167058931d45e7550f94e5336761c1b5e93dc40b01952f167dfd4a8ee0aa6d6e56a87e88778912b0aac980eded1b
6
+ metadata.gz: f1e61631280784a6a85d34593206abba2420d978e372a9b44d3fecfef48efdc16df50d603097dc2dfd9d11fcb4a92f31f836eed54fe0d77ee1006273522bdeb1
7
+ data.tar.gz: a95a9ebaa9019a503011a318a9c28256f2d1613b6a384b6bc2114875db687561dd34be830f9fa49a3f14d48cf0e9750b2e77ce447a13e016cb0d6c6ecd4ef0de
@@ -0,0 +1,33 @@
1
+ name: Test using different Ansible & Ruby versions
2
+
3
+ on: [push]
4
+
5
+ jobs:
6
+ build:
7
+ runs-on: ubuntu-latest
8
+ strategy:
9
+ matrix:
10
+ ansible:
11
+ - 2.0.2
12
+ - 2.1.6
13
+ - 2.2.3
14
+ - 2.3.3
15
+ - 2.4.6
16
+ - 2.5.15
17
+ - 2.6.19
18
+ - 2.7.12
19
+ - 2.8.5
20
+ steps:
21
+ - uses: actions/checkout@v1
22
+ - name: Run tests against Ruby 2.6.4
23
+ run: RUBY_VERSION=2.6.4 ANSIBLE_VERSION=${{ matrix.ansible }} && docker run --rm -v $PWD:/app pgeraghty/ansible-ruby:$RUBY_VERSION-$ANSIBLE_VERSION /bin/sh -c "cd /app && bundle install --jobs=3 --retry=3 && rake"
24
+ - name: Run tests against Ruby 2.5.6
25
+ run: RUBY_VERSION=2.5.6 ANSIBLE_VERSION=${{ matrix.ansible }} && docker run --rm -v $PWD:/app pgeraghty/ansible-ruby:$RUBY_VERSION-$ANSIBLE_VERSION /bin/sh -c "cd /app && bundle install --jobs=3 --retry=3 && rake"
26
+ - name: Run tests against Ruby 2.4.7
27
+ run: RUBY_VERSION=2.4.7 ANSIBLE_VERSION=${{ matrix.ansible }} && docker run --rm -v $PWD:/app pgeraghty/ansible-ruby:$RUBY_VERSION-$ANSIBLE_VERSION /bin/sh -c "cd /app && bundle install --jobs=3 --retry=3 && rake"
28
+ - name: Run tests against Ruby 2.3.7
29
+ run: RUBY_VERSION=2.3.7 ANSIBLE_VERSION=${{ matrix.ansible }} && docker run --rm -v $PWD:/app pgeraghty/ansible-ruby:$RUBY_VERSION-$ANSIBLE_VERSION /bin/sh -c "cd /app && bundle install --jobs=3 --retry=3 && rake"
30
+ - name: Run tests against Ruby 2.2.7
31
+ run: RUBY_VERSION=2.2.7 ANSIBLE_VERSION=${{ matrix.ansible }} && docker run --rm -v $PWD:/app pgeraghty/ansible-ruby:$RUBY_VERSION-$ANSIBLE_VERSION /bin/sh -c "cd /app && bundle install --jobs=3 --retry=3 && rake"
32
+ - name: Run tests against Ruby 2.1.10
33
+ run: RUBY_VERSION=2.1.10 ANSIBLE_VERSION=${{ matrix.ansible }} && docker run --rm -v $PWD:/app pgeraghty/ansible-ruby:$RUBY_VERSION-$ANSIBLE_VERSION /bin/sh -c "cd /app && bundle install --jobs=3 --retry=3 && rake"
data/.travis.yml CHANGED
@@ -1,21 +1,21 @@
1
- language: ruby
1
+ language: minimal
2
+ services:
3
+ - docker
2
4
  env:
3
- - ANSIBLE_VERSION=1.8.4
4
- - ANSIBLE_VERSION=1.9.4
5
- - ANSIBLE_VERSION=2.0.0.2
6
- - ANSIBLE_VERSION=2.1.0.0
7
- - ANSIBLE_VERSION=2.2.0.0
8
- rvm:
9
- - 2.1.8
10
- - 2.2.4
11
- - 2.3.0
12
- cache: bundler
13
- before_install:
14
- # make sure everything's up to date
15
- - sudo apt-get update -qq
16
- # install Python
17
- - sudo apt-get install python
18
- # upgrade pip
19
- - sudo pip install --upgrade pip
20
- # install Ansible
21
- - sudo pip install ansible==$ANSIBLE_VERSION
5
+ - ANSIBLE_VERSION=2.0.2
6
+ - ANSIBLE_VERSION=2.1.6
7
+ - ANSIBLE_VERSION=2.2.3
8
+ - ANSIBLE_VERSION=2.3.3
9
+ - ANSIBLE_VERSION=2.4.6
10
+ - ANSIBLE_VERSION=2.5.15
11
+ - ANSIBLE_VERSION=2.6.19
12
+ - ANSIBLE_VERSION=2.7.12
13
+ - ANSIBLE_VERSION=2.8.5
14
+ - RUBY_VERSION=2.1.10
15
+ - RUBY_VERSION=2.2.7
16
+ - RUBY_VERSION=2.3.7
17
+ - RUBY_VERSION=2.4.7
18
+ - RUBY_VERSION=2.5.6
19
+ - RUBY_VERSION=2.6.4
20
+ script:
21
+ - docker run --rm -it -v $PWD:/app pgeraghty/ansible-ruby:$RUBY_VERSION-$ANSIBLE_VERSION /bin/sh -c cd /app && bundle install --jobs=3 --retry=3 --deployment && rake
data/README.md CHANGED
@@ -1,8 +1,8 @@
1
1
  # Ansible Wrapper
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/ansible-wrapper.svg)](http://badge.fury.io/rb/ansible-wrapper)
4
- [![Build Status](https://travis-ci.org/pgeraghty/ansible-wrapper-ruby.svg?branch=master)](https://travis-ci.org/pgeraghty/ansible-wrapper-ruby)
5
- [![Coverage Status](https://coveralls.io/repos/pgeraghty/ansible-wrapper-ruby/badge.svg?branch=master&service=github)](https://coveralls.io/github/pgeraghty/ansible-wrapper-ruby?branch=master)
4
+ [![Build Status](https://travis-ci.com/pgeraghty/ansible-wrapper-ruby.svg?branch=master)](https://travis-ci.com/pgeraghty/ansible-wrapper-ruby)
5
+ [![Coverage Status](https://coveralls.io/repos/github/pgeraghty/ansible-wrapper-ruby/badge.svg?branch=master)](https://coveralls.io/github/pgeraghty/ansible-wrapper-ruby?branch=master)
6
6
  [![Code Climate](https://codeclimate.com/github/pgeraghty/ansible-wrapper-ruby/badges/gpa.svg)](https://codeclimate.com/github/pgeraghty/ansible-wrapper-ruby)
7
7
 
8
8
  #### A lightweight Ruby wrapper around Ansible that allows for ad-hoc commands and playbook execution. The primary purpose is to support easy streaming output.
Binary file
@@ -31,4 +31,5 @@ Gem::Specification.new do |spec|
31
31
  spec.add_development_dependency 'rake', '~> 10.0'
32
32
  spec.add_development_dependency 'rspec'
33
33
  spec.add_development_dependency 'coveralls'
34
+ spec.add_development_dependency 'json', '~> 1.8.4'
34
35
  end
@@ -0,0 +1,6 @@
1
+ source 'https://rubygems.org'
2
+
3
+ gem 'sinatra'
4
+ gem 'thin'
5
+
6
+ gem 'ansible-wrapper', path: '../../' #github: 'pgeraghty/ansible-wrapper-ruby'
@@ -0,0 +1,35 @@
1
+ PATH
2
+ remote: ../..
3
+ specs:
4
+ ansible-wrapper (0.2.0)
5
+
6
+ GEM
7
+ remote: https://rubygems.org/
8
+ specs:
9
+ daemons (1.3.1)
10
+ eventmachine (1.2.7)
11
+ mustermann (1.0.3)
12
+ rack (2.0.7)
13
+ rack-protection (2.0.7)
14
+ rack
15
+ sinatra (2.0.7)
16
+ mustermann (~> 1.0)
17
+ rack (~> 2.0)
18
+ rack-protection (= 2.0.7)
19
+ tilt (~> 2.0)
20
+ thin (1.7.2)
21
+ daemons (~> 1.0, >= 1.0.9)
22
+ eventmachine (~> 1.0, >= 1.0.4)
23
+ rack (>= 1, < 3)
24
+ tilt (2.0.9)
25
+
26
+ PLATFORMS
27
+ ruby
28
+
29
+ DEPENDENCIES
30
+ ansible-wrapper!
31
+ sinatra
32
+ thin
33
+
34
+ BUNDLED WITH
35
+ 1.17.3
@@ -0,0 +1,4 @@
1
+ require 'rubygems'
2
+ require './run'
3
+
4
+ run Sinatra::Application
@@ -0,0 +1,71 @@
1
+ require 'sinatra'
2
+
3
+ require 'ansible-wrapper'
4
+
5
+ set server: 'thin'
6
+ set :environment, :production
7
+ set :bind, '0.0.0.0'
8
+ set :port, 4567
9
+
10
+ Process.setproctitle 'Ansible Streaming Example'
11
+
12
+
13
+ CONSOLE_OUTPUT_START = %{<!doctype html>
14
+ <html>
15
+ <head>
16
+ <meta charset="utf-8" />
17
+ <style>
18
+ body {
19
+ background-color: #{background ||= 'black'}; color: #{color ||= 'white'};
20
+ }
21
+ .bold {
22
+ font-weight: bold;
23
+ }
24
+ .black {
25
+ color: black;
26
+ }
27
+ .red {
28
+ color: red;
29
+ }
30
+ .green {
31
+ color: green;
32
+ }
33
+ .yellow {
34
+ color: yellow;
35
+ }
36
+ .blue {
37
+ color: blue;
38
+ }
39
+ .magenta {
40
+ color: magenta;
41
+ }
42
+ .cyan {
43
+ color: cyan;
44
+ }
45
+ .white {
46
+ color: white;
47
+ }
48
+ .grey {
49
+ color: grey;
50
+ }
51
+ </style>
52
+ </head>
53
+ <body><pre><code>}
54
+
55
+ CONSOLE_OUTPUT_END = '</code></pre></body></html>'
56
+
57
+
58
+ get '/' do
59
+ "Ansible #{Ansible::Config::VERSION}"
60
+ end
61
+
62
+ get '/streaming' do
63
+ #content_type 'text/plain'
64
+ stream do |out|
65
+ out << CONSOLE_OUTPUT_START
66
+ Ansible.stream ['-i', 'localhost,', File.expand_path('../../../spec/mock_playbook.yml', __FILE__)]*' ' do |line|
67
+ Ansible::Output.to_html line, out
68
+ end
69
+ out << CONSOLE_OUTPUT_END
70
+ end
71
+ end
@@ -1,14 +1,15 @@
1
1
  require 'ansible/version'
2
+ require 'ansible/config'
2
3
  require 'ansible/ad_hoc'
3
4
  require 'ansible/playbook'
5
+ require 'ansible/output'
4
6
 
5
7
  module Ansible
6
- extend self
7
- ENV = {}
8
+ include Ansible::Config
9
+ include Ansible::Methods
10
+ include Ansible::PlaybookMethods
8
11
 
9
- def env_string
10
- ENV.map { |a| a*'=' }*' '
11
- end
12
+ extend self
12
13
 
13
14
  def enable_shortcuts!
14
15
  require 'ansible/shortcuts'
@@ -1,11 +1,35 @@
1
+ module Ansible::Methods
2
+ BIN = 'ansible'
3
+
4
+ def one_off cmd
5
+ `#{config.to_s "#{BIN} #{cmd}"}`
6
+ end
7
+ alias :[] :one_off
8
+
9
+ # this solution should work for Ansible pre-2.0 as well as 2.0+
10
+ def list_hosts cmd
11
+ one_off("#{cmd} --list-hosts").scan(IP_OR_HOSTNAME).map { |ip| ip.first.strip }
12
+ end
13
+
14
+ def parse_host_vars(host, inv_file, filter = 'hostvars[inventory_hostname]')
15
+ hostvars_filter = filter
16
+ cmd = "all -m debug -a 'var=#{hostvars_filter}' -i #{inv_file} -l #{host} --one-line"
17
+ hostvars = JSON.parse(self[cmd].split(/>>|=>/).last)
18
+
19
+ if Gem::Version.new(Ansible::Config::VERSION) >= Gem::Version.new('2.0')
20
+ hostvars[hostvars_filter]
21
+ else
22
+ hostvars['var'][hostvars_filter]
23
+ end
24
+ end
25
+ end
26
+
1
27
  module Ansible
2
28
  module AdHoc
3
- extend self
4
- BIN = 'ansible'
29
+ include Ansible::Config
30
+ include Ansible::Methods
5
31
 
6
- def run(cmd, _opts={})
7
- cmd_line = [Ansible.env_string, BIN, cmd]*' '
8
- `#{cmd_line}`
9
- end
32
+ extend self
33
+ alias :run :one_off
10
34
  end
11
35
  end
@@ -0,0 +1,53 @@
1
+ module Ansible::Config
2
+ PATH = 'lib/ansible/'
3
+ IP_OR_HOSTNAME = /((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.(25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)){3})$|^((([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9\-]*[a-zA-Z0-9])\.)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9\-]*[A-Za-z0-9]))/
4
+ SKIP_HOSTVARS = %w(ansible_version inventory_dir inventory_file inventory_hostname inventory_hostname_short group_names groups omit playbook_dir)
5
+ VERSION = `ansible --version`.split("\n").first.split.last rescue nil # nil when Ansible not installed
6
+
7
+ DefaultConfig = Struct.new(:env, :extra_vars, :params) do
8
+ def initialize
9
+ self.env = {
10
+ 'ANSIBLE_FORCE_COLOR' => 'True',
11
+ 'ANSIBLE_HOST_KEY_CHECKING' => 'False'
12
+ }
13
+
14
+ self.params = {
15
+ debug: false
16
+ }
17
+
18
+ # options
19
+ self.extra_vars = {
20
+ # skip creation of .retry files
21
+ 'retry_files_enabled' => 'False'
22
+ }
23
+ # TODO support --ssh-common-args, --ssh-extra-args
24
+ # e.g. ansible-playbook --ssh-common-args="-o ServerAliveInterval=60" -i inventory install.yml
25
+ end
26
+
27
+ # NB: --extra-vars can also accept JSON string, see http://stackoverflow.com/questions/25617273/pass-array-in-extra-vars-ansible
28
+ def options
29
+ x = extra_vars.each_with_object('--extra-vars=\'') { |kv, a| a << "#{kv.first}=\"#{kv.last}\" " }.strip+'\'' if extra_vars unless extra_vars.empty?
30
+ # can test with configure { |config| config.extra_vars.clear }
31
+
32
+ [x, '--ssh-extra-args=\'-o UserKnownHostsFile=/dev/null\'']*' '
33
+ end
34
+
35
+ def to_s(cmd)
36
+ entire_cmd = [env.each_with_object([]) { |kv, a| a << kv*'=' } * ' ', cmd, options]*' '
37
+ puts entire_cmd if params[:debug]
38
+ entire_cmd
39
+ end
40
+ end
41
+
42
+ def configure
43
+ @config ||= DefaultConfig.new
44
+ yield(@config) if block_given?
45
+
46
+ # allow chaining if block given
47
+ block_given? ? self : @config
48
+ end
49
+
50
+ def config
51
+ @config || configure
52
+ end
53
+ end
@@ -0,0 +1,47 @@
1
+ require 'strscan'
2
+ require 'erb'
3
+
4
+ module Ansible::Output
5
+ COLOR = {
6
+ '1' => 'font-weight: bold',
7
+ '30' => 'color: black',
8
+ '31' => 'color: red',
9
+ '32' => 'color: green',
10
+ '33' => 'color: yellow',
11
+ '34' => 'color: blue',
12
+ '35' => 'color: magenta',
13
+ '36' => 'color: cyan',
14
+ '37' => 'color: white',
15
+ '90' => 'color: grey'
16
+ }
17
+
18
+ def self.to_html(line, stream='')
19
+ s = StringScanner.new(ERB::Util.h line)
20
+ while(!s.eos?)
21
+ if s.scan(/\e\[([0-1]);(3[0-7]|90|1)m/)
22
+ bold, colour = s.captures
23
+ styles = []
24
+
25
+ styles << COLOR[bold] if bold.to_i == 1
26
+ styles << COLOR[colour]
27
+
28
+ span =
29
+ if styles.empty?
30
+ %{<span>}
31
+ else
32
+ %{<span style="#{styles*'; '};">}
33
+ end
34
+
35
+ stream << span
36
+ else
37
+ if s.scan(/\e\[0m/)
38
+ stream << %{</span>}
39
+ else
40
+ stream << s.scan(/./m)
41
+ end
42
+ end
43
+ end
44
+
45
+ stream
46
+ end
47
+ end
@@ -1,23 +1,38 @@
1
1
  require 'ansible/safe_pty'
2
2
 
3
3
  module Ansible
4
- module Playbook
4
+ module PlaybookMethods
5
5
  BIN = 'ansible-playbook'
6
- extend self
7
-
8
- def run(cmd, _opts={})
9
- cmd_line = [Ansible.env_string, 'ANSIBLE_FORCE_COLOR=True', BIN, cmd]*' '
10
6
 
11
- `#{cmd_line}`
7
+ def playbook pb
8
+ `#{config.to_s "#{BIN} #{pb}"}`
12
9
  end
10
+ alias :<< :playbook
13
11
 
14
- # This method uses PTY because otherwise output is buffered
15
- def stream(cmd, _opts={})
16
- cmd_line = [Ansible.env_string, 'ANSIBLE_FORCE_COLOR=True', BIN, cmd]*' '
12
+ def stream pb
13
+ # Use PTY because otherwise output is buffered
14
+ SafePty.spawn config.to_s("#{BIN} #{pb}") do |r,w,p| # add -vvvv here for verbose
15
+ until r.eof? do
16
+ line = r.gets
17
+ block_given? ? yield(line) : puts(line)
17
18
 
18
- SafePty.spawn(cmd_line) do |r,_w,_p|
19
- block_given? ? yield(r.gets) : puts(r.gets) until r.eof?
19
+ raise "FAILED: #{line}" if line.include?('fatal: [')
20
+ raise Playbook::Exception.new("ERROR: #{line}") if line.include?('ERROR!')
21
+ # TODO raise if contains FAILED!
22
+ end
20
23
  end
21
24
  end
22
25
  end
26
+ end
27
+
28
+ module Ansible
29
+ module Playbook
30
+ include Ansible::Config
31
+ include Ansible::PlaybookMethods
32
+
33
+ extend self
34
+ alias :run :playbook
35
+
36
+ class Exception < RuntimeError; end
37
+ end
23
38
  end
@@ -1,6 +1,6 @@
1
1
  require 'pty'
2
2
 
3
- module SafePty
3
+ module Ansible::SafePty
4
4
  def self.spawn(command)
5
5
 
6
6
  PTY.spawn(command) do |r,w,p|
@@ -1,3 +1,3 @@
1
1
  module Ansible
2
- VERSION = '0.1.2'
2
+ VERSION = '0.2.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ansible-wrapper
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.2
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Paul Geraghty
8
8
  autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2016-11-14 00:00:00.000000000 Z
11
+ date: 2019-09-18 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -66,6 +66,20 @@ dependencies:
66
66
  - - ">="
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: json
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - "~>"
74
+ - !ruby/object:Gem::Version
75
+ version: 1.8.4
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - "~>"
81
+ - !ruby/object:Gem::Version
82
+ version: 1.8.4
69
83
  description: A lightweight Ruby wrapper around Ansible that allows for ad-hoc commands
70
84
  and playbook execution.
71
85
  email:
@@ -74,6 +88,7 @@ executables: []
74
88
  extensions: []
75
89
  extra_rdoc_files: []
76
90
  files:
91
+ - ".github/workflows/test_via_docker.yml"
77
92
  - ".gitignore"
78
93
  - ".rspec"
79
94
  - ".travis.yml"
@@ -81,11 +96,18 @@ files:
81
96
  - LICENSE.txt
82
97
  - README.md
83
98
  - Rakefile
99
+ - ansible-wrapper-0.1.2.gem
84
100
  - ansible-wrapper.gemspec
85
101
  - bin/console
86
102
  - bin/setup
103
+ - examples/streaming/Gemfile
104
+ - examples/streaming/Gemfile.lock
105
+ - examples/streaming/config.ru
106
+ - examples/streaming/run.rb
87
107
  - lib/ansible-wrapper.rb
88
108
  - lib/ansible/ad_hoc.rb
109
+ - lib/ansible/config.rb
110
+ - lib/ansible/output.rb
89
111
  - lib/ansible/playbook.rb
90
112
  - lib/ansible/safe_pty.rb
91
113
  - lib/ansible/shortcuts.rb
@@ -109,8 +131,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
109
131
  - !ruby/object:Gem::Version
110
132
  version: '0'
111
133
  requirements: []
112
- rubyforge_project:
113
- rubygems_version: 2.4.8
134
+ rubygems_version: 3.0.6
114
135
  signing_key:
115
136
  specification_version: 4
116
137
  summary: Ruby wrapper around Ansible