jenkins_shell 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 8b75e3e5e33e080ce9171c0b0ee8db6516c0ac65caf40f6439f2ab29d46a8f48
4
- data.tar.gz: 8d6e7aa40827b25a6c0ae21be8189aa91e2117100578a033dadfbb8d9adab657
3
+ metadata.gz: 2a3c4e6f5e959d87ca2844c64a33796acd3f451ab3a539f9753ddcc3c513d79f
4
+ data.tar.gz: 18488798eeaf5089518edfd2d99318a388b28d7e1a555769fa140682e4f5fb91
5
5
  SHA512:
6
- metadata.gz: ac037325b5a840fb70578e5dc11705b22d21653d0f26e8d8cae5afb550220d483076d4e992c137cbc7260fe5626a3a3d6eb0443fc8acf79caeae6bce598aa6fa
7
- data.tar.gz: 317538957c5d1f4d0d4e16f170926d0e67cca4612652cf1acaeba0406030fac8cd3096e006274f72e359d16d4fc8ad08c8e5224ba2c919e0c85394ae81c9b4e6
6
+ metadata.gz: bb5d6ca84706904c59e0626eaa60e91e3e536558dc3fa37103b301a65fe608af89f7fa5972a6e5c74bf0f548dabe3cf7e3e08cc80ca631de71629d017396a6f4
7
+ data.tar.gz: 447d92effb45eb20436baa27f5da20811aa23a8d7ac18dbdb81c853a6fb73588385857043747c8fe9e5d09aee823cca9f37f409f87dd89ec7162724a4ed56ee5
data/bin/jsh CHANGED
@@ -16,9 +16,18 @@ class JShExit
16
16
  AMBIGUOUS_ARGUMENT = 6
17
17
  end
18
18
 
19
+ def get_password
20
+ print "Enter password: "
21
+ passwd = STDIN.noecho(&:gets)
22
+ puts
23
+ return passwd.chomp
24
+ end
25
+
19
26
  def parse(args)
20
27
  options = Hash.new
28
+ options["password"] = nil
21
29
  options["port"] = "8080"
30
+ options["username"] = nil
22
31
  options["verbose"] = false
23
32
 
24
33
  info = "Simulate a cmd prompt using Jenkins script functionality"
@@ -45,6 +54,13 @@ def parse(args)
45
54
  Hilighter.disable
46
55
  end
47
56
 
