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 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
@@ -0,0 +1,14 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /_yardoc/
4
+ /coverage/
5
+ /doc/
6
+ /pkg/
7
+ /spec/reports/
8
+ /tmp/
9
+ vendor/
10
+ local/
11
+
12
+ # rspec failure tracking
13
+ .rspec_status
14
+ test-files/
data/.rspec ADDED
@@ -0,0 +1,3 @@
1
+ --format documentation
2
+ --color
3
+ --require spec_helper
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
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ source 'https://rubygems.org'
4
+
5
+ git_source(:github) { |repo_name| "https://github.com/#{repo_name}" }
6
+
7
+ # Specify your gem's dependencies in gojira.gemspec
8
+ gemspec
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
@@ -0,0 +1,8 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'bundler/gem_tasks'
4
+ require 'rspec/core/rake_task'
5
+
6
+ RSpec::Core::RakeTask.new(:spec)
7
+
8
+ task default: :spec
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
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env bash
2
+ set -euo pipefail
3
+ IFS=$'\n\t'
4
+ set -vx
5
+
6
+ bundle install
7
+
8
+
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
@@ -0,0 +1,5 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Gojira
4
+ VERSION = '0.1.0'
5
+ 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: []