knife-github 0.0.9 → 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- data/README.md +21 -7
- data/knife-github.gemspec +1 -0
- data/lib/chef/knife/github_baselist.rb +21 -21
- data/lib/chef/knife/github_cleanup.rb +8 -13
- data/lib/chef/knife/github_clone.rb +4 -4
- data/lib/chef/knife/github_compare.rb +4 -5
- data/lib/chef/knife/github_deploy.rb +52 -54
- data/lib/chef/knife/github_diff.rb +2 -6
- data/lib/chef/knife/github_list.rb +2 -4
- data/lib/chef/knife/github_pin.rb +4 -5
- data/lib/chef/knife/{github_create.rb → github_repo_create.rb} +92 -34
- data/lib/chef/knife/github_repo_destroy.rb +273 -0
- data/lib/chef/knife/github_search.rb +1 -4
- data/lib/chef/knife/github_token_create.rb +239 -0
- data/lib/knife-github/config.rb +3 -0
- data/lib/knife-github/password.rb +85 -0
- data/lib/knife-github/version.rb +1 -1
- metadata +22 -3
data/README.md
CHANGED
@@ -3,21 +3,35 @@ knife-github
|
|
3
3
|
|
4
4
|
Chef knife plugin to interact with the github enterprise appliance.
|
5
5
|
|
6
|
-
|
6
|
+
Configurations
|
7
7
|
==========
|
8
8
|
|
9
|
-
|
9
|
+
### Central Configuration.
|
10
|
+
When working on customer admin machines, it's recommended to used an central configuration file.
|
11
|
+
This file should be created in: /etc/githubrc.rb and can contain any attribute in the following structure:
|
12
|
+
|
13
|
+
github_url "https://github.schubergphilis.com"
|
14
|
+
github_link "ssh"
|
15
|
+
github_organizations [ "TLA-Cookbooks", "SBP-Cookbooks" ]
|
16
|
+
|
17
|
+
Please note: these options are recommended for the central config file:
|
18
|
+
|
19
|
+
### Personal Configuration.
|
20
|
+
You can also configure attributes within your ~/.chef/knife.rb in the following structure:
|
10
21
|
|
11
|
-
knife[:
|
12
|
-
knife[:github_organizations] = [ 'customer-cookbooks', 'central-cookbooks' ]
|
13
|
-
knife[:github_link] = 'ssh'
|
22
|
+
knife[:github_token] = '28374928374928374923874923842'
|
14
23
|
knife[:github_api_version] = 'v3'
|
15
24
|
knife[:github_ssl_verify_mode] = 'verify_none'
|
16
25
|
|
26
|
+
Please note: these settings will overwrite the central settings.
|
27
|
+
In a perfect world, your personal configuration file only contains your token information.
|
28
|
+
|
17
29
|
###### github_url
|
18
|
-
This will be the URL to your
|
30
|
+
This will be the URL to your (personal) github enterprise appliance.
|
19
31
|
Here you can also use the github.com address if you don't have an internal appliance.
|
20
32
|
|
33
|
+
Attributes
|
34
|
+
==========
|
21
35
|
###### github_organizations
|
22
36
|
Here you specify the organizations that you want to taget when searching for cookbooks.
|
23
37
|
The first entry will have priority over the other entries.
|
@@ -37,7 +51,7 @@ Other
|
|
37
51
|
=====
|
38
52
|
|
39
53
|
Cache files will be created into the: ~/.chef directory.
|
40
|
-
We use cache files to offload the api calls and increase the performance for
|
54
|
+
We use cache files to offload the api calls and increase the performance for repetitive executions
|
41
55
|
Updated to any repo inside the organization will cause the cache files to update.
|
42
56
|
But in case of any problems, the cache files can be safely deleted.
|
43
57
|
|
data/knife-github.gemspec
CHANGED
@@ -22,36 +22,36 @@ class Chef
|
|
22
22
|
|
23
23
|
def self.included(includer)
|
24
24
|
includer.class_eval do
|
25
|
-
|
25
|
+
|
26
26
|
option :fields,
|
27
|
-
|
28
|
-
|
29
|
-
|
27
|
+
:long => "--fields 'NAME, NAME'",
|
28
|
+
:description => "The fields to output, comma-separated"
|
29
|
+
|
30
30
|
option :fieldlist,
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
31
|
+
:long => "--fieldlist",
|
32
|
+
:description => "The available fields to output/filter",
|
33
|
+
:boolean => true
|
34
|
+
|
35
35
|
option :noheader,
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
36
|
+
:long => "--noheader",
|
37
|
+
:description => "Removes header from output",
|
38
|
+
:boolean => true
|
39
|
+
|
40
40
|
def display_info(data, columns, match = [])
|
41
41
|
object_list = []
|
42
|
-
|
42
|
+
|
43
43
|
if config[:fields]
|
44
44
|
config[:fields].split(',').each { |n| object_list << ui.color(("#{n}").capitalize.strip, :bold) }
|
45
45
|
else
|
46
46
|
columns.each { |c| r = c.split(","); object_list << ui.color(("#{r.last}").strip, :bold) }
|
47
47
|
end
|
48
|
-
|
48
|
+
|
49
49
|
col = object_list.count
|
50
50
|
object_list = [] if config[:noheader]
|
51
|
-
|
51
|
+
|
52
52
|
data.each do |k,v|
|
53
53
|
if config[:fields]
|
54
|
-
|
54
|
+
config[:fields].downcase.split(',').each { |n| object_list << ((v["#{n}".strip]).to_s || 'n/a') }
|
55
55
|
else
|
56
56
|
color = :white
|
57
57
|
if !match.empty? && !config[:all]
|
@@ -59,25 +59,25 @@ class Chef
|
|
59
59
|
if matches.uniq.count == 1
|
60
60
|
next if config[:mismatch]
|
61
61
|
else
|
62
|
-
color = :yellow
|
62
|
+
color = :yellow
|
63
63
|
end
|
64
64
|
end
|
65
65
|
columns.each { |c| r = c.split(","); object_list << ui.color((v["#{r.first}"]).to_s, color) || 'n/a' }
|
66
66
|
end
|
67
67
|
end
|
68
|
-
|
68
|
+
|
69
69
|
puts ui.list(object_list, :uneven_columns_across, col)
|
70
70
|
display_object_fields(data) if locate_config_value(:fieldlist)
|
71
71
|
end
|
72
|
-
|
72
|
+
|
73
73
|
def display_object_fields(object)
|
74
74
|
exit 1 if object.nil? || object.empty?
|
75
75
|
object_fields = [
|
76
76
|
ui.color('Key', :bold),
|
77
77
|
ui.color('Type', :bold),
|
78
78
|
ui.color('Value', :bold)
|
79
|
-
|
80
|
-
|
79
|
+
]
|
80
|
+
object.first.each do |n|
|
81
81
|
if n.class == Hash
|
82
82
|
n.keys.each do |k,v|
|
83
83
|
object_fields << ui.color(k, :yellow, :bold)
|
@@ -15,22 +15,17 @@
|
|
15
15
|
# See the License for the specific language governing permissions and
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
|
-
# ---------------------------------------------------------------------------- #
|
19
|
-
# Abstract
|
20
|
-
# ---------------------------------------------------------------------------- #
|
21
|
-
# This code is intended to help you cleaning up your locate repo's.
|
22
|
-
# It will check if your repo if insync with the github and will not touch if
|
23
|
-
# this is not the case. Then it will check if you have any branches local
|
24
|
-
# and not on the github.
|
25
|
-
#
|
26
|
-
# If it cannot find any uncommitted changes, it will safely remove your repo.
|
27
|
-
# It's good practice to cleanup and re-download repos because this way they
|
28
|
-
# can move from organization to organization.
|
29
|
-
# ---------------------------------------------------------------------------- #
|
30
|
-
#
|
31
18
|
require 'chef/knife'
|
32
19
|
|
33
20
|
module KnifeGithubCleanup
|
21
|
+
# This module is intended to help you cleaning up your locate repo's.
|
22
|
+
# It will check if your repo if insync with the github and will not touch if
|
23
|
+
# this is not the case. Then it will check if you have any branches local
|
24
|
+
# and not on the github.
|
25
|
+
#
|
26
|
+
# If it cannot find any uncommitted changes, it will safely remove your repo.
|
27
|
+
# It's good practice to cleanup and re-download repos because this way they
|
28
|
+
# can move from organization to organization.
|
34
29
|
class GithubCleanup < Chef::Knife
|
35
30
|
|
36
31
|
deps do
|
@@ -18,10 +18,11 @@
|
|
18
18
|
|
19
19
|
require 'chef/knife'
|
20
20
|
|
21
|
-
|
22
|
-
class Knife
|
21
|
+
module KnifeGitHubClone
|
23
22
|
|
24
|
-
|
23
|
+
# Clones a cookbook version to your local cookbooks directory
|
24
|
+
#
|
25
|
+
class GithubClone < Chef::Knife
|
25
26
|
|
26
27
|
deps do
|
27
28
|
require 'chef/knife/github_base'
|
@@ -101,6 +102,5 @@ class Chef
|
|
101
102
|
end
|
102
103
|
end
|
103
104
|
|
104
|
-
end
|
105
105
|
end
|
106
106
|
end
|
@@ -18,9 +18,9 @@
|
|
18
18
|
|
19
19
|
require 'chef/knife'
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
module KnifeGithubCompare
|
22
|
+
# Compare cookbooks in chef with those in the repository
|
23
|
+
class GithubCompare < Chef::Knife
|
24
24
|
|
25
25
|
deps do
|
26
26
|
require 'chef/knife/github_base'
|
@@ -92,6 +92,5 @@ class Chef
|
|
92
92
|
end
|
93
93
|
|
94
94
|
end
|
95
|
-
|
96
|
-
end
|
95
|
+
end
|
97
96
|
end
|
@@ -1,58 +1,57 @@
|
|
1
1
|
require 'chef/knife'
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
class GithubDeploy < Knife
|
3
|
+
module KnifeGithubDeploy
|
4
|
+
# Implements the knife github deploy function
|
5
|
+
# @author:: Ian Southam (<isoutham@schubergphilis.com>)
|
6
|
+
# Copyright:: Copyright (c) 2013 Ian Southam.
|
7
|
+
# This code is specific to our company workflow
|
8
|
+
#
|
9
|
+
# == Overview
|
10
|
+
# All modes presume you have used github download to download a cookbook or
|
11
|
+
# are creating a new cookbook
|
12
|
+
#
|
13
|
+
# === Examples
|
14
|
+
# Deploy a development version of cookbook to your chef server
|
15
|
+
# knife github deploy cookbook_name
|
16
|
+
#
|
17
|
+
# Deploy a release version of cookbook to your chef server
|
18
|
+
# knife github deploy cookbook_name -f
|
19
|
+
#
|
20
|
+
# === Options
|
21
|
+
# -f Operate in final release mode
|
22
|
+
# -p Update the patch component of the version
|
23
|
+
# -m Update the minor component of the version
|
24
|
+
# -M Update the major component of the version
|
25
|
+
#
|
26
|
+
# == Operation Modes
|
27
|
+
# Development (default)
|
28
|
+
#
|
29
|
+
# This will take a cookbook name
|
30
|
+
# Do some basic version checks (if the current cookbook is frozen) and
|
31
|
+
# upload it
|
32
|
+
#
|
33
|
+
# If the cookbook is frozen it will force you to choose a new version
|
34
|
+
# and update the metadata accordingly
|
35
|
+
#
|
36
|
+
# Release (-f)
|
37
|
+
#
|
38
|
+
# You will be forced to select a new version.
|
39
|
+
# You can choose via the options whether to increment the Major/minor or patch
|
40
|
+
# revision numbers
|
41
|
+
# The version will be tagged
|
42
|
+
# Uploaded to the Chef server and frozen
|
43
|
+
#
|
44
|
+
# == Version numbers
|
45
|
+
#
|
46
|
+
# You can choose a specific version number by specifying it on the command
|
47
|
+
# line.
|
48
|
+
#
|
49
|
+
# If you do not specify a version, the version will be the version in your
|
50
|
+
# cookbook's metadata
|
51
|
+
#
|
52
|
+
# A warning is issued if the version is lower than the version in github
|
53
|
+
#
|
54
|
+
class GithubDeploy < Chef::Knife
|
56
55
|
deps do
|
57
56
|
require 'chef/knife/github_base'
|
58
57
|
include Chef::Knife::GithubBase
|
@@ -333,6 +332,5 @@ class Chef
|
|
333
332
|
return true
|
334
333
|
end
|
335
334
|
|
336
|
-
end
|
337
335
|
end
|
338
336
|
end
|
@@ -18,10 +18,7 @@
|
|
18
18
|
|
19
19
|
require 'chef/knife'
|
20
20
|
|
21
|
-
|
22
|
-
class Knife
|
23
|
-
|
24
|
-
class GithubDiff < Knife
|
21
|
+
module GithubDiff
|
25
22
|
# Implements a diff function between your downloaded copy from git and what is in the Chef Server
|
26
23
|
#
|
27
24
|
# By default, it expects that you have already done knife github download COOKBOOK
|
@@ -31,6 +28,7 @@ class Chef
|
|
31
28
|
# You can also diff a cookbook against the github version bu using the -g option
|
32
29
|
#
|
33
30
|
# You can also optionally give a version on the command line
|
31
|
+
class GithubDiff < Chef::Knife
|
34
32
|
|
35
33
|
deps do
|
36
34
|
require 'chef/knife/github_base'
|
@@ -150,7 +148,5 @@ class Chef
|
|
150
148
|
end
|
151
149
|
return version
|
152
150
|
end
|
153
|
-
|
154
|
-
end
|
155
151
|
end
|
156
152
|
end
|
@@ -18,10 +18,9 @@
|
|
18
18
|
|
19
19
|
require 'chef/knife'
|
20
20
|
|
21
|
-
|
22
|
-
class Knife
|
21
|
+
module KnifeGithubList
|
23
22
|
|
24
|
-
|
23
|
+
class GithubList < Chef::Knife
|
25
24
|
|
26
25
|
deps do
|
27
26
|
require 'chef/knife/github_base'
|
@@ -94,6 +93,5 @@ class Chef
|
|
94
93
|
|
95
94
|
end
|
96
95
|
|
97
|
-
end
|
98
96
|
end
|
99
97
|
end
|
@@ -18,8 +18,7 @@
|
|
18
18
|
|
19
19
|
require 'chef/knife'
|
20
20
|
|
21
|
-
|
22
|
-
class Knife
|
21
|
+
module KnifeGithubPin
|
23
22
|
|
24
23
|
# Pin a specific cookbook version to an environment
|
25
24
|
#
|
@@ -28,7 +27,7 @@ class Chef
|
|
28
27
|
# In some respects does duplicate some functionality that can be found
|
29
28
|
# in spork but, I want a single set of tools that would help people
|
30
29
|
# to get quickly up to speed with using chef in an industrialised environment
|
31
|
-
class GithubPin < Knife
|
30
|
+
class GithubPin < Chef::Knife
|
32
31
|
deps do
|
33
32
|
require 'chef/knife/github_base'
|
34
33
|
require 'chef/knife/core/object_loader'
|
@@ -53,8 +52,9 @@ class Chef
|
|
53
52
|
@version = nil
|
54
53
|
@env = nil
|
55
54
|
|
56
|
-
if @cookbook_name.
|
55
|
+
if @cookbook_name.nil?
|
57
56
|
Chef::Log.error("You must specify a cookbook name to use this module")
|
57
|
+
exit 1;
|
58
58
|
end
|
59
59
|
|
60
60
|
# Parameter 2 can be a version or an environment (if version is not given) or nothing
|
@@ -133,6 +133,5 @@ class Chef
|
|
133
133
|
@env
|
134
134
|
end
|
135
135
|
|
136
|
-
end
|
137
136
|
end
|
138
137
|
end
|
@@ -16,24 +16,34 @@
|
|
16
16
|
# limitations under the License.
|
17
17
|
#
|
18
18
|
|
19
|
-
|
20
|
-
#
|
21
|
-
#
|
22
|
-
# BE AWARE THIS COMMAND IS STILL UNDER HEAVY DEVELOPMENT!
|
23
|
-
#
|
24
|
-
#
|
25
19
|
require 'chef/knife'
|
26
20
|
|
27
|
-
module
|
28
|
-
class
|
29
|
-
|
21
|
+
module KnifeGithubRepoCreate
|
22
|
+
class GithubRepoCreate < Chef::Knife
|
23
|
+
# Implements the knife github repo create function
|
24
|
+
#
|
25
|
+
# == Overview
|
26
|
+
# The command will create a empty cookbook structure and it will commit this one into the github.
|
27
|
+
#
|
28
|
+
# === Examples
|
29
|
+
# Create a new cookbook:
|
30
|
+
# knife github repo create <name> <here you give your cookbook description>
|
31
|
+
#
|
32
|
+
# # Deploy a release version of cookbook to your chef server
|
33
|
+
# # knife github deploy cookbook_name -f
|
34
|
+
#
|
35
|
+
# === Options
|
36
|
+
# -t --github_token Authentication token for the github.
|
37
|
+
# -U --github_user_repo Create the cookbook in the user environment.
|
38
|
+
#
|
39
|
+
|
30
40
|
deps do
|
31
41
|
require 'chef/knife/github_base'
|
32
42
|
include Chef::Knife::GithubBase
|
33
43
|
require 'chef/mixin/shell_out'
|
34
44
|
end
|
35
45
|
|
36
|
-
banner "knife github create
|
46
|
+
banner "knife github repo create <name> <description> (options)"
|
37
47
|
category "github"
|
38
48
|
|
39
49
|
option :github_token,
|
@@ -58,6 +68,8 @@ module KnifeGithubCreate
|
|
58
68
|
|
59
69
|
# Get the name_args from the command line
|
60
70
|
name = name_args.first
|
71
|
+
name_args.shift
|
72
|
+
desc = name_args.join(" ")
|
61
73
|
|
62
74
|
# Get the organization name from config
|
63
75
|
org = locate_config_value('github_organizations').first
|
@@ -66,7 +78,12 @@ module KnifeGithubCreate
|
|
66
78
|
Chef::Log.error("Please specify a repository name")
|
67
79
|
exit 1
|
68
80
|
end
|
69
|
-
|
81
|
+
|
82
|
+
if desc.nil? || desc.empty?
|
83
|
+
Chef::Log.error("Please specify a repository description")
|
84
|
+
exit 1
|
85
|
+
end
|
86
|
+
|
70
87
|
if config[:github_user_repo]
|
71
88
|
url = @github_url + "/api/" + @github_api_version + "/user/repos"
|
72
89
|
Chef::Log.debug("Creating repository in user environment")
|
@@ -75,34 +92,73 @@ module KnifeGithubCreate
|
|
75
92
|
Chef::Log.debug("Creating repository in organization: #{org}")
|
76
93
|
end
|
77
94
|
|
95
|
+
@github_tmp = locate_config_value("github_tmp") || '/var/tmp/gitcreate'
|
96
|
+
@github_tmp = "#{@github_tmp}#{Process.pid}"
|
97
|
+
|
78
98
|
# Get token information
|
79
99
|
token = get_github_token()
|
80
100
|
|
81
101
|
# Get body data for post
|
82
|
-
body = get_body_json(name)
|
102
|
+
body = get_body_json(name, desc)
|
83
103
|
|
84
|
-
# Creating the repository
|
85
|
-
|
86
|
-
|
104
|
+
# Creating the local repository or using existing one.
|
105
|
+
cookbook_dir = ""
|
106
|
+
cookbook_dir = get_cookbook_path(name)
|
87
107
|
|
88
|
-
|
89
|
-
|
108
|
+
if File.exists?(cookbook_dir)
|
109
|
+
Chef::Log.debug("Using local repository from #{cookbook_dir}")
|
90
110
|
|
91
|
-
|
111
|
+
# Creating the github repository
|
112
|
+
Chef::Log.debug("Creating the github repository")
|
113
|
+
repo = post_request(url, body, token)
|
114
|
+
github_ssh_url = repo['ssh_url']
|
115
|
+
|
116
|
+
Chef::Log.debug("Commit and push local repository")
|
117
|
+
# Initialize the local git repo
|
118
|
+
git_commit_and_push(cookbook_dir, github_ssh_url)
|
92
119
|
|
93
|
-
|
94
|
-
|
120
|
+
puts "Finished creating #{name} and uploading #{cookbook_dir}"
|
121
|
+
else
|
122
|
+
Chef::Log.debug("Creating the local repository based on template")
|
123
|
+
create_cookbook(name, @github_tmp)
|
124
|
+
|
125
|
+
cookbook_dir = File.join(@github_tmp, name)
|
126
|
+
|
127
|
+
# Updating README.md if needed.
|
128
|
+
update_readme(cookbook_dir)
|
129
|
+
|
130
|
+
# Updateing metadata.rb if needed.
|
131
|
+
update_metadata(cookbook_dir)
|
132
|
+
|
133
|
+
# Creating the github repository
|
134
|
+
Chef::Log.debug("Creating the github repository")
|
135
|
+
repo = post_request(url, body, token)
|
136
|
+
github_ssh_url = repo['ssh_url']
|
137
|
+
|
138
|
+
Chef::Log.debug("Commit and push local repository")
|
139
|
+
# Initialize the local git repo
|
140
|
+
git_commit_and_push(cookbook_dir, github_ssh_url)
|
141
|
+
|
142
|
+
Chef::Log.debug("Removing temp files")
|
143
|
+
FileUtils.remove_entry(@github_tmp)
|
144
|
+
puts "Finished creating and uploading #{name}"
|
145
|
+
end
|
146
|
+
end
|
95
147
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
shell_out!("
|
148
|
+
# Set the username in README.md
|
149
|
+
# @param cookbook_path [String] cookbook path
|
150
|
+
# github_ssh_url [String] github ssh url from repo
|
151
|
+
def git_commit_and_push(cookbook_path, github_ssh_url)
|
152
|
+
if File.exists?(File.join(cookbook_path, ".git"))
|
153
|
+
shell_out("git remote rm origin", :cwd => cookbook_path)
|
154
|
+
else
|
155
|
+
shell_out!("git init", :cwd => cookbook_path)
|
156
|
+
end
|
157
|
+
shell_out!("echo - $(date): Uploaded with knife github plugin. >> CHANGELOG.md ", :cwd => cookbook_path)
|
158
|
+
shell_out!("git add .", :cwd => cookbook_path)
|
159
|
+
shell_out!("git commit -m 'creating initial cookbook structure from the knife-github plugin' ", :cwd => cookbook_path)
|
160
|
+
shell_out!("git remote add origin #{github_ssh_url} ", :cwd => cookbook_path)
|
161
|
+
shell_out!("git push -u origin master", :cwd => cookbook_path)
|
106
162
|
end
|
107
163
|
|
108
164
|
# Set the username in README.md
|
@@ -157,18 +213,20 @@ module KnifeGithubCreate
|
|
157
213
|
|
158
214
|
# Create the cookbook template for upload
|
159
215
|
# @param name [String] cookbook name
|
160
|
-
|
161
|
-
|
216
|
+
# tmp [String] temp location
|
217
|
+
def create_cookbook(name, tmp)
|
218
|
+
args = [ name ]
|
162
219
|
create = Chef::Knife::CookbookCreate.new(args)
|
220
|
+
create.config[:cookbook_path] = tmp
|
163
221
|
create.run
|
164
222
|
end
|
165
223
|
|
166
224
|
# Create the json body with repo config for POST information
|
167
225
|
# @param name [String] cookbook name
|
168
|
-
def get_body_json(cookbook_name)
|
226
|
+
def get_body_json(cookbook_name, description="Please fill in the description.")
|
169
227
|
body = {
|
170
228
|
"name" => cookbook_name,
|
171
|
-
"description" =>
|
229
|
+
"description" => description,
|
172
230
|
"private" => false,
|
173
231
|
"has_issues" => true,
|
174
232
|
"has_wiki" => true,
|
@@ -0,0 +1,273 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Sander Botman (<sbotman@schubergphilis.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 Sander Botman.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/knife'
|
20
|
+
|
21
|
+
module KnifeGithubRepoDestroy
|
22
|
+
class GithubRepoDestroy < Chef::Knife
|
23
|
+
# Implements the knife github repo destroy function
|
24
|
+
#
|
25
|
+
# == Overview
|
26
|
+
# The command will delete and destroy your repo on the github.
|
27
|
+
#
|
28
|
+
# === Examples
|
29
|
+
# Destroy a repository:
|
30
|
+
# knife github repo destroy <name>
|
31
|
+
#
|
32
|
+
# === Options
|
33
|
+
# -t --github_token Authentication token for the github.
|
34
|
+
# -U --github_user_repo Destroy the cookbook in the user environment.
|
35
|
+
#
|
36
|
+
|
37
|
+
deps do
|
38
|
+
require 'chef/knife/github_base'
|
39
|
+
include Chef::Knife::GithubBase
|
40
|
+
require 'chef/mixin/shell_out'
|
41
|
+
end
|
42
|
+
|
43
|
+
banner "knife github repo destroy <name> (options)"
|
44
|
+
category "github"
|
45
|
+
|
46
|
+
option :github_token,
|
47
|
+
:short => "-t",
|
48
|
+
:long => "--github_token",
|
49
|
+
:description => "Your github token for OAuth authentication"
|
50
|
+
|
51
|
+
option :github_user_repo,
|
52
|
+
:short => "-U",
|
53
|
+
:long => "--github_user_repo",
|
54
|
+
:description => "Create the repo within your user environment",
|
55
|
+
:boolean => true
|
56
|
+
|
57
|
+
def run
|
58
|
+
extend Chef::Mixin::ShellOut
|
59
|
+
|
60
|
+
# validate base options from base module.
|
61
|
+
validate_base_options
|
62
|
+
|
63
|
+
# Display information if debug mode is on.
|
64
|
+
display_debug_info
|
65
|
+
|
66
|
+
# Get the repo name from the command line
|
67
|
+
name = name_args.first
|
68
|
+
|
69
|
+
# Get the organization name from config
|
70
|
+
org = locate_config_value('github_organizations').first
|
71
|
+
|
72
|
+
if name.nil? || name.empty?
|
73
|
+
Chef::Log.error("Please specify a repository name")
|
74
|
+
exit 1
|
75
|
+
end
|
76
|
+
|
77
|
+
user = get_userlogin
|
78
|
+
|
79
|
+
if config[:github_user_repo]
|
80
|
+
url = @github_url + "/api/" + @github_api_version + "/repos/#{user}/#{name}"
|
81
|
+
Chef::Log.debug("Destroying repository in user environment: #{user}")
|
82
|
+
else
|
83
|
+
url = @github_url + "/api/" + @github_api_version + "/repos/#{org}/#{name}"
|
84
|
+
Chef::Log.debug("Destroying repository in organization: #{org}")
|
85
|
+
end
|
86
|
+
|
87
|
+
# @github_tmp = locate_config_value("github_tmp") || '/var/tmp/gitcreate'
|
88
|
+
# @github_tmp = "#{@github_tmp}#{Process.pid}"
|
89
|
+
|
90
|
+
# Get token information
|
91
|
+
token = get_github_token()
|
92
|
+
|
93
|
+
# Get body data for post
|
94
|
+
# body = get_body_json(name, desc)
|
95
|
+
|
96
|
+
# Creating the local repository
|
97
|
+
# Chef::Log.debug("Creating the local repository based on template")
|
98
|
+
# create_cookbook(name, @github_tmp)
|
99
|
+
|
100
|
+
# cookbook_path = File.join(@github_tmp, name)
|
101
|
+
|
102
|
+
# Updating README.md if needed.
|
103
|
+
# update_readme(cookbook_path)
|
104
|
+
|
105
|
+
# Updateing metadata.rb if needed.
|
106
|
+
# update_metadata(cookbook_path)
|
107
|
+
|
108
|
+
# Creating the github repository
|
109
|
+
repo = delete_request(url, token)
|
110
|
+
puts "Repo: #{name} is deleted" if repo.nil?
|
111
|
+
|
112
|
+
# github_ssh_url = repo['ssh_url']
|
113
|
+
|
114
|
+
# Chef::Log.debug("Commit and push local repository")
|
115
|
+
# Initialize the local git repo
|
116
|
+
# git_commit_and_push(cookbook_path, github_ssh_url)
|
117
|
+
|
118
|
+
# Chef::Log.debug("Removing temp files")
|
119
|
+
# FileUtils.remove_entry(@github_tmp)
|
120
|
+
end
|
121
|
+
|
122
|
+
# Set the username in README.md
|
123
|
+
# @param cookbook_path [String] cookbook path
|
124
|
+
# github_ssh_url [String] github ssh url from repo
|
125
|
+
def git_commit_and_push(cookbook_path, github_ssh_url)
|
126
|
+
shell_out!("git init", :cwd => cookbook_path )
|
127
|
+
shell_out!("git add .", :cwd => cookbook_path )
|
128
|
+
shell_out!("git commit -m 'creating initial cookbook structure from the knife-github plugin' ", :cwd => cookbook_path )
|
129
|
+
shell_out!("git remote add origin #{github_ssh_url} ", :cwd => cookbook_path )
|
130
|
+
shell_out!("git push -u origin master", :cwd => cookbook_path )
|
131
|
+
end
|
132
|
+
|
133
|
+
# Set the username in README.md
|
134
|
+
# @param name [String] cookbook path
|
135
|
+
def update_readme(cookbook_path)
|
136
|
+
contents = ''
|
137
|
+
username = get_username
|
138
|
+
readme = File.join(cookbook_path, "README.md")
|
139
|
+
File.foreach(readme) do |line|
|
140
|
+
line.gsub!(/TODO: List authors/,"#{username}\n")
|
141
|
+
contents = contents << line
|
142
|
+
end
|
143
|
+
File.open(readme, 'w') {|f| f.write(contents) }
|
144
|
+
return nil
|
145
|
+
end
|
146
|
+
|
147
|
+
# Set the username and email in metadata.rb
|
148
|
+
# @param name [String] cookbook path
|
149
|
+
def update_metadata(cookbook_path)
|
150
|
+
contents = ''
|
151
|
+
username = get_username
|
152
|
+
email = get_useremail
|
153
|
+
metadata = File.join(cookbook_path, "metadata.rb")
|
154
|
+
File.foreach(metadata) do |line|
|
155
|
+
line.gsub!(/YOUR_COMPANY_NAME/,username) if username
|
156
|
+
line.gsub!(/YOUR_EMAIL/,email) if email
|
157
|
+
contents = contents << line
|
158
|
+
end
|
159
|
+
File.open(metadata, 'w') {|f| f.write(contents) }
|
160
|
+
return nil
|
161
|
+
end
|
162
|
+
|
163
|
+
# Get the username from passwd file or git config
|
164
|
+
# @param nil
|
165
|
+
def get_username()
|
166
|
+
username = ENV['USER']
|
167
|
+
passwd_user = %x(getent passwd #{username} | cut -d ':' -f 5).chomp
|
168
|
+
username = passwd_user if passwd_user
|
169
|
+
git_user_name = %x(git config user.name).strip
|
170
|
+
username = git_user_name if git_user_name
|
171
|
+
username
|
172
|
+
end
|
173
|
+
|
174
|
+
# Get the email from passwd file or git config
|
175
|
+
# @param nil
|
176
|
+
def get_useremail()
|
177
|
+
email = nil
|
178
|
+
git_user_email = %x(git config user.email).strip
|
179
|
+
email = git_user_email if git_user_email
|
180
|
+
email
|
181
|
+
end
|
182
|
+
|
183
|
+
# Get the email from passwd file or git config
|
184
|
+
# @param nil
|
185
|
+
def get_userlogin()
|
186
|
+
email = get_useremail()
|
187
|
+
unless email
|
188
|
+
puts "Cannot continue without login information. Please define the git email address."
|
189
|
+
exit 1
|
190
|
+
end
|
191
|
+
login = email.split('@').first
|
192
|
+
end
|
193
|
+
|
194
|
+
|
195
|
+
# Create the cookbook template for upload
|
196
|
+
# @param name [String] cookbook name
|
197
|
+
# tmp [String] temp location
|
198
|
+
def create_cookbook(name, tmp)
|
199
|
+
args = [ name ]
|
200
|
+
create = Chef::Knife::CookbookCreate.new(args)
|
201
|
+
create.config[:cookbook_path] = tmp
|
202
|
+
create.run
|
203
|
+
end
|
204
|
+
|
205
|
+
# Create the json body with repo config for POST information
|
206
|
+
# @param name [String] cookbook name
|
207
|
+
def get_body_json()
|
208
|
+
body = {
|
209
|
+
"scopes" => ["public_repo"]
|
210
|
+
}.to_json
|
211
|
+
end
|
212
|
+
|
213
|
+
# Get the OAuth authentication token from config or command line
|
214
|
+
# @param nil
|
215
|
+
def get_github_token()
|
216
|
+
token = locate_config_value('github_token')
|
217
|
+
if token.nil? || token.empty?
|
218
|
+
Chef::Log.error("Cannot find any token information!")
|
219
|
+
Chef::Log.error("Please use: knife github token create")
|
220
|
+
exit 1
|
221
|
+
end
|
222
|
+
token
|
223
|
+
end
|
224
|
+
|
225
|
+
# Send DELETE command to API OAuth authentication token from config or command line
|
226
|
+
# @param url [String] target url (organization or user)
|
227
|
+
# body [JSON] json data with repo configuration
|
228
|
+
# token [String] token sring
|
229
|
+
def delete_request(url, token)
|
230
|
+
|
231
|
+
# if @github_ssl_verify_mode == "verify_none"
|
232
|
+
# config[:ssl_verify_mode] = :verify_none
|
233
|
+
# elsif @github_ssl_verify_mode == "verify_peer"
|
234
|
+
# config[:ssl_verify_mode] = :verify_peer
|
235
|
+
# end
|
236
|
+
|
237
|
+
Chef::Log.debug("URL: " + url.to_s)
|
238
|
+
|
239
|
+
uri = URI.parse(url)
|
240
|
+
http = Net::HTTP.new(uri.host,uri.port)
|
241
|
+
if uri.scheme == "https"
|
242
|
+
http.use_ssl = true
|
243
|
+
if @github_ssl_verify_mode == "verify_none"
|
244
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
245
|
+
else
|
246
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
247
|
+
end
|
248
|
+
end
|
249
|
+
|
250
|
+
req = Net::HTTP::Delete.new(uri.path, initheader = {"Authorization" => "token #{token}"})
|
251
|
+
req.body = get_body_json()
|
252
|
+
response = http.request(req)
|
253
|
+
|
254
|
+
return nil if response.code == "204"
|
255
|
+
|
256
|
+
unless response.code == "201" then
|
257
|
+
puts "Error #{response.code}: #{response.message}"
|
258
|
+
puts JSON.pretty_generate(JSON.parse(response.body))
|
259
|
+
puts "URL: #{url}"
|
260
|
+
exit 1
|
261
|
+
end
|
262
|
+
|
263
|
+
begin
|
264
|
+
json = JSON.parse(response.body)
|
265
|
+
rescue
|
266
|
+
ui.warn "The result on the RESTRequest is not in json format"
|
267
|
+
ui.warn "Output: " + response.body
|
268
|
+
exit 1
|
269
|
+
end
|
270
|
+
json
|
271
|
+
end
|
272
|
+
end
|
273
|
+
end
|
@@ -24,8 +24,6 @@ module KnifeGithubSearch
|
|
24
24
|
deps do
|
25
25
|
require 'chef/knife/github_base'
|
26
26
|
include Chef::Knife::GithubBase
|
27
|
-
require 'chef/knife/github_baselist'
|
28
|
-
include Chef::Knife::GithubBaseList
|
29
27
|
end
|
30
28
|
|
31
29
|
banner "knife github search STRING (options)"
|
@@ -80,8 +78,7 @@ module KnifeGithubSearch
|
|
80
78
|
|
81
79
|
url = @github_url + "/api/" + @github_api_version + "/legacy/repos/search/" + query
|
82
80
|
Chef::Log.debug("URL: #{url}")
|
83
|
-
|
84
|
-
send_request(url)
|
81
|
+
connection.send_get_request(url, params = {})
|
85
82
|
end
|
86
83
|
|
87
84
|
end
|
@@ -0,0 +1,239 @@
|
|
1
|
+
#
|
2
|
+
# Author:: Sander Botman (<sbotman@schubergphilis.com>)
|
3
|
+
# Copyright:: Copyright (c) 2013 Sander Botman.
|
4
|
+
# License:: Apache License, Version 2.0
|
5
|
+
#
|
6
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
7
|
+
# you may not use this file except in compliance with the License.
|
8
|
+
# You may obtain a copy of the License at
|
9
|
+
#
|
10
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
11
|
+
#
|
12
|
+
# Unless required by applicable law or agreed to in writing, software
|
13
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
14
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
15
|
+
# See the License for the specific language governing permissions and
|
16
|
+
# limitations under the License.
|
17
|
+
#
|
18
|
+
|
19
|
+
require 'chef/knife'
|
20
|
+
|
21
|
+
module KnifeGithubTokenCreate
|
22
|
+
class GithubTokenCreate < Chef::Knife
|
23
|
+
# Implements the knife github token create function
|
24
|
+
#
|
25
|
+
# == Overview
|
26
|
+
# The command will create a authorization token in order to communicate with the github enterprise appliance.
|
27
|
+
#
|
28
|
+
# === Examples
|
29
|
+
# Create a new token:
|
30
|
+
# knife github token create <username>
|
31
|
+
#
|
32
|
+
# # Deploy a release version of cookbook to your chef server
|
33
|
+
# # knife github deploy cookbook_name -f
|
34
|
+
#
|
35
|
+
# === Options
|
36
|
+
# -t --github_token Authentication token for the github.
|
37
|
+
# -U --github_user_repo Create the cookbook in the user environment.
|
38
|
+
#
|
39
|
+
|
40
|
+
deps do
|
41
|
+
require 'knife-github/password'
|
42
|
+
require 'chef/knife/github_base'
|
43
|
+
include Chef::Knife::GithubBase
|
44
|
+
require 'chef/mixin/shell_out'
|
45
|
+
end
|
46
|
+
|
47
|
+
banner "knife github token create <username> (options)"
|
48
|
+
category "github"
|
49
|
+
|
50
|
+
option :force,
|
51
|
+
:short => "-f",
|
52
|
+
:long => "--force",
|
53
|
+
:description => "Force token creation for OAuth authentication",
|
54
|
+
:boolean => true
|
55
|
+
|
56
|
+
option :github_user_repo,
|
57
|
+
:short => "-U",
|
58
|
+
:long => "--github_user_repo",
|
59
|
+
:description => "Create the repo within your user environment",
|
60
|
+
:boolean => true
|
61
|
+
|
62
|
+
def run
|
63
|
+
extend Chef::Mixin::ShellOut
|
64
|
+
|
65
|
+
# validate base options from base module.
|
66
|
+
validate_base_options
|
67
|
+
|
68
|
+
# Display information if debug mode is on.
|
69
|
+
display_debug_info
|
70
|
+
|
71
|
+
# Get the name_args from the command line
|
72
|
+
username = name_args.first
|
73
|
+
|
74
|
+
# Get token information
|
75
|
+
token = get_github_token() unless config[:force]
|
76
|
+
|
77
|
+
# Create github token if needed
|
78
|
+
if token.nil?
|
79
|
+
token = validate_github_token(username)
|
80
|
+
update_knife_config(token)
|
81
|
+
end
|
82
|
+
|
83
|
+
puts "Finished updating your token. Using key:#{token}"
|
84
|
+
end
|
85
|
+
|
86
|
+
# Updates the knife configuration with the token information inside ~/.chef/knife.rb
|
87
|
+
# @param token [String] token key
|
88
|
+
#
|
89
|
+
def update_knife_config(token)
|
90
|
+
contents = ''
|
91
|
+
update = false
|
92
|
+
config = File.join(ENV["HOME"], ".chef/knife.rb")
|
93
|
+
File.foreach(config) do |line|
|
94
|
+
if line =~ /^\s*knife\[:github_token\].*/ && !token.nil?
|
95
|
+
Chef::Log.debug("Replacing current token with: #{token}")
|
96
|
+
contents = contents << "knife[:github_token] = \"#{token}\"\n"
|
97
|
+
update = true
|
98
|
+
else
|
99
|
+
contents = contents << line
|
100
|
+
end
|
101
|
+
end
|
102
|
+
unless update
|
103
|
+
Chef::Log.debug("Updating configuration with token: #{token}")
|
104
|
+
contents = contents << "knife[:github_token] = \"#{token}\"\n"
|
105
|
+
end
|
106
|
+
File.open(config, 'w') {|f| f.write(contents) }
|
107
|
+
return true
|
108
|
+
end
|
109
|
+
|
110
|
+
# Get the OAuth authentication token from config or command line
|
111
|
+
# @param none
|
112
|
+
def get_github_token()
|
113
|
+
token = locate_config_value('github_token')
|
114
|
+
if token.nil? || token.empty?
|
115
|
+
return nil
|
116
|
+
else
|
117
|
+
return token
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
# Validate the OAuth authentication token for the knife-github application.
|
122
|
+
# @param username [String] validates the token for specific user. (default is ENV['USER'])
|
123
|
+
#
|
124
|
+
def validate_github_token(username=nil)
|
125
|
+
params = {}
|
126
|
+
username = ENV["USER"] if username.nil?
|
127
|
+
|
128
|
+
params[:url] = @github_url + "/api/" + @github_api_version + "/authorizations"
|
129
|
+
Chef::Log.debug("Validating token information for user: #{username}.")
|
130
|
+
|
131
|
+
params[:username] = username
|
132
|
+
params[:password] = Github::Password.get( "Please enter github password for #{username} :" )
|
133
|
+
params[:action] = "GET"
|
134
|
+
|
135
|
+
token_key = nil
|
136
|
+
|
137
|
+
result = send_request(params)
|
138
|
+
result.each do |token|
|
139
|
+
if token['app'] && token['app']['name'] == "knife-github (API)"
|
140
|
+
if token['scopes'].include?("delete_repo")
|
141
|
+
Chef::Log.debug("Found and using token: #{token_key}")
|
142
|
+
token_key = token['token']
|
143
|
+
else
|
144
|
+
Chef::Log.debug("Found token: #{token_key} but wrong scope, deleting token.")
|
145
|
+
params[:id] = token['id']
|
146
|
+
delete_github_token(params)
|
147
|
+
end
|
148
|
+
end
|
149
|
+
end
|
150
|
+
|
151
|
+
if token_key.nil?
|
152
|
+
result = create_github_token(params)
|
153
|
+
token_key = result['token']
|
154
|
+
end
|
155
|
+
|
156
|
+
return token_key
|
157
|
+
end
|
158
|
+
|
159
|
+
|
160
|
+
# Create the OAuth authentication token for the knife-github application.
|
161
|
+
# @param params [Hash] Hash containing all options
|
162
|
+
# params[:username] [String] Username if no token specified
|
163
|
+
# params[:password] [String] Password if no token specified
|
164
|
+
#
|
165
|
+
def create_github_token(params)
|
166
|
+
Chef::Log.debug("Creating new application token for user: #{username}.")
|
167
|
+
params[:url] = @github_url + "/api/" + @github_api_version + "/authorizations"
|
168
|
+
params[:body] = '{"note":"knife-github","scopes":["delete_repo", "user", "public_repo", "repo", "gist"]"}'
|
169
|
+
params[:action] = "POST"
|
170
|
+
send_request(params)
|
171
|
+
end
|
172
|
+
|
173
|
+
def delete_github_token(params)
|
174
|
+
Chef::Log.debug("Deleting token id: #{params[':id']}")
|
175
|
+
params[:url] = @github_url + "/api/" + @github_api_version + "/authorizations/#{params[:id]}"
|
176
|
+
params[:action] = "DELETE"
|
177
|
+
send_request(params)
|
178
|
+
end
|
179
|
+
|
180
|
+
# Post Get the OAuth authentication token from config or command line
|
181
|
+
# @param params [Hash] Hash containing all options
|
182
|
+
# params[:url] [String] Url to target
|
183
|
+
# params[:body] [JSON] json data for the request
|
184
|
+
# params[:token] [String] OAuth token
|
185
|
+
# params[:username] [String] Username if no token specified
|
186
|
+
# params[:password] [String] Password if no token specified
|
187
|
+
#
|
188
|
+
def send_request(params)
|
189
|
+
url = params[:url]
|
190
|
+
|
191
|
+
Chef::Log.debug("URL: " + url.to_s)
|
192
|
+
|
193
|
+
uri = URI.parse(url)
|
194
|
+
http = Net::HTTP.new(uri.host,uri.port)
|
195
|
+
if uri.scheme == "https"
|
196
|
+
http.use_ssl = true
|
197
|
+
if @github_ssl_verify_mode == "verify_none"
|
198
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
|
199
|
+
else
|
200
|
+
http.verify_mode = OpenSSL::SSL::VERIFY_PEER
|
201
|
+
end
|
202
|
+
end
|
203
|
+
|
204
|
+
if params[:action] == "GET"
|
205
|
+
req = Net::HTTP::Get.new(uri.path)
|
206
|
+
elsif params[:action] == "POST"
|
207
|
+
req = Net::HTTP::Post.new(uri.path)
|
208
|
+
elsif params[:action] == "DELETE"
|
209
|
+
req = Net::HTTP::Delete.new(uri.path)
|
210
|
+
end
|
211
|
+
|
212
|
+
if params[:token].nil?
|
213
|
+
req.basic_auth params[:username], params[:password]
|
214
|
+
else
|
215
|
+
req.initheader = ({"Authorization" => "token #{params[:token]}"})
|
216
|
+
end
|
217
|
+
req.body = params[:body] if params[:body]
|
218
|
+
response = http.request(req)
|
219
|
+
|
220
|
+
unless response.code =~ /^2../ then
|
221
|
+
puts "Error #{response.code}: #{response.message}"
|
222
|
+
puts JSON.pretty_generate(JSON.parse(response.body))
|
223
|
+
puts "URL: #{url}"
|
224
|
+
exit 1
|
225
|
+
end
|
226
|
+
|
227
|
+
return nil if response.body.nil? || response.body.empty?
|
228
|
+
|
229
|
+
begin
|
230
|
+
json = JSON.parse(response.body)
|
231
|
+
rescue
|
232
|
+
ui.warn "The result on the REST Request is not in json format"
|
233
|
+
ui.warn "Output: " + response.body
|
234
|
+
exit 1
|
235
|
+
end
|
236
|
+
json
|
237
|
+
end
|
238
|
+
end
|
239
|
+
end
|
data/lib/knife-github/config.rb
CHANGED
@@ -0,0 +1,85 @@
|
|
1
|
+
require 'termios'
|
2
|
+
|
3
|
+
module Github
|
4
|
+
class Password < String
|
5
|
+
|
6
|
+
# Turn local terminal echo on or off. This method is used for securing the
|
7
|
+
# display, so that a soon to be entered password will not be echoed to the
|
8
|
+
# screen. It is also used for restoring the display afterwards.
|
9
|
+
#
|
10
|
+
# If _masked_ is +true+, the keyboard is put into unbuffered mode, allowing
|
11
|
+
# the retrieval of characters one at a time. _masked_ has no effect when
|
12
|
+
# _on_ is +false+. You are unlikely to need this method in the course of
|
13
|
+
# normal operations.
|
14
|
+
#
|
15
|
+
def Password.echo(on=true, masked=false)
|
16
|
+
term = Termios::getattr( $stdin )
|
17
|
+
|
18
|
+
if on
|
19
|
+
term.c_lflag |= ( Termios::ECHO | Termios::ICANON )
|
20
|
+
else # off
|
21
|
+
term.c_lflag &= ~Termios::ECHO
|
22
|
+
term.c_lflag &= ~Termios::ICANON if masked
|
23
|
+
end
|
24
|
+
|
25
|
+
Termios::setattr( $stdin, Termios::TCSANOW, term )
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
# Get a password from _STDIN_, using buffered line input and displaying
|
30
|
+
# _message_ as the prompt. No output will appear while the password is being
|
31
|
+
# typed. Hitting <b>[Enter]</b> completes password entry. If _STDIN_ is not
|
32
|
+
# connected to a tty, no prompt will be displayed.
|
33
|
+
#
|
34
|
+
def Password.get(message="Password: ")
|
35
|
+
begin
|
36
|
+
if $stdin.tty?
|
37
|
+
Password.echo false
|
38
|
+
print message if message
|
39
|
+
end
|
40
|
+
|
41
|
+
pw = Password.new( $stdin.gets || "" )
|
42
|
+
pw.chomp!
|
43
|
+
|
44
|
+
ensure
|
45
|
+
if $stdin.tty?
|
46
|
+
Password.echo true
|
47
|
+
print "\n"
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
# Get a password from _STDIN_ in unbuffered mode, i.e. one key at a time.
|
54
|
+
# _message_ will be displayed as the prompt and each key press with echo
|
55
|
+
# _mask_ to the terminal. There is no need to hit <b>[Enter]</b> at the end.
|
56
|
+
#
|
57
|
+
def Password.getc(message="Password: ", mask='*')
|
58
|
+
# Save current buffering mode
|
59
|
+
buffering = $stdout.sync
|
60
|
+
|
61
|
+
# Turn off buffering
|
62
|
+
$stdout.sync = true
|
63
|
+
|
64
|
+
begin
|
65
|
+
Password.echo(false, true)
|
66
|
+
print message if message
|
67
|
+
pw = ""
|
68
|
+
|
69
|
+
while ( char = $stdin.getc ) != 10 # break after [Enter]
|
70
|
+
putc mask
|
71
|
+
pw << char
|
72
|
+
end
|
73
|
+
|
74
|
+
ensure
|
75
|
+
Password.echo true
|
76
|
+
print "\n"
|
77
|
+
end
|
78
|
+
|
79
|
+
# Restore original buffering mode
|
80
|
+
$stdout.sync = buffering
|
81
|
+
|
82
|
+
Password.new( pw )
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
data/lib/knife-github/version.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: knife-github
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 0.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -10,7 +10,7 @@ authors:
|
|
10
10
|
autorequire:
|
11
11
|
bindir: bin
|
12
12
|
cert_chain: []
|
13
|
-
date: 2013-
|
13
|
+
date: 2013-12-31 00:00:00.000000000 Z
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
16
16
|
name: mixlib-versioning
|
@@ -28,6 +28,22 @@ dependencies:
|
|
28
28
|
- - ! '>='
|
29
29
|
- !ruby/object:Gem::Version
|
30
30
|
version: 1.0.0
|
31
|
+
- !ruby/object:Gem::Dependency
|
32
|
+
name: ruby-termios
|
33
|
+
requirement: !ruby/object:Gem::Requirement
|
34
|
+
none: false
|
35
|
+
requirements:
|
36
|
+
- - ! '>='
|
37
|
+
- !ruby/object:Gem::Version
|
38
|
+
version: 0.9.6
|
39
|
+
type: :runtime
|
40
|
+
prerelease: false
|
41
|
+
version_requirements: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: 0.9.6
|
31
47
|
- !ruby/object:Gem::Dependency
|
32
48
|
name: chef
|
33
49
|
requirement: !ruby/object:Gem::Requirement
|
@@ -91,14 +107,17 @@ files:
|
|
91
107
|
- lib/chef/knife/github_cleanup.rb
|
92
108
|
- lib/chef/knife/github_clone.rb
|
93
109
|
- lib/chef/knife/github_compare.rb
|
94
|
-
- lib/chef/knife/github_create.rb
|
95
110
|
- lib/chef/knife/github_deploy.rb
|
96
111
|
- lib/chef/knife/github_diff.rb
|
97
112
|
- lib/chef/knife/github_list.rb
|
98
113
|
- lib/chef/knife/github_pin.rb
|
114
|
+
- lib/chef/knife/github_repo_create.rb
|
115
|
+
- lib/chef/knife/github_repo_destroy.rb
|
99
116
|
- lib/chef/knife/github_search.rb
|
117
|
+
- lib/chef/knife/github_token_create.rb
|
100
118
|
- lib/knife-github/config.rb
|
101
119
|
- lib/knife-github/connection.rb
|
120
|
+
- lib/knife-github/password.rb
|
102
121
|
- lib/knife-github/repo.rb
|
103
122
|
- lib/knife-github/version.rb
|
104
123
|
homepage: https://github.com/schubergphilis/knife-github
|