57
+ opts.on(
58
+ "--password=PASSWORD",
59
+ "Use specified password (will prompt if not provided)"
60
+ ) do |password|
61
+ options["password"] = password
62
+ end
63
+
48
64
  opts.on(
49
65
  "-p",
50
66
  "--port=PORT",
@@ -53,6 +69,10 @@ def parse(args)
53
69
  options["port"] = port
54
70
  end
55
71
 
72
+ opts.on("-u", "--user=USER", "Use specified username") do |u|
73
+ options["username"] = u
74
+ end
75
+
56
76
  opts.on(
57
77
  "-v",
58
78
  "--verbose",
@@ -98,7 +118,14 @@ end
98
118
  options = parse(ARGV)
99
119
 
100
120
  begin
101
- jsh = JenkinsShell.new(options["host"], options["port"])
121
+ passwd = options["password"]
122
+ passwd = get_password if (options["username"] && passwd.nil?)
123
+ jsh = JenkinsShell.new(
124
+ options["host"],
125
+ options["port"],
126
+ options["username"],
127
+ passwd
128
+ )
102
129
 
103
130
  djinni = Djinni.new
104
131
  djinni.fallback = "cmd"
@@ -3,9 +3,13 @@ require "rexml/document"
3
3
  require "uri"
4
4
 
5
5
  class JenkinsShell
6
+ attr_reader :cookie
7
+ attr_reader :crumb
6
8
  attr_reader :cwd
7
9
  attr_reader :host
10
+ attr_reader :password
8
11
  attr_reader :port
12
+ attr_reader :username
9
13
 
10
14
  def cd(dir = nil)
11
15
  return true if (dir.nil? || dir.empty?)
@@ -21,20 +25,48 @@ class JenkinsShell
21
25
  end
22
26
 
23
27
  def command(cmd, dir = @int_cwd)
24
- # Create and encode Groovy script
28
+ login if (@username && (@cookie.nil? || @crumb.nil?))
29
+ if (@username && (@cookie.nil? || @crumb.nil?))
30
+ raise JenkinsShell::Error::LoginFailure.new
31
+ end
32
+
33
+ # Create Groovy script
25
34
  fix = dir.gsub(/\\/, "\\\\\\")
26
35
  gs = "println(\"cmd /c cd #{fix} && #{cmd}\".execute().text)"
27
- enc = URI::encode(URI::encode(gs), "&()/").gsub("%20", "+")
28
36
 
37
+ # Make POST request and return command output
38
+ xml = post("/script", "script=#{encode(gs)}")[1]
39
+ output = xml.get_elements("html/body/div/div/pre")[1]
40
+ return "" if (output.nil?)
41
+ return output.text.strip
42
+ end
43
+
44
+ def encode(str)
45
+ # TODO what other chars need encoded?
46
+ return URI::encode(URI::encode(str), "@&()/").gsub("%20", "+")
47
+ end
48
+ private :encode
49
+
50
+ def get(path)
29
51
  begin
30
- # Establish connection and send script
52
+ # Establish connection
31
53
  http = Net::HTTP.new(@host, @port)
32
- xml = REXML::Document.new(
33
- http.post("/script", "script=#{enc}").body
34
- )
35
54
 
36
- # Parse response and return script output
37
- return xml.get_elements("html/body/div/div/pre")[1].text
55
+ # Create request
56
+ req = Net::HTTP::Get.new(path)
57
+ req["Cookie"] = @cookie if (@cookie)
58
+
59
+ # Send request and get response
60
+ res = http.request(req)
61
+
62
+ # Parse HTML body
63
+ xml = REXML::Document.new(res.body)
64
+
65
+ # Store needed values
66
+ store_state(res, xml)
67
+
68
+ # Return headers and xml body
69
+ return res, xml
38
70
  rescue Errno::ECONNREFUSED
39
71
  raise JenkinsShell::Error::ConnectionRefused.new(
40
72
  @host,
@@ -43,22 +75,88 @@ class JenkinsShell
43
75
  rescue REXML::ParseException
44
76
  raise JenkinsShell::Error::InvalidHTMLReceived.new
45
77
  end
46
- return ""
47
78
  end
79
+ private :get
48
80
 
49
- def initialize(host, port = 8080)
81
+ def initialize(host, port = 8080, username = nil, password = nil)
82
+ @cookie = nil
83
+ @crumb = nil
50
84
  @int_cwd = "."
51
85
  @host = host.gsub(/^https?:\/\/|(:[0-9]+)?\/.+/, "")
86
+ @password = password
52
87
  @port = port
88
+ @username = username
53
89
  @cwd = pwd
54
90
  end
55
91
 
92
+ def login
93
+ get("/login")
94
+ post(
95
+ "/j_acegi_security_check",
96
+ [
97
+ "j_username=#{encode(@username)}",
98
+ "j_password=#{encode(@password)}",
99
+ "Submit=log+in"
100
+ ].join("&")
101
+ )
102
+ get("/")
103
+ end
104
+
105
+ def post(path, data)
106
+ body = Array.new
107
+ body.push("Jenkins-Crumb=#{@crumb}") if (@crumb)
108
+ body.push(data)
109
+
110
+ begin
111
+ # Establish connection
112
+ http = Net::HTTP.new(@host, @port)
113
+
114
+ # Create request
115
+ req = Net::HTTP::Post.new(path)
116
+ req.body = body.join("&")
117
+ req["Cookie"] = @cookie if (@cookie)
118
+
119
+ # Send request and get response
120
+ res = http.request(req)
121
+
122
+ # Parse HTML response
123
+ xml = REXML::Document.new(res.body)
124
+
125
+ # Store needed values
126
+ store_state(res, xml)
127
+
128
+ # Return headers and xml body
129
+ return res, xml
130
+ rescue Errno::ECONNREFUSED
131
+ raise JenkinsShell::Error::ConnectionRefused.new(
132
+ @host,
133
+ @port
134
+ )
135
+ rescue REXML::ParseException
136
+ raise JenkinsShell::Error::InvalidHTMLReceived.new
137
+ end
138
+ end
139
+ private :post
140
+
56
141
  def pwd(dir = @int_cwd)
57
142
  command("dir", dir).match(/^\s+Directory of (.+)/) do |m|
58
143
  return m[1]
59
144
  end
60
145
  return ""
61
146
  end
147
+
148
+ def store_state(headers, xml)
149
+ # Store crumb if it exists
150
+ crumb = xml.get_elements("html/head/script").join
151
+ crumb.match(/"Jenkins-Crumb", "([A-Fa-f0-9]+)"/) do |m|
152
+ @crumb = m[1]
153
+ end
154
+
155
+ # Store cookie if there is one
156
+ new_cookie = headers["Set-Cookie"]
157
+ @cookie = new_cookie if (new_cookie)
158
+ end
159
+ private :store_state
62
160
  end
63
161
 
64
162
  require "jenkins_shell/error"
@@ -3,3 +3,4 @@ end
3
3
 
4
4
  require "jenkins_shell/error/connection_refused"
5
5
  require "jenkins_shell/error/invalid_html_received"
6
+ require "jenkins_shell/error/login_failure"
@@ -0,0 +1,5 @@
1
+ class JenkinsShell::Error::LoginFailure < JenkinsShell::Error
2
+ def initialize
3
+ super("Failure to login")
4
+ end
5
+ end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: jenkins_shell
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.2
4
+ version: 0.0.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Miles Whittaker
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2018-03-15 00:00:00.000000000 Z
11
+ date: 2018-03-16 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: rake
@@ -83,6 +83,7 @@ files:
83
83
  - lib/jenkins_shell/error.rb
84
84
  - lib/jenkins_shell/error/connection_refused.rb
85
85
  - lib/jenkins_shell/error/invalid_html_received.rb
86
+ - lib/jenkins_shell/error/login_failure.rb
86
87
  - lib/jenkins_shell/wish/cd_wish.rb
87
88
  - lib/jenkins_shell/wish/cmd_wish.rb
88
89
  - lib/jenkins_shell/wish/ls_wish.rb