uffizzi-cli 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,33 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'thor'
4
+
5
+ module Uffizzi
6
+ class CLI < Thor
7
+ desc 'version', 'show version'
8
+ def version
9
+ require_relative 'version'
10
+ puts Uffizzi::VERSION
11
+ end
12
+
13
+ desc 'login', 'login'
14
+ method_option :user, required: true, aliases: '-u'
15
+ method_option :hostname, required: true, aliases: '-h'
16
+ def login
17
+ require_relative 'cli/login'
18
+ Login.new(options).run
19
+ end
20
+
21
+ desc 'projects', 'projects'
22
+ def projects
23
+ require_relative 'cli/projects'
24
+ Projects.new.run
25
+ end
26
+
27
+ desc 'config', 'config'
28
+ def config(command, property = nil, value = nil)
29
+ require_relative 'cli/config'
30
+ Config.new.run(command, property, value)
31
+ end
32
+ end
33
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'api_routes'
4
+ require_relative 'http_client'
5
+
6
+ module ApiClient
7
+ include ApiRoutes
8
+ def create_session(hostname, params = {})
9
+ uri = session_uri(hostname)
10
+ response = Uffizzi::HttpClient.make_request(uri, :post, false, params)
11
+
12
+ build_response(response)
13
+ end
14
+
15
+ def fetch_projects(hostname)
16
+ uri = projects_uri(hostname)
17
+ response = Uffizzi::HttpClient.make_request(uri, :get, true)
18
+
19
+ build_response(response)
20
+ end
21
+
22
+ def print_errors(errors)
23
+ puts errors.keys.reduce([]) { |acc, key| acc.push(errors[key]) }
24
+ end
25
+
26
+ private
27
+
28
+ def build_response(response)
29
+ {
30
+ body: response_body(response),
31
+ headers: response_cookie(response),
32
+ code: response.class,
33
+ }
34
+ end
35
+
36
+ def response_body(response)
37
+ return nil if response.body.nil?
38
+
39
+ JSON.parse(response.body, symbolize_names: true)
40
+ end
41
+
42
+ def response_cookie(response)
43
+ cookies = response.to_hash['set-cookie']
44
+ return nil if cookies.nil?
45
+
46
+ cookie_content = cookies.first
47
+ cookie = cookie_content.split(';').first
48
+ Uffizzi::ConfigFile.rewrite_cookie(cookie) if Uffizzi::ConfigFile.exists?
49
+
50
+ cookie
51
+ end
52
+ end
@@ -0,0 +1,11 @@
1
+ # frozen_string_literal: true
2
+
3
+ module ApiRoutes
4
+ def session_uri(hostname)
5
+ "#{hostname}/api/cli/v1/session"
6
+ end
7
+
8
+ def projects_uri(hostname)
9
+ "#{hostname}/api/cli/v1/projects"
10
+ end
11
+ end
@@ -0,0 +1,52 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'net/http'
4
+ require 'json'
5
+ require 'uffizzi/config_file'
6
+
7
+ module Uffizzi
8
+ class HttpClient
9
+ class << self
10
+ def make_request(request_uri, method, require_cookies, params = {})
11
+ uri = URI(request_uri)
12
+ use_ssl = request_uri.start_with?('https')
13
+
14
+ response = Net::HTTP.start(uri.host, uri.port, use_ssl: use_ssl) do |http|
15
+ request = build_request(uri, params, method, require_cookies)
16
+
17
+ http.request(request)
18
+ end
19
+
20
+ if response.instance_of?(Net::HTTPUnauthorized)
21
+ raise StandardError.new('Not authorized')
22
+ end
23
+
24
+ response
25
+ end
26
+
27
+ private
28
+
29
+ def build_request(uri, params, method, require_cookies)
30
+ headers = { 'Content-Type' => 'application/json' }
31
+ request = case method
32
+ when :get
33
+ Net::HTTP::Get.new(uri.path, headers)
34
+ when :post
35
+ Net::HTTP::Post.new(uri.path, headers)
36
+ when :delete
37
+ Net::HTTP::Delete.new(uri.path, headers)
38
+ when :put
39
+ Net::HTTP::Put.new(uri.path, headers)
40
+ end
41
+ if request.instance_of?(Net::HTTP::Post)
42
+ request.body = params.to_json
43
+ end
44
+ request['Cookie'] = ConfigFile.read_option(:cookie) if require_cookies
45
+ if ConfigFile.exists? && ConfigFile.option_exists?(:basic_auth_user) && ConfigFile.option_exists?(:basic_auth_password)
46
+ request.basic_auth(ConfigFile.read_option(:basic_auth_user), ConfigFile.read_option(:basic_auth_password))
47
+ end
48
+ request
49
+ end
50
+ end
51
+ end
52
+ end
@@ -0,0 +1,103 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'json'
4
+ require 'fileutils'
5
+
6
+ module Uffizzi
7
+ class ConfigFile
8
+ CONFIG_PATH = "#{Dir.home}/.uffizzi/config.json"
9
+
10
+ class << self
11
+ def create(account_id, cookie, hostname)
12
+ data = prepare_config_data(account_id, cookie, hostname)
13
+ data.each_pair { |key, value| write_option(key, value) }
14
+ end
15
+
16
+ def delete
17
+ File.delete(CONFIG_PATH) if exists?
18
+ end
19
+
20
+ def exists?
21
+ File.exist?(CONFIG_PATH)
22
+ end
23
+
24
+ def read_option(option)
25
+ data = read
26
+ return nil if data.nil?
27
+
28
+ puts "The option #{option} doesn't exist in config file" if data[option].nil?
29
+ data[option]
30
+ end
31
+
32
+ def option_exists?(option)
33
+ data = read
34
+ return false if data.nil?
35
+
36
+ data.key?(option)
37
+ end
38
+
39
+ def write_option(key, value)
40
+ data = exists? ? read : {}
41
+ return nil if data.nil?
42
+
43
+ data[key] = value
44
+ write(data.to_json)
45
+ end
46
+
47
+ def delete_option(key)
48
+ data = read
49
+ return nil if data.nil?
50
+
51
+ new_data = data.except(key)
52
+ write(new_data.to_json)
53
+ end
54
+
55
+ def rewrite_cookie(cookie)
56
+ write_option(:cookie, cookie)
57
+ end
58
+
59
+ def list
60
+ data = read
61
+ return nil if data.nil?
62
+
63
+ data.each do |property, value|
64
+ puts "#{property} - #{value}"
65
+ end
66
+ end
67
+
68
+ private
69
+
70
+ def read
71
+ JSON.parse(File.read(CONFIG_PATH), symbolize_names: true)
72
+ rescue Errno::ENOENT => e
73
+ puts e
74
+ rescue JSON::ParserError
75
+ puts 'Config file is in incorrect format'
76
+ end
77
+
78
+ def write(data)
79
+ file = create_file
80
+ file.write(data)
81
+ file.close
82
+ end
83
+
84
+ def prepare_config_data(account_id, cookie, hostname)
85
+ {
86
+ account_id: account_id,
87
+ hostname: hostname,
88
+ cookie: cookie,
89
+ }
90
+ end
91
+
92
+ def create_file
93
+ dir = File.dirname(CONFIG_PATH)
94
+
95
+ unless File.directory?(dir)
96
+ FileUtils.mkdir_p(dir)
97
+ end
98
+
99
+ File.new(CONFIG_PATH, 'w')
100
+ end
101
+ end
102
+ end
103
+ end
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Uffizzi
4
+ VERSION = '0.1.0'
5
+ end
data/lib/uffizzi.rb ADDED
@@ -0,0 +1,10 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'uffizzi/version'
4
+ require_relative 'uffizzi/clients/api/api_client'
5
+ require_relative 'uffizzi/clients/api/api_routes'
6
+ require_relative 'uffizzi/config_file'
7
+
8
+ module Uffizzi
9
+ class Error < StandardError; end
10
+ end
data/uffizzi.gemspec ADDED
@@ -0,0 +1,46 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative 'lib/uffizzi/version'
4
+
5
+ Gem::Specification.new do |spec|
6
+ spec.name = 'uffizzi-cli'
7
+ spec.version = Uffizzi::VERSION
8
+ spec.authors = ['Josh Thurman', 'Grayson Adkins']
9
+ spec.email = ['info@uffizzi.com']
10
+
11
+ spec.summary = 'uffizzi-cli'
12
+ spec.description = 'uffizzi-cli'
13
+ spec.homepage = 'https://uffizzi.com'
14
+ spec.license = 'Apache-2.0'
15
+ spec.required_ruby_version = '>= 2.5.0'
16
+
17
+ spec.metadata['homepage_uri'] = spec.homepage
18
+ spec.metadata['source_code_uri'] = 'https://github.com/UffizziCloud/uffizzi_cli'
19
+ spec.metadata['changelog_uri'] = 'https://github.com/UffizziCloud/uffizzi_cli/blob/master/CHANGELOG.md'
20
+
21
+ spec.files = Dir.chdir(File.expand_path(__dir__)) do
22
+ `git ls-files -z`.split("\x0").reject do |f|
23
+ (f == __FILE__) || f.match(%r{\A(?:(?:test|spec|features)/|\.(?:git|travis|circleci)|appveyor)})
24
+ end
25
+ end
26
+ spec.bindir = 'exe'
27
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
28
+ spec.require_paths = ['lib']
29
+
30
+ spec.add_development_dependency 'bundler', '~> 2.2'
31
+ spec.add_development_dependency 'byebug'
32
+ spec.add_development_dependency 'factory_bot'
33
+ spec.add_development_dependency 'minitest'
34
+ spec.add_development_dependency 'minitest-power_assert'
35
+ spec.add_development_dependency 'mocha'
36
+ spec.add_development_dependency 'pry-byebug'
37
+ spec.add_development_dependency 'pry-inline'
38
+ spec.add_development_dependency 'rake'
39
+ spec.add_development_dependency 'rubocop'
40
+ spec.add_development_dependency 'rubocop-minitest'
41
+ spec.add_development_dependency 'rubocop-rake'
42
+ spec.add_development_dependency 'webmock'
43
+
44
+ spec.add_dependency 'io-console'
45
+ spec.add_dependency 'thor'
46
+ end
metadata ADDED
@@ -0,0 +1,284 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: uffizzi-cli
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Josh Thurman
8
+ - Grayson Adkins
9
+ autorequire:
10
+ bindir: exe
11
+ cert_chain: []
12
+ date: 2022-02-24 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: bundler
16
+ requirement: !ruby/object:Gem::Requirement
17
+ requirements:
18
+ - - "~>"
19
+ - !ruby/object:Gem::Version
20
+ version: '2.2'
21
+ type: :development
22
+ prerelease: false
23
+ version_requirements: !ruby/object:Gem::Requirement
24
+ requirements:
25
+ - - "~>"
26
+ - !ruby/object:Gem::Version
27
+ version: '2.2'
28
+ - !ruby/object:Gem::Dependency
29
+ name: byebug
30
+ requirement: !ruby/object:Gem::Requirement
31
+ requirements:
32
+ - - ">="
33
+ - !ruby/object:Gem::Version
34
+ version: '0'
35
+ type: :development
36
+ prerelease: false
37
+ version_requirements: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ - !ruby/object:Gem::Dependency
43
+ name: factory_bot
44
+ requirement: !ruby/object:Gem::Requirement
45
+ requirements:
46
+ - - ">="
47
+ - !ruby/object:Gem::Version
48
+ version: '0'
49
+ type: :development
50
+ prerelease: false
51
+ version_requirements: !ruby/object:Gem::Requirement
52
+ requirements:
53
+ - - ">="
54
+ - !ruby/object:Gem::Version
55
+ version: '0'
56
+ - !ruby/object:Gem::Dependency
57
+ name: minitest
58
+ requirement: !ruby/object:Gem::Requirement
59
+ requirements:
60
+ - - ">="
61
+ - !ruby/object:Gem::Version
62
+ version: '0'
63
+ type: :development
64
+ prerelease: false
65
+ version_requirements: !ruby/object:Gem::Requirement
66
+ requirements:
67
+ - - ">="
68
+ - !ruby/object:Gem::Version
69
+ version: '0'
70
+ - !ruby/object:Gem::Dependency
71
+ name: minitest-power_assert
72
+ requirement: !ruby/object:Gem::Requirement
73
+ requirements:
74
+ - - ">="
75
+ - !ruby/object:Gem::Version
76
+ version: '0'
77
+ type: :development
78
+ prerelease: false
79
+ version_requirements: !ruby/object:Gem::Requirement
80
+ requirements:
81
+ - - ">="
82
+ - !ruby/object:Gem::Version
83
+ version: '0'
84
+ - !ruby/object:Gem::Dependency
85
+ name: mocha
86
+ requirement: !ruby/object:Gem::Requirement
87
+ requirements:
88
+ - - ">="
89
+ - !ruby/object:Gem::Version
90
+ version: '0'
91
+ type: :development
92
+ prerelease: false
93
+ version_requirements: !ruby/object:Gem::Requirement
94
+ requirements:
95
+ - - ">="
96
+ - !ruby/object:Gem::Version
97
+ version: '0'
98
+ - !ruby/object:Gem::Dependency
99
+ name: pry-byebug
100
+ requirement: !ruby/object:Gem::Requirement
101
+ requirements:
102
+ - - ">="
103
+ - !ruby/object:Gem::Version
104
+ version: '0'
105
+ type: :development
106
+ prerelease: false
107
+ version_requirements: !ruby/object:Gem::Requirement
108
+ requirements:
109
+ - - ">="
110
+ - !ruby/object:Gem::Version
111
+ version: '0'
112
+ - !ruby/object:Gem::Dependency
113
+ name: pry-inline
114
+ requirement: !ruby/object:Gem::Requirement
115
+ requirements:
116
+ - - ">="
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
119
+ type: :development
120
+ prerelease: false
121
+ version_requirements: !ruby/object:Gem::Requirement
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
+ requirements:
130
+ - - ">="
131
+ - !ruby/object:Gem::Version
132
+ version: '0'
133
+ type: :development
134
+ prerelease: false
135
+ version_requirements: !ruby/object:Gem::Requirement
136
+ requirements:
137
+ - - ">="
138
+ - !ruby/object:Gem::Version
139
+ version: '0'
140
+ - !ruby/object:Gem::Dependency
141
+ name: rubocop
142
+ requirement: !ruby/object:Gem::Requirement
143
+ requirements:
144
+ - - ">="
145
+ - !ruby/object:Gem::Version
146
+ version: '0'
147
+ type: :development
148
+ prerelease: false
149
+ version_requirements: !ruby/object:Gem::Requirement
150
+ requirements:
151
+ - - ">="
152
+ - !ruby/object:Gem::Version
153
+ version: '0'
154
+ - !ruby/object:Gem::Dependency
155
+ name: rubocop-minitest
156
+ requirement: !ruby/object:Gem::Requirement
157
+ requirements:
158
+ - - ">="
159
+ - !ruby/object:Gem::Version
160
+ version: '0'
161
+ type: :development
162
+ prerelease: false
163
+ version_requirements: !ruby/object:Gem::Requirement
164
+ requirements:
165
+ - - ">="
166
+ - !ruby/object:Gem::Version
167
+ version: '0'
168
+ - !ruby/object:Gem::Dependency
169
+ name: rubocop-rake
170
+ requirement: !ruby/object:Gem::Requirement
171
+ requirements:
172
+ - - ">="
173
+ - !ruby/object:Gem::Version
174
+ version: '0'
175
+ type: :development
176
+ prerelease: false
177
+ version_requirements: !ruby/object:Gem::Requirement
178
+ requirements:
179
+ - - ">="
180
+ - !ruby/object:Gem::Version
181
+ version: '0'
182
+ - !ruby/object:Gem::Dependency
183
+ name: webmock
184
+ requirement: !ruby/object:Gem::Requirement
185
+ requirements:
186
+ - - ">="
187
+ - !ruby/object:Gem::Version
188
+ version: '0'
189
+ type: :development
190
+ prerelease: false
191
+ version_requirements: !ruby/object:Gem::Requirement
192
+ requirements:
193
+ - - ">="
194
+ - !ruby/object:Gem::Version
195
+ version: '0'
196
+ - !ruby/object:Gem::Dependency
197
+ name: io-console
198
+ requirement: !ruby/object:Gem::Requirement
199
+ requirements:
200
+ - - ">="
201
+ - !ruby/object:Gem::Version
202
+ version: '0'
203
+ type: :runtime
204
+ prerelease: false
205
+ version_requirements: !ruby/object:Gem::Requirement
206
+ requirements:
207
+ - - ">="
208
+ - !ruby/object:Gem::Version
209
+ version: '0'
210
+ - !ruby/object:Gem::Dependency
211
+ name: thor
212
+ requirement: !ruby/object:Gem::Requirement
213
+ requirements:
214
+ - - ">="
215
+ - !ruby/object:Gem::Version
216
+ version: '0'
217
+ type: :runtime
218
+ prerelease: false
219
+ version_requirements: !ruby/object:Gem::Requirement
220
+ requirements:
221
+ - - ">="
222
+ - !ruby/object:Gem::Version
223
+ version: '0'
224
+ description: uffizzi-cli
225
+ email:
226
+ - info@uffizzi.com
227
+ executables:
228
+ - uffizzi
229
+ extensions: []
230
+ extra_rdoc_files: []
231
+ files:
232
+ - ".rubocop.yml"
233
+ - CHANGELOG.md
234
+ - CONTRIBUTING.md
235
+ - Dockerfile
236
+ - Gemfile
237
+ - Gemfile.lock
238
+ - LICENSE
239
+ - README.md
240
+ - Rakefile
241
+ - bin/console
242
+ - bin/setup
243
+ - config/uffizzi.rb
244
+ - docker-compose.yml
245
+ - exe/uffizzi
246
+ - lib/uffizzi.rb
247
+ - lib/uffizzi/auth_helper.rb
248
+ - lib/uffizzi/cli.rb
249
+ - lib/uffizzi/cli/config.rb
250
+ - lib/uffizzi/cli/login.rb
251
+ - lib/uffizzi/cli/projects.rb
252
+ - lib/uffizzi/clients/api/api_client.rb
253
+ - lib/uffizzi/clients/api/api_routes.rb
254
+ - lib/uffizzi/clients/api/http_client.rb
255
+ - lib/uffizzi/config_file.rb
256
+ - lib/uffizzi/version.rb
257
+ - uffizzi.gemspec
258
+ homepage: https://uffizzi.com
259
+ licenses:
260
+ - Apache-2.0
261
+ metadata:
262
+ homepage_uri: https://uffizzi.com
263
+ source_code_uri: https://github.com/UffizziCloud/uffizzi_cli
264
+ changelog_uri: https://github.com/UffizziCloud/uffizzi_cli/blob/master/CHANGELOG.md
265
+ post_install_message:
266
+ rdoc_options: []
267
+ require_paths:
268
+ - lib
269
+ required_ruby_version: !ruby/object:Gem::Requirement
270
+ requirements:
271
+ - - ">="
272
+ - !ruby/object:Gem::Version
273
+ version: 2.5.0
274
+ required_rubygems_version: !ruby/object:Gem::Requirement
275
+ requirements:
276
+ - - ">="
277
+ - !ruby/object:Gem::Version
278
+ version: '0'
279
+ requirements: []
280
+ rubygems_version: 3.2.22
281
+ signing_key:
282
+ specification_version: 4
283
+ summary: uffizzi-cli
284
+ test_files: []