lockpick 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,18 @@
1
+ *.gem
2
+ *.rbc
3
+ .bundle
4
+ .config
5
+ .yardoc
6
+ Gemfile.lock
7
+ InstalledFiles
8
+ _yardoc
9
+ coverage
10
+ doc/
11
+ lib/bundler/man
12
+ pkg
13
+ rdoc
14
+ spec/reports
15
+ test/tmp
16
+ test/version_tmp
17
+ tmp
18
+ cookbooks
data/Cheffile ADDED
@@ -0,0 +1,7 @@
1
+ site 'http://community.opscode.com/api/v1'
2
+
3
+ cookbook 'apt'
4
+ cookbook 'rbenv', :git => 'git://github.com/fnichol/chef-rbenv.git'
5
+ cookbook 'ruby_build'
6
+ cookbook 'vim'
7
+ cookbook 'build-essential'
data/Cheffile.lock ADDED
@@ -0,0 +1,20 @@
1
+ SITE
2
+ remote: http://community.opscode.com/api/v1
3
+ specs:
4
+ apt (2.0.0)
5
+ build-essential (1.4.0)
6
+ ruby_build (0.8.0)
7
+
8
+ GIT
9
+ remote: git://github.com/fnichol/chef-rbenv.git
10
+ ref: master
11
+ sha: 9afb4e5da2e6212504a12de3bbbd410cd96100f6
12
+ specs:
13
+ rbenv (0.7.3)
14
+
15
+ DEPENDENCIES
16
+ apt (>= 0)
17
+ build-essential (>= 0)
18
+ rbenv (>= 0)
19
+ ruby_build (>= 0)
20
+
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in lockpick.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Frederic Jean
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,29 @@
1
+ # Lockpick
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ gem 'lockpick'
10
+
11
+ And then execute:
12
+
13
+ $ bundle
14
+
15
+ Or install it yourself as:
16
+
17
+ $ gem install lockpick
18
+
19
+ ## Usage
20
+
21
+ TODO: Write usage instructions here
22
+
23
+ ## Contributing
24
+
25
+ 1. Fork it
26
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
27
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
28
+ 4. Push to the branch (`git push origin my-new-feature`)
29
+ 5. Create new Pull Request
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
data/Vagrantfile ADDED
@@ -0,0 +1,126 @@
1
+ # -*- mode: ruby -*-
2
+ # vi: set ft=ruby :
3
+
4
+ Vagrant.configure("2") do |config|
5
+ # All Vagrant configuration is done here. The most common configuration
6
+ # options are documented and commented below. For a complete reference,
7
+ # please see the online documentation at vagrantup.com.
8
+
9
+ # Every Vagrant virtual environment requires a box to build off of.
10
+ config.vm.box = "ubuntu-precise-64"
11
+
12
+ # The url from where the 'config.vm.box' box will be fetched if it
13
+ # doesn't already exist on the user's system.
14
+ config.vm.box_url = "http://files.vagrantup.com/precise64.box"
15
+
16
+ # Create a forwarded port mapping which allows access to a specific port
17
+ # within the machine from a port on the host machine. In the example below,
18
+ # accessing "localhost:8080" will access port 80 on the guest machine.
19
+ # config.vm.network :forwarded_port, guest: 80, host: 8080
20
+
21
+ # Create a private network, which allows host-only access to the machine
22
+ # using a specific IP.
23
+ # config.vm.network :private_network, ip: "192.168.33.10"
24
+
25
+ # Create a public network, which generally matched to bridged network.
26
+ # Bridged networks make the machine appear as another physical device on
27
+ # your network.
28
+ # config.vm.network :public_network
29
+
30
+ # Share an additional folder to the guest VM. The first argument is
31
+ # the path on the host to the actual folder. The second argument is
32
+ # the path on the guest to mount the folder. And the optional third
33
+ # argument is a set of non-required options.
34
+ # config.vm.synced_folder "../data", "/vagrant_data"
35
+
36
+ # Provider-specific configuration so you can fine-tune various
37
+ # backing providers for Vagrant. These expose provider-specific options.
38
+ # Example for VirtualBox:
39
+ #
40
+ # config.vm.provider :virtualbox do |vb|
41
+ # # Don't boot with headless mode
42
+ # vb.gui = true
43
+ #
44
+ # # Use VBoxManage to customize the VM. For example to change memory:
45
+ # vb.customize ["modifyvm", :id, "--memory", "1024"]
46
+ # end
47
+ #
48
+ # View the documentation for the provider you're using for more
49
+ # information on available options.
50
+
51
+ # Enable provisioning with Puppet stand alone. Puppet manifests
52
+ # are contained in a directory path relative to this Vagrantfile.
53
+ # You will need to create the manifests directory and a manifest in
54
+ # the file base.pp in the manifests_path directory.
55
+ #
56
+ # An example Puppet manifest to provision the message of the day:
57
+ #
58
+ # # group { "puppet":
59
+ # # ensure => "present",
60
+ # # }
61
+ # #
62
+ # # File { owner => 0, group => 0, mode => 0644 }
63
+ # #
64
+ # # file { '/etc/motd':
65
+ # # content => "Welcome to your Vagrant-built virtual machine!
66
+ # # Managed by Puppet.\n"
67
+ # # }
68
+ #
69
+ # config.vm.provision :puppet do |puppet|
70
+ # puppet.manifests_path = "manifests"
71
+ # puppet.manifest_file = "init.pp"
72
+ # end
73
+
74
+ # Enable provisioning with chef solo, specifying a cookbooks path, roles
75
+ # path, and data_bags path (all relative to this Vagrantfile), and adding
76
+ # some recipes and/or roles.
77
+ #
78
+
79
+ config.vm.provision :shell, path: 'upgrade-chef.sh'
80
+ config.vm.provision :chef_solo do |chef|
81
+ chef.cookbooks_path = "cookbooks"
82
+ chef.add_recipe('apt')
83
+ chef.add_recipe('build-essential')
84
+ chef.add_recipe('ruby_build')
85
+ chef.add_recipe('rbenv::system')
86
+ chef.add_recipe('vim')
87
+ chef.add_recipe('rbenv::vagrant')
88
+
89
+ # You may also specify custom JSON attributes:
90
+ chef.json = {
91
+ rbenv: {
92
+ rubies: [ "1.9.3-p385" ],
93
+ upgrade: 'sync',
94
+ global: '1.9.3-p385',
95
+ gems: {
96
+ '1.9.3-p385' => [
97
+ { name: 'bundler' }
98
+ ]
99
+ }
100
+ }
101
+ }
102
+ end
103
+
104
+ # Enable provisioning with chef server, specifying the chef server URL,
105
+ # and the path to the validation key (relative to this Vagrantfile).
106
+ #
107
+ # The Opscode Platform uses HTTPS. Substitute your organization for
108
+ # ORGNAME in the URL and validation key.
109
+ #
110
+ # If you have your own Chef Server, use the appropriate URL, which may be
111
+ # HTTP instead of HTTPS depending on your configuration. Also change the
112
+ # validation key to validation.pem.
113
+ #
114
+ # config.vm.provision :chef_client do |chef|
115
+ # chef.chef_server_url = "https://api.opscode.com/organizations/ORGNAME"
116
+ # chef.validation_key_path = "ORGNAME-validator.pem"
117
+ # end
118
+ #
119
+ # If you're using the Opscode platform, your validator client is
120
+ # ORGNAME-validator, replacing ORGNAME with your organization name.
121
+ #
122
+ # If you have your own Chef Server, the default validation client name is
123
+ # chef-validator, unless you changed the configuration.
124
+ #
125
+ # chef.validation_client_name = "ORGNAME-validator"
126
+ end
data/bin/lockpick ADDED
@@ -0,0 +1,157 @@
1
+ #! /usr/bin/env ruby
2
+ #
3
+ # Pulls the public keys from the members of one or more team on GitHub and
4
+ # populates the ~/.ssh/authorized_keys for the user running the script.
5
+ #
6
+ # Motivation
7
+ # ----------
8
+ #
9
+ # We sometimes get new people at the dojo. We sometimes lose people at the dojo.
10
+ # The goal of this gem is to make it easy to grant and remove access to and from
11
+ # our servers...
12
+
13
+ require 'main'
14
+ require 'yaml'
15
+ require 'digest'
16
+ require 'map'
17
+
18
+ Main {
19
+ config({
20
+ 'github' => {
21
+ 'token' => ENV['GITHUB_TOKEN'],
22
+ 'org' => ENV['GITHUB_TEAM'],
23
+ 'team_ids' => %w( )
24
+ },
25
+ 'default_keys' => %w( )
26
+ })
27
+
28
+ def run
29
+ pull_ssh_keys!
30
+ end
31
+
32
+ def pull_ssh_keys!
33
+ ssh_keys = config.github.team_ids.map do |team_id|
34
+ team_members(team_id).map do |member|
35
+ { member.login => keys_for_member(member.login) }
36
+ end
37
+ end.flatten
38
+
39
+ FileUtils.mkdir_p(File.join(ENV['HOME'], '.ssh'))
40
+
41
+ File.atomic_write(File.join(ENV['HOME'], '.ssh', 'authorized_keys')) do |f|
42
+
43
+ f.puts("# Default Keys -----------------------")
44
+ config.default_keys.each do |key|
45
+ f.puts(key)
46
+ end
47
+ f.puts("# End Default Keys -------------------")
48
+ ssh_keys.each do |user_keys|
49
+ user_keys.each do |login, keys|
50
+ f.puts("# Start Public Key for #{login} ---------------- ")
51
+ keys.each do |key|
52
+ f.puts("#{key['key']} #{key.title}")
53
+ end
54
+ f.puts("# End Public Key for #{login} ----------------- ")
55
+ end
56
+ end
57
+ end
58
+ end
59
+
60
+ def team_members(team_id)
61
+ github.orgs.with(org_name: config.github.org).teams.list_members(team_id: team_id).response.body
62
+ end
63
+
64
+ def keys_for_member(login)
65
+ github.users.keys.list(user: login).response.body
66
+ end
67
+
68
+ mode(:shell) {
69
+ def run
70
+ require 'pry'
71
+ Pry.hooks[:before_session] = proc{}
72
+ prompt = "lockpick >> "
73
+ Pry.config.prompt = proc{ |*a| prompt }
74
+ binding.pry
75
+ end
76
+ }
77
+ }
78
+
79
+
80
+ BEGIN {
81
+ status = DATA.flock(File::LOCK_EX|File::LOCK_NB)
82
+ exit(42) unless status == 0
83
+
84
+ require 'rubygems'
85
+ require 'github_api'
86
+ require 'map'
87
+ require 'tempfile'
88
+
89
+ def github
90
+ @github ||= Github.new oauth_token: config.github.token
91
+ end
92
+
93
+ class File
94
+ # Write to a file atomically. Useful for situations where you don't
95
+ # want other processes or threads to see half-written files.
96
+ #
97
+ # File.atomic_write('important.file') do |file|
98
+ # file.write('hello')
99
+ # end
100
+ #
101
+ # If your temp directory is not on the same filesystem as the file you're
102
+ # trying to write, you can provide a different temporary directory.
103
+ #
104
+ # File.atomic_write('/data/something.important', '/data/tmp') do |file|
105
+ # file.write('hello')
106
+ # end
107
+ def self.atomic_write(file_name, temp_dir = Dir.tmpdir)
108
+ require 'tempfile' unless defined?(Tempfile)
109
+ require 'fileutils' unless defined?(FileUtils)
110
+
111
+ temp_file = Tempfile.new(basename(file_name), temp_dir)
112
+ temp_file.binmode
113
+ yield temp_file
114
+ temp_file.close
115
+
116
+ if File.exists?(file_name)
117
+ # Get original file permissions
118
+ old_stat = stat(file_name)
119
+ else
120
+ # If not possible, probe which are the default permissions in the
121
+ # destination directory.
122
+ old_stat = probe_stat_in(dirname(file_name))
123
+ end
124
+
125
+ # Overwrite original file with temp file
126
+ FileUtils.mv(temp_file.path, file_name)
127
+
128
+ # Set correct permissions on new file
129
+ begin
130
+ chown(old_stat.uid, old_stat.gid, file_name)
131
+ # This operation will affect filesystem ACL's
132
+ chmod(old_stat.mode, file_name)
133
+ rescue Errno::EPERM
134
+ # Changing file ownership failed, moving on.
135
+ end
136
+ end
137
+
138
+ # Private utility method.
139
+ def self.probe_stat_in(dir) #:nodoc:
140
+ basename = [
141
+ '.permissions_check',
142
+ Thread.current.object_id,
143
+ Process.pid,
144
+ rand(1000000)
145
+ ].join('.')
146
+
147
+ file_name = join(dir, basename)
148
+ FileUtils.touch(file_name)
149
+ stat(file_name)
150
+ ensure
151
+ FileUtils.rm_f(file_name) if file_name
152
+ end
153
+ end
154
+ }
155
+
156
+ __END__
157
+ ### We need something to lock on...
@@ -0,0 +1,3 @@
1
+ module Lockpick
2
+ VERSION = "1.0.0"
3
+ end
data/lib/lockpick.rb ADDED
@@ -0,0 +1,5 @@
1
+ require "lockpick/version"
2
+
3
+ module Lockpick
4
+ # Your code goes here...
5
+ end
data/lockpick.gemspec ADDED
@@ -0,0 +1,30 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'lockpick/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "lockpick"
8
+ spec.version = Lockpick::VERSION
9
+ spec.authors = ["Frederic Jean"]
10
+ spec.email = ["fred@fredjean.net"]
11
+ spec.description = %q{pulls ssh public keys from GitHub and populates authorized_keys}
12
+ spec.summary = %q{pulls ssh public keys from GitHub and populates authorized_keys}
13
+ spec.homepage = "https://github.com/fredjean/lockpick"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files`.split($/)
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_dependency "main"
22
+ spec.add_dependency "map"
23
+ spec.add_dependency "pry"
24
+ spec.add_dependency "github_api"
25
+ spec.add_dependency "arrayfields", '~> 4.7.4'
26
+
27
+ spec.add_development_dependency "bundler", "~> 1.3"
28
+ spec.add_development_dependency "librarian-chef"
29
+ spec.add_development_dependency "rake"
30
+ end
data/upgrade-chef.sh ADDED
@@ -0,0 +1,6 @@
1
+ #!/usr/bin/env bash
2
+
3
+ sudo apt-get update
4
+ sudo apt-get -y install curl
5
+
6
+ sudo true && curl -L https://www.opscode.com/chef/install.sh | sudo bash
metadata ADDED
@@ -0,0 +1,194 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: lockpick
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Frederic Jean
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-06-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: main
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ! '>='
20
+ - !ruby/object:Gem::Version
21
+ version: '0'
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ! '>='
28
+ - !ruby/object:Gem::Version
29
+ version: '0'
30
+ - !ruby/object:Gem::Dependency
31
+ name: map
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ! '>='
36
+ - !ruby/object:Gem::Version
37
+ version: '0'
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ! '>='
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ - !ruby/object:Gem::Dependency
47
+ name: pry
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ! '>='
52
+ - !ruby/object:Gem::Version
53
+ version: '0'
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ! '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ - !ruby/object:Gem::Dependency
63
+ name: github_api
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ! '>='
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ! '>='
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ - !ruby/object:Gem::Dependency
79
+ name: arrayfields
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 4.7.4
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 4.7.4
94
+ - !ruby/object:Gem::Dependency
95
+ name: bundler
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: '1.3'
102
+ type: :development
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: '1.3'
110
+ - !ruby/object:Gem::Dependency
111
+ name: librarian-chef
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: rake
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ! '>='
132
+ - !ruby/object:Gem::Version
133
+ version: '0'
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ! '>='
140
+ - !ruby/object:Gem::Version
141
+ version: '0'
142
+ description: pulls ssh public keys from GitHub and populates authorized_keys
143
+ email:
144
+ - fred@fredjean.net
145
+ executables:
146
+ - lockpick
147
+ extensions: []
148
+ extra_rdoc_files: []
149
+ files:
150
+ - .gitignore
151
+ - Cheffile
152
+ - Cheffile.lock
153
+ - Gemfile
154
+ - LICENSE.txt
155
+ - README.md
156
+ - Rakefile
157
+ - Vagrantfile
158
+ - bin/lockpick
159
+ - lib/lockpick.rb
160
+ - lib/lockpick/version.rb
161
+ - lockpick.gemspec
162
+ - upgrade-chef.sh
163
+ homepage: https://github.com/fredjean/lockpick
164
+ licenses:
165
+ - MIT
166
+ post_install_message:
167
+ rdoc_options: []
168
+ require_paths:
169
+ - lib
170
+ required_ruby_version: !ruby/object:Gem::Requirement
171
+ none: false
172
+ requirements:
173
+ - - ! '>='
174
+ - !ruby/object:Gem::Version
175
+ version: '0'
176
+ segments:
177
+ - 0
178
+ hash: 2488233785368816938
179
+ required_rubygems_version: !ruby/object:Gem::Requirement
180
+ none: false
181
+ requirements:
182
+ - - ! '>='
183
+ - !ruby/object:Gem::Version
184
+ version: '0'
185
+ segments:
186
+ - 0
187
+ hash: 2488233785368816938
188
+ requirements: []
189
+ rubyforge_project:
190
+ rubygems_version: 1.8.23
191
+ signing_key:
192
+ specification_version: 3
193
+ summary: pulls ssh public keys from GitHub and populates authorized_keys
194
+ test_files: []