appforce-spawn 0.5.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.appforce.example +4 -0
- data/.gitignore +8 -0
- data/Gemfile +17 -0
- data/History +85 -0
- data/README.md +144 -0
- data/ansible/README.md +31 -0
- data/ansible/common.yml +6 -0
- data/ansible/roles/common/tasks/.keep +0 -0
- data/ansible/roles/common/tasks/active_users.yml +23 -0
- data/ansible/roles/common/tasks/groups.yml +28 -0
- data/ansible/roles/common/tasks/inactive_users.yml +26 -0
- data/ansible/roles/common/tasks/main.yml +5 -0
- data/ansible/roles/common/tasks/setup.yml +6 -0
- data/ansible/roles/scout/tasks/.keep +0 -0
- data/ansible/roles/scout/tasks/install.yml +28 -0
- data/ansible/roles/scout/tasks/main.yml +2 -0
- data/ansible/roles/scout/vars/.keep +0 -0
- data/ansible/rvm.yml +13 -0
- data/ansible/scout.yml +6 -0
- data/ansible/site.yml +4 -0
- data/appforce-spawn.gemspec +24 -0
- data/bin/appforce-spawn +161 -0
- data/lib/appforce-spawn.rb +1 -0
- data/lib/appforce/config.rb +50 -0
- data/lib/appforce/logger.rb +25 -0
- data/lib/appforce/spawn.rb +312 -0
- data/lib/appforce/spawn/api.rb +4 -0
- data/lib/appforce/spawn/api/call.rb +217 -0
- data/lib/appforce/spawn/exceptions.rb +30 -0
- data/lib/appforce/spawn/runner.rb +143 -0
- data/lib/appforce/spawn/template.rb +102 -0
- data/lib/appforce/spawn/version.rb +10 -0
- data/spec/api_call_spec.rb +380 -0
- data/spec/config_spec.rb +51 -0
- data/spec/fixtures/all_host_data.json +12 -0
- data/spec/fixtures/appforce_config.yml +4 -0
- data/spec/fixtures/fake_private_key.yml +2 -0
- data/spec/fixtures/host_scout_vars.yml +10 -0
- data/spec/fixtures/hosts +8 -0
- data/spec/fixtures/inactive_users.yml +3 -0
- data/spec/fixtures/malformed_appforce_config.yml +4 -0
- data/spec/fixtures/private_key_vars.yml +4 -0
- data/spec/fixtures/scout_main.yml +2 -0
- data/spec/fixtures/users.yml +6 -0
- data/spec/fixtures/vars.yml +4 -0
- data/spec/logger_spec.rb +85 -0
- data/spec/runner_spec.rb +308 -0
- data/spec/spec_helper.rb +53 -0
- data/spec/template_spec.rb +160 -0
- data/spec/version_spec.rb +9 -0
- data/tmp/.keep +0 -0
- metadata +151 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: 7817cea2096d669789f0d3248310881e250a169b
|
4
|
+
data.tar.gz: c4f73c8a425d966b31f8b05f072ca4de4869ed36
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 3b9040432f79b6d60d1cc5c7054e45f6b517b4831e1a51ac7bfb0b6d600bf03304a438492deee6c020567635725673107a252dd0757633fd0e125b8554e06bc2
|
7
|
+
data.tar.gz: 78d17949f4f5566f765c14d504c5dcb62095734d1e7051b216d726f8a4cc2b6519106aa3760f56c412a72799dcce8fda9c750eb7a190522bf3ba55142f3f08cf
|
data/.appforce.example
ADDED
data/.gitignore
ADDED
data/Gemfile
ADDED
@@ -0,0 +1,17 @@
|
|
1
|
+
source 'https://rubygems.org'
|
2
|
+
gemspec
|
3
|
+
|
4
|
+
gem 'rake'
|
5
|
+
gem 'httparty'
|
6
|
+
gem 'highline'
|
7
|
+
|
8
|
+
group :development do
|
9
|
+
gem 'guard'
|
10
|
+
gem 'guard-rspec'
|
11
|
+
gem 'guard-bundler'
|
12
|
+
end
|
13
|
+
|
14
|
+
group :test do
|
15
|
+
gem 'rspec', '~> 3.1'
|
16
|
+
gem 'simplecov', require: false
|
17
|
+
end
|
data/History
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
== 0.5.1 2015-06-25
|
2
|
+
|
3
|
+
* remove inactive users from groups
|
4
|
+
|
5
|
+
== 0.5.0 2015-06-24
|
6
|
+
|
7
|
+
* updated to work with new users API
|
8
|
+
|
9
|
+
== 0.4.1 2015-06-11
|
10
|
+
|
11
|
+
* added version checking
|
12
|
+
|
13
|
+
== 0.4.0 2015-06-10
|
14
|
+
|
15
|
+
* new scout install procedure for host machines
|
16
|
+
* added version print commands
|
17
|
+
|
18
|
+
== 0.3.3a
|
19
|
+
|
20
|
+
* added external dependencies check before running ansible
|
21
|
+
|
22
|
+
== 0.3.2 2015-03-30
|
23
|
+
|
24
|
+
* added ability to supply a pem file
|
25
|
+
|
26
|
+
== 0.3.1 2015-03-25
|
27
|
+
|
28
|
+
* hotfix for ssh
|
29
|
+
|
30
|
+
== 0.3.0 2015-03-25
|
31
|
+
|
32
|
+
* added client host SSH feature
|
33
|
+
* cleaned up presentation
|
34
|
+
|
35
|
+
== 0.2.5 2015-03-20
|
36
|
+
|
37
|
+
* Added rvm install support
|
38
|
+
* added Scout App install support
|
39
|
+
|
40
|
+
== 0.2.4 2015-03-17
|
41
|
+
|
42
|
+
* Add rspec tests
|
43
|
+
* 90% test coverage
|
44
|
+
|
45
|
+
== 0.2.3 2015-03-13
|
46
|
+
|
47
|
+
* Moved to production API endpoint
|
48
|
+
|
49
|
+
== 0.2.2 2015-03-13
|
50
|
+
|
51
|
+
* Cleaned up structure of code
|
52
|
+
* Added ping helper methods
|
53
|
+
* Added Ansible ping command
|
54
|
+
* Improved logging and output
|
55
|
+
|
56
|
+
== 0.2.1 2015-03-12
|
57
|
+
|
58
|
+
* Fixed release timestamp
|
59
|
+
|
60
|
+
== 0.2.0 2015-03-12
|
61
|
+
|
62
|
+
* Added ansible run commands
|
63
|
+
* Restructured commands and messages
|
64
|
+
* Improved error messages
|
65
|
+
|
66
|
+
== 0.1.2 2015-03-12
|
67
|
+
|
68
|
+
* Updated Dependency on httparty
|
69
|
+
|
70
|
+
== 0.1.1 2015-03-12
|
71
|
+
|
72
|
+
* Updated Dependency on httparty
|
73
|
+
* Changed default config location to ~/.appforce
|
74
|
+
* Added example config dump option
|
75
|
+
* Cleaned up output
|
76
|
+
* Moved output to STDERR for messages from the script on API calls that render API output to STDOUT. This should allow for piping of STDOUT from the script without issue.
|
77
|
+
|
78
|
+
== 0.1.0 2015-03-11
|
79
|
+
|
80
|
+
* Initial POC complete
|
81
|
+
* Templating engine in place and functional
|
82
|
+
|
83
|
+
== 0.0.1 2015-03-10
|
84
|
+
|
85
|
+
* Initial development
|
data/README.md
ADDED
@@ -0,0 +1,144 @@
|
|
1
|
+
# appforce-ssh-manager
|
2
|
+
Ansible tool to manage the deployment of ssh keys and user profiles to client servers
|
3
|
+
|
4
|
+
# gem appforce-spawn
|
5
|
+
---
|
6
|
+
|
7
|
+
## Installation
|
8
|
+
|
9
|
+
The gem is published on [RubyGems.org](https://rubygems.org/gems/appforce-spawn).
|
10
|
+
|
11
|
+
```
|
12
|
+
$ gem install appforce-spawn
|
13
|
+
```
|
14
|
+
|
15
|
+
This will install the gem and script.
|
16
|
+
|
17
|
+
## Usage
|
18
|
+
|
19
|
+
It requires a `.appforce` configuration file in your home directory to operate. Once the gem is installed you can run `appforce-spawn -D` to dump an example config to your home directory (`~/.appforce.example`). This will have all you need, except for your API token. This token can be found by logging into the [API Admin](http://afuka.synctree.com). If you do not have an account on the Admin, please contact [Derek Smith](https://github.com/clok).
|
20
|
+
|
21
|
+
The tool has help information and a list of available action commands.
|
22
|
+
|
23
|
+
```
|
24
|
+
$ appforce-spawn -h
|
25
|
+
USAGE: appforce-spawn [options]
|
26
|
+
-a, --action [ACTION] Action to perform. Use '-l' to view all available actions
|
27
|
+
-l, --list_actions List available Actions
|
28
|
+
-C, --client [CLIENT API NAME] API Client Name to use for calls
|
29
|
+
-c, --config [PATH] Optional custom config file
|
30
|
+
-D, --dump-config Generate a example config template (to ~/.appforce.example)
|
31
|
+
-v, --verbose If set, print verbose output
|
32
|
+
-h, --help Show help documentation
|
33
|
+
```
|
34
|
+
|
35
|
+
```
|
36
|
+
$ appforce-spawn -l
|
37
|
+
== Available Actions ==
|
38
|
+
clients # Retrieve a complete list of Clients
|
39
|
+
generate # Build out the Ansible template for a Client (client API name is required)
|
40
|
+
client:hosts # Retrieve a Hosts file for a Client (client API name is required)
|
41
|
+
client:users # Retrieve a Users file for a Client (client API name is required)
|
42
|
+
client:vars # Retrieve a Vars file for a Client (client API name is required)
|
43
|
+
ping # Test connection to host and API access
|
44
|
+
ping:host # Test if API is available
|
45
|
+
ping:api # Test if you have access to the API
|
46
|
+
spawn # Run Ansible Playbook to spawn users to Client hosts
|
47
|
+
spawn:command # Display Ansible command to run Playbook for a Client
|
48
|
+
spawn:ping # Ansible ping Client hosts in the 'hosts' file
|
49
|
+
spawn:ping:command # Display ansible ping command
|
50
|
+
=========================
|
51
|
+
```
|
52
|
+
|
53
|
+
## Typical Workflow
|
54
|
+
|
55
|
+
- `appforce-spawn -a clients` will return the list of available clients and API names for those clients.
|
56
|
+
- `appforce-spawn -a generate -C [Client API Name]` will generate the Ansible template for that client, making directories and downloading files.
|
57
|
+
- `cd [Client API Name]` change into the template directory that was just created.
|
58
|
+
- `appforce-spawn -a spawn:ping` will test the configuration that was just downloaded as well as connectivity to the Client hosts.
|
59
|
+
- `appforce-spawn -a spawn` will run the Ansible Playbook to generate the User Groups, Users and set permissions.
|
60
|
+
|
61
|
+
# Testing Locally
|
62
|
+
---
|
63
|
+
|
64
|
+
## Notes
|
65
|
+
|
66
|
+
Helpful [Ansible introduction](http://docs.ansible.com/intro_installation.html)
|
67
|
+
|
68
|
+
For Mac use [Homebrew](http://brew.sh/) (brew):
|
69
|
+
|
70
|
+
```
|
71
|
+
$ brew update
|
72
|
+
$ brew install ansible
|
73
|
+
```
|
74
|
+
|
75
|
+
You will need the [vagrant-triggers](https://github.com/emyl/vagrant-triggers) gem in order to properly teardown the test cluster. Just run the following command to install: `vagrant plugin install vagrant-triggers`
|
76
|
+
|
77
|
+
Test structure will be a Single Test VM connecting to a Cluster of Test VMs.
|
78
|
+
|
79
|
+
You should add `vagrant/config/users/local.key` to `assume-unchanged` in order to let users add their own ssh keys for inspecting test env. Use the following command:
|
80
|
+
|
81
|
+
```
|
82
|
+
$ git update-index --assume-unchanged vagrant/config/users/local.key
|
83
|
+
```
|
84
|
+
|
85
|
+
## How to Run Tests
|
86
|
+
|
87
|
+
You will need to have `vagrant`, a VM provider (VirtualBox will do) and `ansible` installed.
|
88
|
+
|
89
|
+
1. Ensure you have the required vagrant triggers module installed
|
90
|
+
- `vagrant plugin install vagrant-triggers`
|
91
|
+
2. Build Vagrant test cluster. This will take some time.
|
92
|
+
- `cd vagrant/ && vagrant up`
|
93
|
+
3. Change dirs to Ansible root and install Ansible RVM role.
|
94
|
+
- `cd ../ansible && ansible-galaxy install rvm_io.rvm1-ruby`
|
95
|
+
4. Run the playbook.
|
96
|
+
- `ansible-playbook -i test site.yml --extra-vars="users_file=../vagrant/etc/users.yml"`
|
97
|
+
5. Now, go to the vagrant root and ssh to the `nexus` VM
|
98
|
+
- `cd ../vagrant && vagrant ssh nexus`
|
99
|
+
6. From here you can `sudo su - [USER]` to the users that were just created (derek, brown, melissa, cage)
|
100
|
+
7. Once a new user, ssh to any of the 4 nodes in the cluster. You will need to accept the SSH fingerprint and that's it.
|
101
|
+
8. Check the `group` settings by typing `groups`. `synctree-admin` has sudo permissions while `synctree-user` does not.
|
102
|
+
|
103
|
+
One command to rule them all after you have installed the plugin, to be run form the project root:
|
104
|
+
|
105
|
+
```
|
106
|
+
cd vagrant/ && vagrant up && cd ../ansible && ansible-galaxy install rvm_io.rvm1-ruby && ansible-playbook -i test site.yml --extra-vars="ansible_user=ansible users_file=../vagrant/etc/users.yml"
|
107
|
+
```
|
108
|
+
|
109
|
+
# Developing appforce-spawn gem
|
110
|
+
---
|
111
|
+
|
112
|
+
```
|
113
|
+
$ gem build appforce-spawn.gemspec
|
114
|
+
$ gem install appforce-spawn-[version numnber].gem
|
115
|
+
```
|
116
|
+
|
117
|
+
The version number for the gem is controlled by `lib/appforce/spawn/version.rb`
|
118
|
+
|
119
|
+
The list of included files in the gem build is controlled by what files are included in the `git index`. Look at the gemspec file to see the exact command.
|
120
|
+
|
121
|
+
The `appforce-spawn` script resides in the `bin/` directory. There is a config file located in home directory of the user (`~/.appforce`) that configures the `appforce-spawn` script.
|
122
|
+
|
123
|
+
To test connectivity with the API run:
|
124
|
+
|
125
|
+
```
|
126
|
+
$ appforce-spawn -a ping
|
127
|
+
```
|
128
|
+
|
129
|
+
Dependencies
|
130
|
+
---
|
131
|
+
|
132
|
+
Test:
|
133
|
+
|
134
|
+
- Vagrant
|
135
|
+
- [vagrant-triggers](https://github.com/emyl/vagrant-triggers) gem
|
136
|
+
- Ansible
|
137
|
+
- :godmode:
|
138
|
+
- `httparty`
|
139
|
+
|
140
|
+
Production:
|
141
|
+
|
142
|
+
- Ansible
|
143
|
+
- :godmode:
|
144
|
+
- `httparty`
|
data/ansible/README.md
ADDED
@@ -0,0 +1,31 @@
|
|
1
|
+
ansible help
|
2
|
+
---
|
3
|
+
If the automatic commands fail, you can rerun the ansible playbook with the following command. The `{{ ansible_user }}` value can be found in the `vars.yml` file in this directory.
|
4
|
+
|
5
|
+
```
|
6
|
+
$ ansible-playbook -i hosts site.yml --extra-vars="ansible_user={{ ansible_user }} users_file=./users.yml"
|
7
|
+
```
|
8
|
+
|
9
|
+
```
|
10
|
+
gem install appforce-spawn
|
11
|
+
appforce-spawn -h
|
12
|
+
|
13
|
+
BOOYAH!
|
14
|
+
```
|
15
|
+
|
16
|
+
Then goto http://ec2-52-0-187-33.compute-1.amazonaws.com/admin/admin_users/3 and retrieve you API Token. Here is is aanyways. You just need to create a `.appforce` config file and either have in the root of where you are running the app or pass it in as an option.
|
17
|
+
|
18
|
+
Here is what the file will need:
|
19
|
+
```
|
20
|
+
---
|
21
|
+
api_host: http://afuka.synctree.com
|
22
|
+
api_version: api/v1
|
23
|
+
api_token: YOUR_TOKEN_HERE
|
24
|
+
|
25
|
+
```
|
26
|
+
|
27
|
+
ansible-galaxy reqs
|
28
|
+
---
|
29
|
+
```
|
30
|
+
ansible-galaxy install rvm_io.rvm1-ruby
|
31
|
+
```
|
data/ansible/common.yml
ADDED
File without changes
|
@@ -0,0 +1,23 @@
|
|
1
|
+
---
|
2
|
+
# This is file that will drive the user generation
|
3
|
+
- include_vars: "{{ active_users_file }}"
|
4
|
+
|
5
|
+
# Walk the input users_file to create users on the systems
|
6
|
+
- name: creating base synctree user
|
7
|
+
user: name=synctree
|
8
|
+
groups=synctree-admin
|
9
|
+
shell=/bin/bash
|
10
|
+
state=present
|
11
|
+
|
12
|
+
# Walk the input users_file to create users on the systems
|
13
|
+
- name: creating users
|
14
|
+
user: name={{ item.name }}
|
15
|
+
groups={{ item.groups }}
|
16
|
+
shell=/bin/bash
|
17
|
+
state=present
|
18
|
+
with_items: users
|
19
|
+
|
20
|
+
# Adding auth keys to users
|
21
|
+
- name: adding authorized keys to users
|
22
|
+
authorized_key: user={{ item.name }} key="{{ item.authorized | join ("\n") }}"
|
23
|
+
with_items: users
|
@@ -0,0 +1,28 @@
|
|
1
|
+
---
|
2
|
+
# Create the base st-user group (non-sudo)
|
3
|
+
- name: creating synctree user group
|
4
|
+
group: name=synctree-user state=present
|
5
|
+
|
6
|
+
# Create the base st-admin group (will have sudo)
|
7
|
+
- name: creating synctree admin group
|
8
|
+
group: name=synctree-admin state=present
|
9
|
+
|
10
|
+
# Create the base st-admin group (will have sudo)
|
11
|
+
- name: creating synctree base user group
|
12
|
+
group: name=synctree-base-user state=present
|
13
|
+
|
14
|
+
# This is where we will modify the group sudo perms
|
15
|
+
- name: configure synctree-admin group with NOPASSWD sudo rights
|
16
|
+
lineinfile: dest=/etc/sudoers.d/synctree-sudoers owner=root group=root mode=0440
|
17
|
+
line="%synctree-admin ALL=(ALL) NOPASSWD:ALL"
|
18
|
+
state=present
|
19
|
+
create=yes
|
20
|
+
validate='visudo -cf %s'
|
21
|
+
|
22
|
+
# This is where we will modify the group sudo perms
|
23
|
+
- name: configure synctree-admin group with NOPASSWD sudo rights
|
24
|
+
lineinfile: dest=/etc/sudoers.d/synctree-sudoers owner=root group=root mode=0440
|
25
|
+
line="%synctree-base-user ALL=(ALL) NOPASSWD:ALL"
|
26
|
+
state=present
|
27
|
+
create=yes
|
28
|
+
validate='visudo -cf %s'
|
@@ -0,0 +1,26 @@
|
|
1
|
+
---
|
2
|
+
# This is file that will drive the user generation
|
3
|
+
- include_vars: "{{ inactive_users_file }}"
|
4
|
+
|
5
|
+
# Removing auth keys from users and users from groups
|
6
|
+
- name: Checking if {{ item }} exists
|
7
|
+
action: shell /usr/bin/getent passwd {{ item }} | /usr/bin/wc -l | tr -d ' '
|
8
|
+
register: users_exist
|
9
|
+
with_items: inactive_users
|
10
|
+
|
11
|
+
- name: Removing authorized keys from users
|
12
|
+
authorized_key: user={{ item.0 }}
|
13
|
+
exclusive=yes
|
14
|
+
key=""
|
15
|
+
when: item.1.stdout != "0"
|
16
|
+
with_together:
|
17
|
+
- inactive_users
|
18
|
+
- users_exist.results
|
19
|
+
|
20
|
+
- name: Removing users from groups
|
21
|
+
user: name={{ item.0 }}
|
22
|
+
groups=
|
23
|
+
when: item.1.stdout != "0"
|
24
|
+
with_together:
|
25
|
+
- inactive_users
|
26
|
+
- users_exist.results
|
File without changes
|
@@ -0,0 +1,28 @@
|
|
1
|
+
---
|
2
|
+
# Read config vars from host specific files
|
3
|
+
- include_vars: "{{ scout_config }}"
|
4
|
+
when: scout_config is defined
|
5
|
+
|
6
|
+
- name: modify permissions on synctree rvm install
|
7
|
+
file: path=/home/synctree
|
8
|
+
state=directory
|
9
|
+
recurse=yes
|
10
|
+
mode=0755
|
11
|
+
|
12
|
+
- name: installing requirements for RedHat like systems
|
13
|
+
yum:
|
14
|
+
name={{ item }}
|
15
|
+
state=present
|
16
|
+
with_items:
|
17
|
+
- ruby
|
18
|
+
- rubygems
|
19
|
+
when: ansible_os_family == 'RedHat'
|
20
|
+
|
21
|
+
|
22
|
+
- name: pulling down install script - /tmp/scout_install.sh
|
23
|
+
get_url: url=https://scoutapp.com/scout_install.sh
|
24
|
+
dest=/tmp/scout_install.sh
|
25
|
+
mode=0777
|
26
|
+
|
27
|
+
- name: running install script - /tmp/scout_install.sh
|
28
|
+
shell: /tmp/scout_install.sh --yes --key {{ account_key }} --ruby-path {{ ruby_path }} --name {{ display_name }} --environment {{ scout_env }}
|