aikido-ruby-client 0.0.1 → 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 +4 -4
- data/.rspec +1 -0
- data/.rubocop.yml +5 -0
- data/CHANGELOG.md +14 -0
- data/exe/aikido +7 -1
- data/lib/aikido/client.rb +87 -9
- data/lib/aikido/context.rb +28 -0
- data/lib/aikido/errors.rb +30 -0
- data/lib/aikido/paginated_response.rb +31 -0
- data/lib/aikido/version.rb +1 -1
- data/lib/aikido-ruby-client.rb +1 -0
- metadata +6 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6692ba6b0f697d0f69b840a95e96cbbca656863ed9c71af7c48fc2634678a659
|
4
|
+
data.tar.gz: 9997f0daca4a3e133a3d5e3c041f8ddf66bd6af56521d18d6c8bfbffbc323b40
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5597d2ddd0e6a518a078e6fa6d2b55e3c01a022ffadbb018fe76423f761f9c4381a4dc06bc647866b8bea5ea21cdb8230811c0e71cc60f9ef46e78ed2d4057c3
|
7
|
+
data.tar.gz: d1659f8a75fe77dbd4e60f8b74884b3354458c520482531b49d7b10e014ca1ccbbc8958743686814a5bc075ecbf03b176bb321055df6bc12145651e6aa5dae40
|
data/.rspec
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
--require spec_helper
|
data/.rubocop.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,5 +1,19 @@
|
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+
## [v0.0.3](https://github.com/anakinj/aikido-ruby-client/tree/v0.0.3) (2024-03-10)
|
4
|
+
|
5
|
+
**Features:**
|
6
|
+
|
7
|
+
- Support for even more endpoints
|
8
|
+
|
9
|
+
## [v0.0.2](https://github.com/anakinj/aikido-ruby-client/tree/v0.0.2) (2024-03-10)
|
10
|
+
|
11
|
+
**Features:**
|
12
|
+
|
13
|
+
- More api methods
|
14
|
+
- Pagination support
|
15
|
+
- Specs backed by VCR recordings
|
16
|
+
|
3
17
|
## [v0.0.1](https://github.com/anakinj/aikido-ruby-client/tree/v0.0.1) (2024-03-10)
|
4
18
|
|
5
19
|
**Features:**
|
data/exe/aikido
CHANGED
data/lib/aikido/client.rb
CHANGED
@@ -2,35 +2,93 @@
|
|
2
2
|
|
3
3
|
require 'httpx'
|
4
4
|
|
5
|
+
require_relative 'errors'
|
6
|
+
require_relative 'paginated_response'
|
7
|
+
|
5
8
|
module Aikido
|
6
9
|
# HTTP Client to interact with the Aikido API
|
7
10
|
# Official documentation: https://apidocs.aikido.dev/
|
8
11
|
class Client
|
9
12
|
def initialize(client_id: nil, client_secret: nil)
|
10
|
-
@client_id
|
13
|
+
@client_id = client_id || ENV.fetch('AIKIDO_CLIENT_ID', nil)
|
11
14
|
@client_secret = client_secret || ENV.fetch('AIKIDO_CLIENT_SECRET', nil)
|
12
15
|
end
|
13
16
|
|
14
17
|
def authorize
|
15
|
-
http.plugin(:basic_auth)
|
16
|
-
|
18
|
+
handle_response!(http.plugin(:basic_auth)
|
19
|
+
.basic_auth(@client_id, @client_secret)
|
20
|
+
.post('/oauth/token', json: { grant_type: 'client_credentials' }))
|
21
|
+
end
|
22
|
+
|
23
|
+
def workspace
|
24
|
+
get('/public/v1/workspace').json
|
25
|
+
end
|
26
|
+
|
27
|
+
def clouds
|
28
|
+
PaginatedResponse.new do |page|
|
29
|
+
get('/public/v1/clouds', params: { page: page }).json
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
def connect_aws_cloud(role_arn:, name:, environment:)
|
34
|
+
handle_response!(authed_http.post('/public/v1/clouds/aws',
|
35
|
+
json: { role_arn: role_arn,
|
36
|
+
name: name,
|
37
|
+
environment: environment })).json
|
17
38
|
end
|
18
39
|
|
19
|
-
def issues(
|
20
|
-
|
40
|
+
def issues(options = {})
|
41
|
+
get('/public/v1/issues/export', params: options).json
|
21
42
|
end
|
22
43
|
|
23
44
|
def issue(id)
|
24
|
-
|
45
|
+
get("/public/v1/issues/#{id.to_i}").json
|
25
46
|
end
|
26
47
|
|
27
|
-
def
|
28
|
-
|
29
|
-
|
48
|
+
def issue_groups
|
49
|
+
PaginatedResponse.new do |page|
|
50
|
+
get('/public/v1/open-issue-groups', params: { page: page }).json
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
def issue_group(id)
|
55
|
+
get("/public/v1/issues/groups/#{id.to_i}").json
|
56
|
+
end
|
57
|
+
|
58
|
+
def code_repositories
|
59
|
+
PaginatedResponse.new do |page|
|
60
|
+
get('/public/v1/repositories/code', params: { page: page }).json
|
61
|
+
end
|
62
|
+
end
|
63
|
+
|
64
|
+
def code_repository_sbom(id, format: 'csv')
|
65
|
+
get("/public/v1/repositories/code/#{id.to_i}/licenses/export", params: { format: format }).read
|
66
|
+
end
|
67
|
+
|
68
|
+
def teams
|
69
|
+
PaginatedResponse.new do |page|
|
70
|
+
get('/public/v1/teams', params: { page: page }).json
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def create_team(name:)
|
75
|
+
handle_response!(authed_http.post('/public/v1/teams', json: { name: name })).json
|
76
|
+
end
|
77
|
+
|
78
|
+
def update_team(id)
|
79
|
+
raise NotImplementedError
|
80
|
+
end
|
81
|
+
|
82
|
+
def containers
|
83
|
+
get('/public/v1/containers').json
|
30
84
|
end
|
31
85
|
|
32
86
|
private
|
33
87
|
|
88
|
+
def get(path, params: {})
|
89
|
+
handle_response!(authed_http.get(path, params: params))
|
90
|
+
end
|
91
|
+
|
34
92
|
def authed_http
|
35
93
|
http.plugin(:auth).bearer_auth(auth_token)
|
36
94
|
end
|
@@ -47,5 +105,25 @@ module Aikido
|
|
47
105
|
# TODO: Handle token expiration
|
48
106
|
@auth_token ||= authorize.json['access_token']
|
49
107
|
end
|
108
|
+
|
109
|
+
def handle_response!(response)
|
110
|
+
case response.status
|
111
|
+
when 200..299
|
112
|
+
response
|
113
|
+
else
|
114
|
+
raise_response_error!(response)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
|
118
|
+
def raise_response_error!(response)
|
119
|
+
case response.status
|
120
|
+
when 400
|
121
|
+
raise Errors::BadRequestError, response
|
122
|
+
when 401
|
123
|
+
raise Errors::UnauthorizedError, response
|
124
|
+
else
|
125
|
+
raise Errors::ApiError, response
|
126
|
+
end
|
127
|
+
end
|
50
128
|
end
|
51
129
|
end
|
@@ -0,0 +1,28 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Aikido
|
4
|
+
# Represents a context for interacting with the Aikido API
|
5
|
+
# Context will store data in memory for further processing
|
6
|
+
class Context
|
7
|
+
def initialize(client: nil)
|
8
|
+
@client = client || Aikido::Client.new
|
9
|
+
end
|
10
|
+
|
11
|
+
def issues_for_code_repository(external_repo_id:)
|
12
|
+
repo = code_repositories.find { |r| r['external_repo_id'] == external_repo_id }
|
13
|
+
return [] unless repo
|
14
|
+
|
15
|
+
issues.select do |issue|
|
16
|
+
issue['code_repo_id'] == repo['id']
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def code_repositories
|
21
|
+
@code_repositories ||= @client.code_repositories
|
22
|
+
end
|
23
|
+
|
24
|
+
def issues
|
25
|
+
@issues ||= @client.issues
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
@@ -0,0 +1,30 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Aikido
|
4
|
+
module Errors
|
5
|
+
AikidoError = Class.new(StandardError)
|
6
|
+
|
7
|
+
# Represents an error that occurred while making an API request.
|
8
|
+
class ApiError < AikidoError
|
9
|
+
def initialize(response)
|
10
|
+
@response = response
|
11
|
+
super("API Error: #{response.status}")
|
12
|
+
end
|
13
|
+
|
14
|
+
def message
|
15
|
+
json = @response.json
|
16
|
+
if json.key?('error_description')
|
17
|
+
"#{super} - #{json['error_description']}"
|
18
|
+
elsif json.key?('reason_phrase')
|
19
|
+
"#{super} - #{json['reason_phrase']}"
|
20
|
+
else
|
21
|
+
super
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
|
26
|
+
BadRequestError = Class.new(ApiError)
|
27
|
+
UnauthorizedError = Class.new(ApiError)
|
28
|
+
NotFoundError = Class.new(ApiError)
|
29
|
+
end
|
30
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Aikido
|
4
|
+
# Represents a reponse that is paginated
|
5
|
+
class PaginatedResponse
|
6
|
+
include Enumerable
|
7
|
+
|
8
|
+
def initialize(&block)
|
9
|
+
@page_loader = block
|
10
|
+
@pages = []
|
11
|
+
load_page(0)
|
12
|
+
end
|
13
|
+
|
14
|
+
def each(&block)
|
15
|
+
return enum_for(:each) unless block_given?
|
16
|
+
|
17
|
+
loop.with_index do |_, index|
|
18
|
+
page = load_page(index)
|
19
|
+
break if page.empty?
|
20
|
+
|
21
|
+
page.each(&block)
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
private
|
26
|
+
|
27
|
+
def load_page(page)
|
28
|
+
@pages[page] ||= @page_loader.call(page)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/lib/aikido/version.rb
CHANGED
data/lib/aikido-ruby-client.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: aikido-ruby-client
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0.
|
4
|
+
version: 0.0.3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Joakim Antman
|
@@ -32,6 +32,7 @@ executables:
|
|
32
32
|
extensions: []
|
33
33
|
extra_rdoc_files: []
|
34
34
|
files:
|
35
|
+
- ".rspec"
|
35
36
|
- ".rubocop.yml"
|
36
37
|
- CHANGELOG.md
|
37
38
|
- LICENSE.txt
|
@@ -40,6 +41,9 @@ files:
|
|
40
41
|
- exe/aikido
|
41
42
|
- lib/aikido-ruby-client.rb
|
42
43
|
- lib/aikido/client.rb
|
44
|
+
- lib/aikido/context.rb
|
45
|
+
- lib/aikido/errors.rb
|
46
|
+
- lib/aikido/paginated_response.rb
|
43
47
|
- lib/aikido/version.rb
|
44
48
|
homepage: https://github.com/anakinj/aikido-ruby-client
|
45
49
|
licenses:
|
@@ -47,7 +51,7 @@ licenses:
|
|
47
51
|
metadata:
|
48
52
|
homepage_uri: https://github.com/anakinj/aikido-ruby-client
|
49
53
|
source_code_uri: https://github.com/anakinj
|
50
|
-
changelog_uri: https://github.com/anakinj/jwk-loader/blob/0.0.
|
54
|
+
changelog_uri: https://github.com/anakinj/jwk-loader/blob/0.0.3/CHANGELOG.md
|
51
55
|
rubygems_mfa_required: 'true'
|
52
56
|
post_install_message:
|
53
57
|
rdoc_options: []
|