gojira_apiops 0.1.0
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 +7 -0
- data/.github/workflows/main.yml +59 -0
- data/.gitignore +14 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/Dockerfile +13 -0
- data/Gemfile +8 -0
- data/Gemfile.lock +75 -0
- data/README.md +116 -0
- data/Rakefile +8 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/docs/gojira.png +0 -0
- data/exe/gojira +20 -0
- data/gojira.gemspec +47 -0
- data/lib/gojira/apiops/merge.rb +20 -0
- data/lib/gojira/apiops/validations.rb +54 -0
- data/lib/gojira/cli.rb +33 -0
- data/lib/gojira/command/base.rb +15 -0
- data/lib/gojira/command/cluster.rb +91 -0
- data/lib/gojira/command/env.rb +38 -0
- data/lib/gojira/deck/base.rb +41 -0
- data/lib/gojira/deck/file.rb +31 -0
- data/lib/gojira/deck/gateway.rb +31 -0
- data/lib/gojira/errors.rb +25 -0
- data/lib/gojira/version.rb +5 -0
- data/lib/gojira.rb +26 -0
- data/rubocop.yml +0 -0
- metadata +174 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA256:
|
3
|
+
metadata.gz: b6ec417813d73cf612a22ad5686c54994bb64174adeb82250766b47e9e2d9f93
|
4
|
+
data.tar.gz: 79a616a00c33bfce5cf97adeabeafeb093094976cb1d80ccdb54bd17ea2c98cc
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 06e7ad585f278c500bfe88898bb69513c53d74437234e52ce3a4ca4b200c954b2f2da840bdabb486b0684909490e8d00afeda40e06e80fb27627cb69f956910b
|
7
|
+
data.tar.gz: 68eafc086dfe33681ee0b3d759c32615e64471dabe52beae44ffa57eef4541405ea2e0f092da0a1bdeeb3b3873c37f391e38a44bb4a9f8cc419be2f3f01cc030
|
@@ -0,0 +1,59 @@
|
|
1
|
+
name: Gojira Pipeline
|
2
|
+
|
3
|
+
on:
|
4
|
+
push:
|
5
|
+
branches:
|
6
|
+
- main
|
7
|
+
pull_request:
|
8
|
+
branches:
|
9
|
+
- main
|
10
|
+
|
11
|
+
jobs:
|
12
|
+
test:
|
13
|
+
runs-on: ubuntu-latest
|
14
|
+
|
15
|
+
steps:
|
16
|
+
- uses: actions/checkout@v4
|
17
|
+
- uses: ruby/setup-ruby
|
18
|
+
with:
|
19
|
+
ruby-version: '3.3.1'
|
20
|
+
- run: bundle install
|
21
|
+
- run: bundle exec rspec
|
22
|
+
|
23
|
+
build:
|
24
|
+
name: Build + Publish
|
25
|
+
runs-on: ubuntu-latest
|
26
|
+
permissions:
|
27
|
+
packages: write
|
28
|
+
contents: read
|
29
|
+
|
30
|
+
steps:
|
31
|
+
- uses: actions/checkout@v4
|
32
|
+
- name: Set up Ruby 3.3.1
|
33
|
+
uses: ruby/setup-ruby
|
34
|
+
with:
|
35
|
+
ruby-version: '3.3.1'
|
36
|
+
- run: bundle install
|
37
|
+
|
38
|
+
- name: Publish to GPR
|
39
|
+
run: |
|
40
|
+
mkdir -p $HOME/.gem
|
41
|
+
touch $HOME/.gem/credentials
|
42
|
+
chmod 0600 $HOME/.gem/credentials
|
43
|
+
printf -- "---\n:github: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
44
|
+
gem build *.gemspec
|
45
|
+
gem push --KEY github --host https://rubygems.pkg.github.com/${OWNER} *.gem
|
46
|
+
env:
|
47
|
+
GEM_HOST_API_KEY: "Bearer ${{secrets.GITHUB_TOKEN}}"
|
48
|
+
OWNER: ${{ github.repository_owner }}
|
49
|
+
|
50
|
+
- name: Publish to RubyGems
|
51
|
+
run: |
|
52
|
+
mkdir -p $HOME/.gem
|
53
|
+
touch $HOME/.gem/credentials
|
54
|
+
chmod 0600 $HOME/.gem/credentials
|
55
|
+
printf -- "---\n:rubygems_api_key: ${GEM_HOST_API_KEY}\n" > $HOME/.gem/credentials
|
56
|
+
gem build *.gemspec
|
57
|
+
gem push *.gem
|
58
|
+
env:
|
59
|
+
GEM_HOST_API_KEY: "${{secrets.RUBYGEMS_AUTH_TOKEN}}"
|
data/.gitignore
ADDED
data/.rspec
ADDED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
3.3.1
|
data/Dockerfile
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
FROM ruby:3.3.1
|
2
|
+
|
3
|
+
RUN curl -sL https://github.com/Kong/deck/releases/download/v1.39.4/deck_1.39.4_linux_arm64.tar.gz -o deck.tar.gz
|
4
|
+
RUN tar -xf deck.tar.gz -C /tmp
|
5
|
+
RUN cp /tmp/deck /usr/local/bin/
|
6
|
+
|
7
|
+
COPY . /app
|
8
|
+
|
9
|
+
WORKDIR /app
|
10
|
+
|
11
|
+
RUN bundle install
|
12
|
+
RUN gem build gojira.gemspec
|
13
|
+
RUN gem install *.gem
|
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
PATH
|
2
|
+
remote: .
|
3
|
+
specs:
|
4
|
+
gojira (0.1.0)
|
5
|
+
|
6
|
+
GEM
|
7
|
+
remote: https://rubygems.org/
|
8
|
+
specs:
|
9
|
+
ast (2.4.2)
|
10
|
+
coderay (1.1.3)
|
11
|
+
diff-lcs (1.5.1)
|
12
|
+
json (2.7.2)
|
13
|
+
language_server-protocol (3.17.0.3)
|
14
|
+
method_source (1.1.0)
|
15
|
+
parallel (1.25.1)
|
16
|
+
parser (3.3.3.0)
|
17
|
+
ast (~> 2.4.1)
|
18
|
+
racc
|
19
|
+
pry (0.14.2)
|
20
|
+
coderay (~> 1.1)
|
21
|
+
method_source (~> 1.0)
|
22
|
+
racc (1.8.0)
|
23
|
+
rainbow (3.1.1)
|
24
|
+
rake (10.5.0)
|
25
|
+
regexp_parser (2.9.2)
|
26
|
+
rexml (3.3.0)
|
27
|
+
strscan
|
28
|
+
rspec (3.13.0)
|
29
|
+
rspec-core (~> 3.13.0)
|
30
|
+
rspec-expectations (~> 3.13.0)
|
31
|
+
rspec-mocks (~> 3.13.0)
|
32
|
+
rspec-core (3.13.0)
|
33
|
+
rspec-support (~> 3.13.0)
|
34
|
+
rspec-expectations (3.13.1)
|
35
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
36
|
+
rspec-support (~> 3.13.0)
|
37
|
+
rspec-mocks (3.13.1)
|
38
|
+
diff-lcs (>= 1.2.0, < 2.0)
|
39
|
+
rspec-support (~> 3.13.0)
|
40
|
+
rspec-support (3.13.1)
|
41
|
+
rubocop (1.64.1)
|
42
|
+
json (~> 2.3)
|
43
|
+
language_server-protocol (>= 3.17.0)
|
44
|
+
parallel (~> 1.10)
|
45
|
+
parser (>= 3.3.0.2)
|
46
|
+
rainbow (>= 2.2.2, < 4.0)
|
47
|
+
regexp_parser (>= 1.8, < 3.0)
|
48
|
+
rexml (>= 3.2.5, < 4.0)
|
49
|
+
rubocop-ast (>= 1.31.1, < 2.0)
|
50
|
+
ruby-progressbar (~> 1.7)
|
51
|
+
unicode-display_width (>= 2.4.0, < 3.0)
|
52
|
+
rubocop-ast (1.31.3)
|
53
|
+
parser (>= 3.3.1.0)
|
54
|
+
ruby-progressbar (1.13.0)
|
55
|
+
strscan (3.1.0)
|
56
|
+
thor (1.3.1)
|
57
|
+
unicode-display_width (2.5.0)
|
58
|
+
yaml (0.3.0)
|
59
|
+
|
60
|
+
PLATFORMS
|
61
|
+
arm64-darwin-23
|
62
|
+
ruby
|
63
|
+
|
64
|
+
DEPENDENCIES
|
65
|
+
bundler (~> 2.5)
|
66
|
+
gojira!
|
67
|
+
pry
|
68
|
+
rake (~> 10.0)
|
69
|
+
rspec (~> 3.0)
|
70
|
+
rubocop (~> 1.64)
|
71
|
+
thor (~> 1.3.1)
|
72
|
+
yaml
|
73
|
+
|
74
|
+
BUNDLED WITH
|
75
|
+
2.5.9
|
data/README.md
ADDED
@@ -0,0 +1,116 @@
|
|
1
|
+
# Gojira
|
2
|
+
|
3
|
+
**Maintaining order within the Kong realm** [[ref](https://en.wikipedia.org/wiki/Gojira)]
|
4
|
+
|
5
|
+
<img src="docs/gojira.png" alt="drawing" width="500"/>
|
6
|
+
|
7
|
+
## Documentation
|
8
|
+
|
9
|
+
This post on my blog was the starting point of it all: [Gojira: Building Multi-Region APIOps with Kong](https://www.kumarabhijeet.me/building-multi-region-kong-apiops)
|
10
|
+
|
11
|
+
More detailed docs about the conventions of the framework are yet to follow.
|
12
|
+
|
13
|
+
## Installation
|
14
|
+
|
15
|
+
Add this line to your application's Gemfile:
|
16
|
+
|
17
|
+
```ruby
|
18
|
+
gem 'gojira'
|
19
|
+
```
|
20
|
+
|
21
|
+
And then execute:
|
22
|
+
|
23
|
+
$ bundle
|
24
|
+
|
25
|
+
Or install it yourself as:
|
26
|
+
|
27
|
+
$ gem install gojira
|
28
|
+
|
29
|
+
## Usage
|
30
|
+
|
31
|
+
### Top-Level Commands
|
32
|
+
```
|
33
|
+
commands:
|
34
|
+
gojira cluster # Commands interacting with Kong cluster
|
35
|
+
gojira env # Commands interacting with Gateway env directory
|
36
|
+
gojira help [COMMAND] # Describe available commands or one specific command
|
37
|
+
gojira version # Print Gojira gem version
|
38
|
+
|
39
|
+
Options:
|
40
|
+
[--kong-addr=KONG_ADDR] # Kong Host & Port
|
41
|
+
[--config=CONFIG] # decK config file
|
42
|
+
[--ca-cert-file=CA_CERT_FILE] # CA Cert File
|
43
|
+
[--tls-client-key-file=TLS_CLIENT_KEY_FILE] # TLS Client Key file
|
44
|
+
[--tls-client-cert-file=TLS_CLIENT_CERT_FILE] # TLS Client Cert file
|
45
|
+
[--tls-server-name=TLS_SERVER_NAME] # TLS Server Name
|
46
|
+
```
|
47
|
+
|
48
|
+
### Cluster commands
|
49
|
+
|
50
|
+
These commands are used to interact with the Kong Control Plane
|
51
|
+
|
52
|
+
```
|
53
|
+
Commands:
|
54
|
+
gojira cluster diff # diff output for kong config in a cluster
|
55
|
+
gojira cluster dump # takes dump of resources from a kong cluster
|
56
|
+
gojira cluster help [COMMAND] # Describe subcommands or one specific subcommand
|
57
|
+
gojira cluster sync # syncs kong config to a cluster
|
58
|
+
gojira cluster validate # validates kong config for a cluster
|
59
|
+
|
60
|
+
```
|
61
|
+
|
62
|
+
```
|
63
|
+
Usage:
|
64
|
+
gojira cluster sync
|
65
|
+
|
66
|
+
Options:
|
67
|
+
-s, [--kong-state-file=KONG_STATE_FILE] # Kong State File
|
68
|
+
-n, [--env-name=ENV_NAME] # Environment identifier name
|
69
|
+
-c, [--compliance-type=COMPLIANCE_TYPE] # Compliance Type
|
70
|
+
# Possible values: pci, non-pci
|
71
|
+
-f, [--cluster-file=CLUSTER_FILE] # Cluster file path
|
72
|
+
-d, [--dc-name=DC_NAME] # DC Name
|
73
|
+
|
74
|
+
syncs kong config to a cluster
|
75
|
+
```
|
76
|
+
|
77
|
+
### Env Commands
|
78
|
+
|
79
|
+
These commands are used to lint and generate configurations based on environments and tags defined a/c Gojira's opinionated conventions
|
80
|
+
|
81
|
+
```
|
82
|
+
Commands:
|
83
|
+
gojira env generate # generates kong state for the env repo
|
84
|
+
gojira env help [COMMAND] # Describe subcommands or one specific subcommand
|
85
|
+
gojira env lint # lints env repo and validates against conventions
|
86
|
+
```
|
87
|
+
|
88
|
+
```
|
89
|
+
Usage:
|
90
|
+
gojira env generate
|
91
|
+
|
92
|
+
Options:
|
93
|
+
-f, [--gateway-folder=GATEWAY_FOLDER] # Gateway configs folder path
|
94
|
+
-n, [--env-name=ENV_NAME] # Environment identifier name
|
95
|
+
-f, [--cluster-file=CLUSTER_FILE] # Path to Cluster definition file
|
96
|
+
-c, [--compliance-type=COMPLIANCE_TYPE] # Compliance Type(pci/non-pci)
|
97
|
+
-d, [--dc-name=DC_NAME] # DC Name
|
98
|
+
|
99
|
+
generates kong state for the env repo
|
100
|
+
```
|
101
|
+
|
102
|
+
### TODO:
|
103
|
+
|
104
|
+
* Lint:
|
105
|
+
* Searches through env directory
|
106
|
+
* get list of all products/services
|
107
|
+
* checks if their upstream info is available across all clusters of that env
|
108
|
+
* service level validations(PCI/NPCI service tags, no route with tags)
|
109
|
+
* Gives out errors of each validation level in JSON
|
110
|
+
|
111
|
+
* Generate:
|
112
|
+
* Merge product services files into one config
|
113
|
+
* Substitute kong upstreams for respective compliance type and DC
|
114
|
+
* Merge all product configs into one file
|
115
|
+
* Not to interfere and merge global conf and certs, they will be passed with -s
|
116
|
+
* Can include local config here later
|
data/Rakefile
ADDED
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
require 'bundler/setup'
|
5
|
+
require 'gojira'
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
# require "pry"
|
12
|
+
# Pry.start
|
13
|
+
|
14
|
+
require 'irb'
|
15
|
+
IRB.start(__FILE__)
|
data/bin/setup
ADDED
data/docs/gojira.png
ADDED
Binary file
|
data/exe/gojira
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# frozen_string_literal: true
|
3
|
+
|
4
|
+
lib_path = File.expand_path('../lib', __dir__)
|
5
|
+
$LOAD_PATH.unshift(lib_path) unless $LOAD_PATH.include?(lib_path)
|
6
|
+
|
7
|
+
begin
|
8
|
+
require 'pry-byebug' if ENV['GOJIRA_ENV'] == 'debug'
|
9
|
+
rescue LoadError
|
10
|
+
# do nothing
|
11
|
+
end
|
12
|
+
|
13
|
+
require 'gojira'
|
14
|
+
|
15
|
+
Signal.trap('INT') do
|
16
|
+
warn("\n#{caller.join("\n")}: interrupted")
|
17
|
+
exit(1)
|
18
|
+
end
|
19
|
+
|
20
|
+
Gojira::CLI.start(ARGV)
|
data/gojira.gemspec
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
lib = File.expand_path('lib', __dir__)
|
4
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
5
|
+
require 'gojira/version'
|
6
|
+
|
7
|
+
Gem::Specification.new do |spec|
|
8
|
+
spec.name = 'gojira_apiops'
|
9
|
+
spec.version = Gojira::VERSION
|
10
|
+
spec.authors = ['Kumar Abhijeet']
|
11
|
+
spec.email = ['kumarabhijeet1202@gmail.com']
|
12
|
+
|
13
|
+
spec.summary = 'A ruby gem to generate Kong configs across multiple clusters to achieve service equivalence'
|
14
|
+
spec.description = 'A ruby gem to generate Kong configs across multiple clusters to achieve service equivalence'
|
15
|
+
spec.homepage = 'https://github.com/kumar1202/gojira/tree/main'
|
16
|
+
|
17
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
18
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
19
|
+
if spec.respond_to?(:metadata)
|
20
|
+
spec.metadata['allowed_push_host'] = "https://rubygems.org"
|
21
|
+
|
22
|
+
spec.metadata['homepage_uri'] = spec.homepage
|
23
|
+
spec.metadata['source_code_uri'] = 'https://github.com/kumar1202/gojira/tree/main'
|
24
|
+
spec.metadata['changelog_uri'] = 'https://github.com/kumar1202/gojira/tree/main'
|
25
|
+
else
|
26
|
+
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
27
|
+
'public gem pushes.'
|
28
|
+
end
|
29
|
+
|
30
|
+
# Specify which files should be added to the gem when it is released.
|
31
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
32
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
33
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
34
|
+
end
|
35
|
+
spec.bindir = 'exe'
|
36
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
37
|
+
spec.require_paths = ['lib']
|
38
|
+
|
39
|
+
spec.add_development_dependency 'bundler', '~> 2.5'
|
40
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
41
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
42
|
+
spec.add_development_dependency 'rubocop', '~> 1.64'
|
43
|
+
spec.add_development_dependency 'thor', '~> 1.3.1'
|
44
|
+
spec.add_development_dependency 'yaml'
|
45
|
+
|
46
|
+
spec.add_development_dependency 'pry'
|
47
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gojira
|
4
|
+
module APIOps
|
5
|
+
class Merge
|
6
|
+
attr_accessor :errors
|
7
|
+
attr_reader :gateway_folder, :env_dir, :cluster_file
|
8
|
+
|
9
|
+
def initialize
|
10
|
+
@gateway_folder = gateway_folder
|
11
|
+
@env_dir = env_dir
|
12
|
+
@cluster_file = cluster_file
|
13
|
+
@errors = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
20
|
+
end
|
@@ -0,0 +1,54 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gojira
|
4
|
+
module APIOps
|
5
|
+
class Validations
|
6
|
+
attr_accessor :errors
|
7
|
+
attr_reader :gateway_folder, :env_dir, :cluster_file
|
8
|
+
|
9
|
+
def initialize(gateway_folder, env_dir, cluster_file)
|
10
|
+
@gateway_folder = gateway_folder
|
11
|
+
@env_dir = env_dir
|
12
|
+
@cluster_file = cluster_file
|
13
|
+
@errors = []
|
14
|
+
end
|
15
|
+
|
16
|
+
def execute
|
17
|
+
validate_env
|
18
|
+
validate_cluster_file
|
19
|
+
validate_env_dir
|
20
|
+
validate_service
|
21
|
+
validate_upstreams
|
22
|
+
end
|
23
|
+
|
24
|
+
def validate_env
|
25
|
+
Dir.open(@gateway_folder + @env_dir)
|
26
|
+
# Check env name if is allowed
|
27
|
+
end
|
28
|
+
|
29
|
+
def validate_cluster_file
|
30
|
+
# Check if all env have defined DCs and each DC have pci and npci control planes
|
31
|
+
end
|
32
|
+
|
33
|
+
def validate_env_dir
|
34
|
+
# check the structure of the env dir:
|
35
|
+
# product_group -> one or more services
|
36
|
+
# product_group has a valid upstreams file
|
37
|
+
# figure out if any unknown files are present
|
38
|
+
end
|
39
|
+
|
40
|
+
def validate_service(service_file)
|
41
|
+
# Check if only one service is defined per file
|
42
|
+
# Check if the correct pci/non-pci tag is present on the service
|
43
|
+
# Check if routes don't have tags
|
44
|
+
# Check if
|
45
|
+
end
|
46
|
+
|
47
|
+
def validate_upstreams(upstreams_file)
|
48
|
+
# Check if upstreams for all services in the product_group is present or not
|
49
|
+
# Check if both pci and non-pci upstreams for a service are defined
|
50
|
+
# Check if all targets of a given upstream add up to 100
|
51
|
+
end
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
data/lib/gojira/cli.rb
ADDED
@@ -0,0 +1,33 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
require 'gojira/command/base'
|
5
|
+
require 'gojira/command/cluster'
|
6
|
+
require 'gojira/command/env'
|
7
|
+
|
8
|
+
module Gojira
|
9
|
+
class CLI < Thor
|
10
|
+
check_unknown_options!
|
11
|
+
|
12
|
+
def self.exit_on_failure?
|
13
|
+
true
|
14
|
+
end
|
15
|
+
|
16
|
+
desc 'version', 'Print Gojira gem version'
|
17
|
+
def version
|
18
|
+
puts Gojira::VERSION
|
19
|
+
end
|
20
|
+
|
21
|
+
desc 'cluster', 'Commands interacting with Kong cluster'
|
22
|
+
class_option :kong_addr, type: :string, desc: 'Kong Host & Port'
|
23
|
+
class_option :config, type: :string, desc: 'decK config file'
|
24
|
+
class_option :ca_cert_file, type: :string, desc: 'CA Cert File'
|
25
|
+
class_option :tls_client_key_file, type: :string, desc: 'TLS Client Key file'
|
26
|
+
class_option :tls_client_cert_file, type: :string, desc: 'TLS Client Cert file'
|
27
|
+
class_option :tls_server_name, type: :string, desc: 'TLS Server Name'
|
28
|
+
subcommand 'cluster', Gojira::Command::Cluster
|
29
|
+
|
30
|
+
desc 'env', 'Commands interacting with Gateway env directory'
|
31
|
+
subcommand 'env', Gojira::Command::Env
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,15 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gojira
|
4
|
+
module Command
|
5
|
+
class Base < Thor
|
6
|
+
def self.banner(command, _namespace = nil, _subcommand = false)
|
7
|
+
"#{basename} #{subcommand_prefix} #{command.usage}"
|
8
|
+
end
|
9
|
+
|
10
|
+
def self.subcommand_prefix
|
11
|
+
name.split('::').last.gsub(/([A-Z]+)([A-Z][a-z])/, '\1-\2').gsub(/([a-z\d])([A-Z])/, '\1-\2').downcase
|
12
|
+
end
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require 'gojira/command/base'
|
2
|
+
require 'gojira/errors'
|
3
|
+
require 'yaml'
|
4
|
+
|
5
|
+
module Gojira
|
6
|
+
module Command
|
7
|
+
class Cluster < Gojira::Command::Base
|
8
|
+
REQUIRED_CLASS_OPTIONS = %i[tls_enabled]
|
9
|
+
|
10
|
+
desc "validate", "validates kong config for a cluster"
|
11
|
+
method_option :kong_state_file, aliases: '-s', type: :string, desc: 'Kong State File', required: false
|
12
|
+
method_option :env_name, aliases: '-n', type: :string, desc: 'Environment identifier name', required: false
|
13
|
+
method_option :compliance_type, aliases: '-c', type: :string, desc: 'Compliance Type', enum: ['pci', 'non-pci'], required: false
|
14
|
+
method_option :cluster_file, aliases: '-f', type: :string, desc: 'Cluster file path', required: false
|
15
|
+
method_option :dc_name, aliases: '-d', type: :string, desc: 'DC Name', required: false
|
16
|
+
def validate
|
17
|
+
validate_options
|
18
|
+
deck = Gojira::Deck::Gateway.new('deck', get_control_plane)
|
19
|
+
deck.validate(options[:kong_state_file])
|
20
|
+
raise Thor::Error, deck.error if deck.error.any?
|
21
|
+
|
22
|
+
print("Kong state file validated successfully")
|
23
|
+
end
|
24
|
+
|
25
|
+
desc "diff", "diff output for kong config in a cluster"
|
26
|
+
method_option :kong_state_file, aliases: '-s', type: :string, desc: 'Kong State File', required: false
|
27
|
+
method_option :env_name, aliases: '-n', type: :string, desc: 'Environment identifier name', required: false
|
28
|
+
method_option :compliance_type, aliases: '-c', type: :string, desc: 'Compliance Type', enum: ['pci', 'non-pci'], required: false
|
29
|
+
method_option :cluster_file, aliases: '-f', type: :string, desc: 'Cluster file path', required: false
|
30
|
+
method_option :dc_name, aliases: '-d', type: :string, desc: 'DC Name', required: false
|
31
|
+
def diff
|
32
|
+
validate_options
|
33
|
+
deck = Gojira::Deck::Gateway.new('deck', get_control_plane)
|
34
|
+
deck.diff(options[:kong_state_file])
|
35
|
+
raise Thor::Error, deck.error if deck.error.any?
|
36
|
+
|
37
|
+
print(deck.output.first)
|
38
|
+
end
|
39
|
+
|
40
|
+
desc "sync", "syncs kong config to a cluster"
|
41
|
+
method_option :kong_state_file, aliases: '-s', type: :string, desc: 'Kong State File', required: false
|
42
|
+
method_option :env_name, aliases: '-n', type: :string, desc: 'Environment identifier name', required: false
|
43
|
+
method_option :compliance_type, aliases: '-c', type: :string, desc: 'Compliance Type', enum: ['pci', 'non-pci'], required: false
|
44
|
+
method_option :cluster_file, aliases: '-f', type: :string, desc: 'Cluster file path', required: false
|
45
|
+
method_option :dc_name, aliases: '-d', type: :string, desc: 'DC Name', required: false
|
46
|
+
def sync
|
47
|
+
require 'pry'; binding.pry
|
48
|
+
validate_options
|
49
|
+
deck = Gojira::Deck::Gateway.new('deck', get_control_plane)
|
50
|
+
deck.sync(options[:kong_state_file])
|
51
|
+
raise Thor::Error, deck.error if deck.error.any?
|
52
|
+
|
53
|
+
print(deck.output.first)
|
54
|
+
end
|
55
|
+
|
56
|
+
desc "dump", "takes dump of resources from a kong cluster"
|
57
|
+
method_option :env_name, aliases: '-n', type: :string, desc: 'Environment identifier name'
|
58
|
+
method_option :compliance_type, aliases: '-c', type: :string, desc: 'Compliance Type'
|
59
|
+
method_option :cluster_file, aliases: '-f', type: :string, desc: 'Cluster file path'
|
60
|
+
method_option :dc_name, aliases: '-d', type: :string, desc: 'DC Name'
|
61
|
+
def dump
|
62
|
+
validate_options
|
63
|
+
deck = Gojira::Deck::Gateway.new('deck', get_control_plane)
|
64
|
+
deck.dump(options[:kong_state_file])
|
65
|
+
raise Thor::Error, deck.error if deck.error.any?
|
66
|
+
|
67
|
+
print(deck.output.first)
|
68
|
+
end
|
69
|
+
|
70
|
+
no_commands do
|
71
|
+
def validate_options
|
72
|
+
raise Thor::Error, Gojira::Errors.required_options(REQUIRED_CLASS_OPTIONS) unless REQUIRED_CLASS_OPTIONS.all? {|option| @parent_options.key? option}
|
73
|
+
raise Thor::Error, Gojira::Errors.dc_type_invalid(dc_list) unless dc_list.include?(options['dc_name'])
|
74
|
+
end
|
75
|
+
|
76
|
+
def get_control_plane
|
77
|
+
clusters = YAML.load_file(options[:cluster_file])[options['env_name']]['control_plane']
|
78
|
+
|
79
|
+
required_cluster = clusters.select { |cluster| cluster['compliance_type'] == options['compliance_type'] and cluster['dc'] == options['dc_name'] }
|
80
|
+
required_cluster.first['address']
|
81
|
+
end
|
82
|
+
|
83
|
+
def dc_list
|
84
|
+
YAML.load_file(options[:cluster_file])[options['env_name']]['dc']
|
85
|
+
end
|
86
|
+
|
87
|
+
#TODO: Check if env_name is invalid
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'gojira/command/base'
|
4
|
+
require 'gojira/apiops/validations'
|
5
|
+
require 'gojira/apiops/merge'
|
6
|
+
require 'gojira/errors'
|
7
|
+
|
8
|
+
module Gojira
|
9
|
+
module Command
|
10
|
+
class Env < Gojira::Command::Base
|
11
|
+
desc 'lint', 'lints env repo and validates against conventions'
|
12
|
+
method_option :gateway_folder, aliases: '-f', type: :string, desc: 'Gateway configs folder path'
|
13
|
+
method_option :env_name, aliases: '-n', type: :string, desc: 'Environment identifier name'
|
14
|
+
method_option :cluster_file, aliases: '-c', type: :string, desc: 'Path to cluster definition file'
|
15
|
+
def lint
|
16
|
+
validation_engine = APIOps::Validations.new(options[:gateway_folder], options[:env_name], options[:cluster_file])
|
17
|
+
validation_engine.execute
|
18
|
+
|
19
|
+
raise Thor::Error, Gojira::Errors.lint_failed(validation_engine.errors) if validation_engine.errors.any?
|
20
|
+
print("Env successfully validated")
|
21
|
+
end
|
22
|
+
|
23
|
+
desc 'generate', 'generates kong state for the env repo'
|
24
|
+
method_option :gateway_folder, aliases: '-f', type: :string, desc: 'Gateway configs folder path'
|
25
|
+
method_option :env_name, aliases: '-n', type: :string, desc: 'Environment identifier name'
|
26
|
+
method_option :cluster_file, aliases: '-f', type: :string, desc: 'Path to Cluster definition file'
|
27
|
+
method_option :compliance_type, aliases: '-c', type: :string, desc: 'Compliance Type(pci/non-pci)'
|
28
|
+
method_option :dc_name, aliases: '-d', type: :string, desc: 'DC Name'
|
29
|
+
def generate
|
30
|
+
merge_engine = APIOps::Merge.new()
|
31
|
+
merge_engine.execute
|
32
|
+
|
33
|
+
raise Thor::Error, Gojira::Errors.merge_failed(merge_engine.errors) if merge_engine.errors.any?
|
34
|
+
print("Merge config validated at")
|
35
|
+
end
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,41 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'open3'
|
4
|
+
|
5
|
+
module Gojira
|
6
|
+
module Deck
|
7
|
+
class Base
|
8
|
+
attr_reader :binary_path, :params
|
9
|
+
attr_accessor :output, :error
|
10
|
+
|
11
|
+
def initialize(binary_path, kong_addr = nil, config_file = nil, timeout = 10, tls_params = {})
|
12
|
+
@binary_path = binary_path
|
13
|
+
@params = {
|
14
|
+
kong_addr: kong_addr,
|
15
|
+
config_file: config_file,
|
16
|
+
timeout: timeout,
|
17
|
+
tls_params: tls_params
|
18
|
+
}
|
19
|
+
@output = []
|
20
|
+
@error = []
|
21
|
+
end
|
22
|
+
|
23
|
+
def execute(command)
|
24
|
+
stdout_str, stderr_str, status = Open3.capture3("#{@binary_path} #{command} #{param_string}")
|
25
|
+
@output << stdout_str.chomp and return if status.success?
|
26
|
+
|
27
|
+
@error << "Error executing command: #{stderr_str}"
|
28
|
+
end
|
29
|
+
|
30
|
+
protected
|
31
|
+
|
32
|
+
def param_string
|
33
|
+
"#{generate_param_string(params.except(:tls_params))} #{generate_param_string(params[:tls_params])}"
|
34
|
+
end
|
35
|
+
|
36
|
+
def generate_param_string(params)
|
37
|
+
params.map { |key, value| "--#{key.to_s.gsub('_', '-')} #{value}" unless value.nil? }.join(' ').strip
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gojira
|
4
|
+
module Deck
|
5
|
+
class File < Gojira::Deck::Base
|
6
|
+
def initialize(binary_path, kong_addr = nil, config_file = nil, timeout = nil, tls_params = {})
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
def lint(state_file, ruleset_file)
|
11
|
+
command = "file lint -s #{state_file} #{ruleset_file}"
|
12
|
+
execute(command)
|
13
|
+
end
|
14
|
+
|
15
|
+
def render(state_file_list, output_file)
|
16
|
+
command = "file render #{state_file_list.join(' ')} -o #{output_file}"
|
17
|
+
execute(command)
|
18
|
+
end
|
19
|
+
|
20
|
+
def merge(state_file_list, output_file)
|
21
|
+
command = "file merge -o #{output_file} #{state_file_list.join(' ')}"
|
22
|
+
execute(command)
|
23
|
+
end
|
24
|
+
|
25
|
+
def validate(state_file)
|
26
|
+
command = "file validate -o #{state_file}"
|
27
|
+
execute(command)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
module Gojira
|
4
|
+
module Deck
|
5
|
+
class Gateway < Gojira::Deck::Base
|
6
|
+
def initialize(binary_path = 'deck', kong_addr = nil, config_file = nil, timeout = nil, tls_params = {})
|
7
|
+
super
|
8
|
+
end
|
9
|
+
|
10
|
+
def sync(state_file)
|
11
|
+
command = "gateway sync #{state_file}"
|
12
|
+
execute(command)
|
13
|
+
end
|
14
|
+
|
15
|
+
def diff(state_file)
|
16
|
+
command = "gateway diff #{state_file}"
|
17
|
+
execute(command)
|
18
|
+
end
|
19
|
+
|
20
|
+
def dump
|
21
|
+
command = 'gateway dump'
|
22
|
+
execute(command)
|
23
|
+
end
|
24
|
+
|
25
|
+
def validate(state_file)
|
26
|
+
command = "gateway validate #{state_file}"
|
27
|
+
execute(command)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
|
5
|
+
module Gojira
|
6
|
+
class Errors
|
7
|
+
class << self
|
8
|
+
def required_options(required_options_list)
|
9
|
+
"Pass all the required options as arguments #{required_options_list}"
|
10
|
+
end
|
11
|
+
|
12
|
+
def lint_failed(lint_output)
|
13
|
+
"Lint process failed, the env directory is not correctly formatted.\nCorrect these errors:\n#{lint_output}"
|
14
|
+
end
|
15
|
+
|
16
|
+
def merge_failed(merge_output)
|
17
|
+
"Merge process failed, the env directory is not correctly formatted. Run lint stage again!\nErrors:\n#{merge_output}"
|
18
|
+
end
|
19
|
+
|
20
|
+
def dc_type_invalid(dc_list)
|
21
|
+
"The passed dc_name is not a valid DC name in this environment. Please pass a DC name from this list: #{dc_list}"
|
22
|
+
end
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
data/lib/gojira.rb
ADDED
@@ -0,0 +1,26 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thor'
|
4
|
+
require_relative 'gojira/version'
|
5
|
+
require_relative 'gojira/deck/base'
|
6
|
+
require_relative 'gojira/deck/gateway'
|
7
|
+
require_relative 'gojira/deck/file'
|
8
|
+
require_relative 'gojira/cli'
|
9
|
+
|
10
|
+
module Gojira
|
11
|
+
class << self
|
12
|
+
attr_writer :config
|
13
|
+
|
14
|
+
def config
|
15
|
+
@config ||= Config.new
|
16
|
+
end
|
17
|
+
|
18
|
+
def configure
|
19
|
+
yield(config)
|
20
|
+
end
|
21
|
+
|
22
|
+
def reset!
|
23
|
+
@config = nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
data/rubocop.yml
ADDED
File without changes
|
metadata
ADDED
@@ -0,0 +1,174 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: gojira_apiops
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.1.0
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Kumar Abhijeet
|
8
|
+
autorequire:
|
9
|
+
bindir: exe
|
10
|
+
cert_chain: []
|
11
|
+
date: 2024-09-15 00:00:00.000000000 Z
|
12
|
+
dependencies:
|
13
|
+
- !ruby/object:Gem::Dependency
|
14
|
+
name: bundler
|
15
|
+
requirement: !ruby/object:Gem::Requirement
|
16
|
+
requirements:
|
17
|
+
- - "~>"
|
18
|
+
- !ruby/object:Gem::Version
|
19
|
+
version: '2.5'
|
20
|
+
type: :development
|
21
|
+
prerelease: false
|
22
|
+
version_requirements: !ruby/object:Gem::Requirement
|
23
|
+
requirements:
|
24
|
+
- - "~>"
|
25
|
+
- !ruby/object:Gem::Version
|
26
|
+
version: '2.5'
|
27
|
+
- !ruby/object:Gem::Dependency
|
28
|
+
name: rake
|
29
|
+
requirement: !ruby/object:Gem::Requirement
|
30
|
+
requirements:
|
31
|
+
- - "~>"
|
32
|
+
- !ruby/object:Gem::Version
|
33
|
+
version: '10.0'
|
34
|
+
type: :development
|
35
|
+
prerelease: false
|
36
|
+
version_requirements: !ruby/object:Gem::Requirement
|
37
|
+
requirements:
|
38
|
+
- - "~>"
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '10.0'
|
41
|
+
- !ruby/object:Gem::Dependency
|
42
|
+
name: rspec
|
43
|
+
requirement: !ruby/object:Gem::Requirement
|
44
|
+
requirements:
|
45
|
+
- - "~>"
|
46
|
+
- !ruby/object:Gem::Version
|
47
|
+
version: '3.0'
|
48
|
+
type: :development
|
49
|
+
prerelease: false
|
50
|
+
version_requirements: !ruby/object:Gem::Requirement
|
51
|
+
requirements:
|
52
|
+
- - "~>"
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '3.0'
|
55
|
+
- !ruby/object:Gem::Dependency
|
56
|
+
name: rubocop
|
57
|
+
requirement: !ruby/object:Gem::Requirement
|
58
|
+
requirements:
|
59
|
+
- - "~>"
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '1.64'
|
62
|
+
type: :development
|
63
|
+
prerelease: false
|
64
|
+
version_requirements: !ruby/object:Gem::Requirement
|
65
|
+
requirements:
|
66
|
+
- - "~>"
|
67
|
+
- !ruby/object:Gem::Version
|
68
|
+
version: '1.64'
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: thor
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: 1.3.1
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 1.3.1
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: yaml
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - ">="
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - ">="
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '0'
|
97
|
+
- !ruby/object:Gem::Dependency
|
98
|
+
name: pry
|
99
|
+
requirement: !ruby/object:Gem::Requirement
|
100
|
+
requirements:
|
101
|
+
- - ">="
|
102
|
+
- !ruby/object:Gem::Version
|
103
|
+
version: '0'
|
104
|
+
type: :development
|
105
|
+
prerelease: false
|
106
|
+
version_requirements: !ruby/object:Gem::Requirement
|
107
|
+
requirements:
|
108
|
+
- - ">="
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
description: A ruby gem to generate Kong configs across multiple clusters to achieve
|
112
|
+
service equivalence
|
113
|
+
email:
|
114
|
+
- kumarabhijeet1202@gmail.com
|
115
|
+
executables:
|
116
|
+
- gojira
|
117
|
+
extensions: []
|
118
|
+
extra_rdoc_files: []
|
119
|
+
files:
|
120
|
+
- ".github/workflows/main.yml"
|
121
|
+
- ".gitignore"
|
122
|
+
- ".rspec"
|
123
|
+
- ".ruby-version"
|
124
|
+
- Dockerfile
|
125
|
+
- Gemfile
|
126
|
+
- Gemfile.lock
|
127
|
+
- README.md
|
128
|
+
- Rakefile
|
129
|
+
- bin/console
|
130
|
+
- bin/setup
|
131
|
+
- docs/gojira.png
|
132
|
+
- exe/gojira
|
133
|
+
- gojira.gemspec
|
134
|
+
- lib/gojira.rb
|
135
|
+
- lib/gojira/apiops/merge.rb
|
136
|
+
- lib/gojira/apiops/validations.rb
|
137
|
+
- lib/gojira/cli.rb
|
138
|
+
- lib/gojira/command/base.rb
|
139
|
+
- lib/gojira/command/cluster.rb
|
140
|
+
- lib/gojira/command/env.rb
|
141
|
+
- lib/gojira/deck/base.rb
|
142
|
+
- lib/gojira/deck/file.rb
|
143
|
+
- lib/gojira/deck/gateway.rb
|
144
|
+
- lib/gojira/errors.rb
|
145
|
+
- lib/gojira/version.rb
|
146
|
+
- rubocop.yml
|
147
|
+
homepage: https://github.com/kumar1202/gojira/tree/main
|
148
|
+
licenses: []
|
149
|
+
metadata:
|
150
|
+
allowed_push_host: https://rubygems.org
|
151
|
+
homepage_uri: https://github.com/kumar1202/gojira/tree/main
|
152
|
+
source_code_uri: https://github.com/kumar1202/gojira/tree/main
|
153
|
+
changelog_uri: https://github.com/kumar1202/gojira/tree/main
|
154
|
+
post_install_message:
|
155
|
+
rdoc_options: []
|
156
|
+
require_paths:
|
157
|
+
- lib
|
158
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
159
|
+
requirements:
|
160
|
+
- - ">="
|
161
|
+
- !ruby/object:Gem::Version
|
162
|
+
version: '0'
|
163
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
164
|
+
requirements:
|
165
|
+
- - ">="
|
166
|
+
- !ruby/object:Gem::Version
|
167
|
+
version: '0'
|
168
|
+
requirements: []
|
169
|
+
rubygems_version: 3.5.9
|
170
|
+
signing_key:
|
171
|
+
specification_version: 4
|
172
|
+
summary: A ruby gem to generate Kong configs across multiple clusters to achieve service
|
173
|
+
equivalence
|
174
|
+
test_files: []
|