satorix 0.0.1 → 1.5.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.
Files changed (40) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +4 -1
  3. data/.gitlab-ci.yml +45 -0
  4. data/.rspec +2 -1
  5. data/.rubocop.yml +11 -0
  6. data/.ruby-version +1 -0
  7. data/Gemfile +2 -0
  8. data/Gemfile.lock +25 -0
  9. data/Procfile +1 -0
  10. data/README.md +93 -1
  11. data/Rakefile +8 -4
  12. data/bin/console +3 -3
  13. data/bin/satorix +8 -0
  14. data/lib/satorix/CI/deploy/flynn/environment_variables.rb +123 -0
  15. data/lib/satorix/CI/deploy/flynn/resources.rb +79 -0
  16. data/lib/satorix/CI/deploy/flynn/routes.rb +267 -0
  17. data/lib/satorix/CI/deploy/flynn/scale.rb +52 -0
  18. data/lib/satorix/CI/deploy/flynn.rb +132 -0
  19. data/lib/satorix/CI/shared/buildpack_manager/buildpack.rb +159 -0
  20. data/lib/satorix/CI/shared/buildpack_manager.rb +220 -0
  21. data/lib/satorix/CI/shared/ruby/gem_manager.rb +80 -0
  22. data/lib/satorix/CI/shared/yarn_manager.rb +25 -0
  23. data/lib/satorix/CI/test/python/django_test.rb +38 -0
  24. data/lib/satorix/CI/test/python/safety.rb +30 -0
  25. data/lib/satorix/CI/test/ruby/brakeman.rb +35 -0
  26. data/lib/satorix/CI/test/ruby/bundler_audit.rb +35 -0
  27. data/lib/satorix/CI/test/ruby/cucumber.rb +29 -0
  28. data/lib/satorix/CI/test/ruby/rails_test.rb +29 -0
  29. data/lib/satorix/CI/test/ruby/rspec.rb +29 -0
  30. data/lib/satorix/CI/test/ruby/rubocop.rb +98 -0
  31. data/lib/satorix/CI/test/shared/database.rb +74 -0
  32. data/lib/satorix/shared/console.rb +157 -0
  33. data/lib/satorix/version.rb +1 -1
  34. data/lib/satorix.rb +343 -2
  35. data/satorix/CI/deploy/ie_gem_server.rb +80 -0
  36. data/satorix/CI/deploy/rubygems.rb +81 -0
  37. data/satorix/custom.rb +21 -0
  38. data/satorix.gemspec +13 -11
  39. metadata +57 -29
  40. data/.travis.yml +0 -5
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: f677f81f64b5f6c8e17e151b2b2be516cb736ff1
4
- data.tar.gz: 55632c8146b1748a25c56b45c2def07e7f6d5902
2
+ SHA256:
3
+ metadata.gz: 9088dfa5e536b94cd4ab988c4201161bb2d830a7ff2417885cd51819457d5b46
4
+ data.tar.gz: 184dcbd4d9ed1c939e293a1186ea9db8189d9cc527e9db3f75add9b02b02dc94
5
5
  SHA512:
6
- metadata.gz: 571f0d7f89ee278d5d06be705e2cc910cd925cdc3642d23f12e852d0542fcac31222c4abf20a8c5475163a14785db243b0d4a8787f84f0ff308dd9e75ecb4af5
7
- data.tar.gz: 4ed70556edd92e3d2a08a6f08e3e54f85fe569c37134748e5483ce201d5f4956d99e8a2a9c54c5eb9dde8c32dc1179506c510ceb26ddd2882d9ed830329d0724
6
+ metadata.gz: 803dd33cf23c8febee87bb48c0546b304afb1b286be05827a171e4a08bbc23e7c2967692f819d89ea255d3ca751d0052dd38ad0bb7a44e8268bffe4a51745bca
7
+ data.tar.gz: c1b2517847dc98193ec4fe56383299d803aff291a5858fa2e1057753ae1c4ecf2031093e453e510a58442d38c4fc5ea01c6e84841fed870a201de40d782c9cdd
data/.gitignore CHANGED
@@ -1,9 +1,12 @@
1
1
  /.bundle/
2
2
  /.yardoc
3
- /Gemfile.lock
4
3
  /_yardoc/
5
4
  /coverage/
6
5
  /doc/
7
6
  /pkg/
8
7
  /spec/reports/
9
8
  /tmp/
9
+
10
+ # Ruymine/development files
11
+ .idea
12
+ clean_branches.rb
data/.gitlab-ci.yml ADDED
@@ -0,0 +1,45 @@
1
+ image: 'satorix/base'
2
+
3
+ cache:
4
+ key: "$CI_PROJECT_ID"
5
+ paths:
6
+ - 'tmp/satorix/cache' # To cache buildpack gems between runs.
7
+
8
+
9
+ .satorix: &satorix
10
+ script:
11
+ - gem install satorix --source https://gems.iexposure.com --no-document
12
+ - satorix
13
+
14
+
15
+ # bundler-audit
16
+ # Patch-level verification for Bundler
17
+ # https://github.com/rubysec/bundler-audit
18
+ bundler_audit:
19
+ <<: *satorix
20
+
21
+
22
+ # RSpec
23
+ # Behaviour Driven Development for Ruby
24
+ # http://rspec.info/
25
+ rspec:
26
+ <<: *satorix
27
+
28
+
29
+ # RuboCop
30
+ # A Ruby static code analyzer, based on the community Ruby style guide.
31
+ # https://github.com/bbatsov/rubocop
32
+ rubocop:
33
+ <<: *satorix
34
+ allow_failure: true
35
+
36
+
37
+
38
+ # This is a custom job, defined at satorix/CI/deploy/rubygems.rb
39
+ deploy_to_rubygems:
40
+ stage: deploy
41
+ only:
42
+ - master
43
+ except:
44
+ - schedules
45
+ <<: *satorix
data/.rspec CHANGED
@@ -1,2 +1,3 @@
1
- --format documentation
1
+ --format progress
2
+ --order rand
2
3
  --color
data/.rubocop.yml ADDED
@@ -0,0 +1,11 @@
1
+ Metrics/LineLength:
2
+ Max: 120
3
+
4
+ Style/ModuleFunction:
5
+ Enabled: false
6
+
7
+ Layout/SpaceInsideStringInterpolation:
8
+ EnforcedStyle: space
9
+
10
+ Style/FrozenStringLiteralComment:
11
+ Enabled: false
data/.ruby-version ADDED
@@ -0,0 +1 @@
1
+ ruby-2.6.6
data/Gemfile CHANGED
@@ -1,3 +1,5 @@
1
+ ruby File.open("#{ File.dirname(__FILE__) }/.ruby-version", &:gets).strip[/ruby-(.+)/i, 1]
2
+
1
3
  source 'https://rubygems.org'
2
4
 
3
5
  # Specify your gem's dependencies in satorix.gemspec
data/Gemfile.lock ADDED
@@ -0,0 +1,25 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ satorix (1.5.3)
5
+ airbrake-ruby
6
+ bundler (~> 1.13)
7
+ rake
8
+
9
+ GEM
10
+ remote: https://rubygems.org/
11
+ specs:
12
+ airbrake-ruby (2.0.0)
13
+ rake (13.0.1)
14
+
15
+ PLATFORMS
16
+ ruby
17
+
18
+ DEPENDENCIES
19
+ satorix!
20
+
21
+ RUBY VERSION
22
+ ruby 2.6.6p146
23
+
24
+ BUNDLED WITH
25
+ 1.17.3
data/Procfile ADDED
@@ -0,0 +1 @@
1
+ # This is an empty file, to silence an buildpack warning during testing.
data/README.md CHANGED
@@ -1,3 +1,95 @@
1
1
  # Satorix
2
2
 
3
- By [Internet Exposure](https://www.iexposure.com/)
3
+ By [Satorix](https://www.satorix.com/)
4
+
5
+ [![build](http://gitlab.iexposure.com/satorix/satorix/badges/master/build.svg)](http://gitlab.iexposure.com/satorix/satorix/pipelines)
6
+ [![coverage](http://gitlab.iexposure.com/satorix/satorix/badges/master/coverage.svg)](http://gitlab.iexposure.com/satorix/satorix/pipelines)
7
+
8
+ This gem is a commandline tool used to tie together SCM, CI/CD, and hosting environments.
9
+
10
+ ## Installation
11
+
12
+ Install Satorix from the command line:
13
+
14
+ $ gem install satorix
15
+
16
+ ## Usage
17
+
18
+ Run Satorix from the command line:
19
+
20
+ $ satorix
21
+
22
+ Note: Satorix is currently designed to be run via GitLab CI, not locally.
23
+
24
+ ## Application Preparation
25
+
26
+ To prepare your application:
27
+
28
+ [Satorix Docs](https://www.satorix.com/docs)
29
+
30
+
31
+ ## Development
32
+
33
+ After checking out the repo, run `bin/setup` to install dependencies.
34
+ Then, run `bundle exec rspec spec` to run the tests.
35
+ You can also run `bin/console` for an interactive prompt that will allow you to experiment.
36
+
37
+ To install this gem onto your local machine, run `bundle exec rake install`.
38
+
39
+
40
+ ## CI/CD
41
+
42
+ Satorix is used to provide continuous integration and continuous deployment for this application.
43
+
44
+ CI is run against every push.
45
+
46
+ CD is used to automatically build and deploy the gem for the master branch.
47
+
48
+ ## Environment Variables
49
+
50
+ Satorix uses environment variables as an authoritative source for application configuration.
51
+
52
+ Environment variables are named with the scheme of PREFIX_BRANCH_KEY.
53
+
54
+
55
+ ### Application (AEEV)
56
+
57
+ Application-level environment variables are identified by the AEEV prefix (Application Exportable Environment Variable).
58
+
59
+ These environment variables are passed to the Satorix Hosting Evnvironment for consumption by the application. A
60
+ likely use case would be secrets.yml
61
+
62
+ The prefix and branch are removed.
63
+
64
+
65
+ * AEEV_PRODUCTION_SECRET_API_KEY
66
+ * AEEV_STAGING_SECRET_API_KEY
67
+
68
+ The variable name passed to the application in the respective environment would be SECRET_API_KEY
69
+
70
+
71
+ ### Flynn (FLYNN)
72
+
73
+ Environment variables used to configure Flynn are identified by the FLYNN prefix.
74
+
75
+ #### Required
76
+
77
+ * DOMAIN
78
+ * KEY
79
+ * TLSPIN
80
+
81
+ #### Optional
82
+
83
+ * SCALE
84
+ * RESOURCES
85
+
86
+ ### Domain (DDEV, CRT, KEY)
87
+
88
+ Domain information can be configured with environment variables identified by the DOMAIN prefix.
89
+
90
+ * KEY_PRODUCTION_DOMAINDOM
91
+ * CRT_PRODUCTION_DOMAINDOM
92
+ * DDEV_PRODUCTION_DOMAINDOM
93
+ * KEY_PRODUCTION_DEFAULT
94
+ * CRT_PRODUCTION_DEFAULT
95
+
data/Rakefile CHANGED
@@ -1,6 +1,10 @@
1
- require "bundler/gem_tasks"
2
- require "rspec/core/rake_task"
1
+ require 'bundler/gem_tasks'
2
+ begin
3
+ require 'rspec/core/rake_task'
3
4
 
4
- RSpec::Core::RakeTask.new(:spec)
5
+ RSpec::Core::RakeTask.new(:spec)
5
6
 
6
- task :default => :spec
7
+ task default: :spec
8
+ rescue LoadError
9
+ # no rspec available
10
+ end
data/bin/console CHANGED
@@ -1,7 +1,7 @@
1
1
  #!/usr/bin/env ruby
2
2
 
3
- require "bundler/setup"
4
- require "satorix"
3
+ require 'bundler/setup'
4
+ require 'satorix'
5
5
 
6
6
  # You can add fixtures and/or initialization code here to make experimenting
7
7
  # with your gem easier. You can also use a different console, if you like.
@@ -10,5 +10,5 @@ require "satorix"
10
10
  # require "pry"
11
11
  # Pry.start
12
12
 
13
- require "irb"
13
+ require 'irb'
14
14
  IRB.start
data/bin/satorix ADDED
@@ -0,0 +1,8 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ #Adjust path in case called directly and not through gem
4
+ $:.unshift "#{File.expand_path(File.dirname(__FILE__))}/../lib"
5
+
6
+ require 'satorix'
7
+
8
+ Satorix.go
@@ -0,0 +1,123 @@
1
+ require 'yaml'
2
+
3
+ module Satorix
4
+ module CI
5
+ module Deploy
6
+ module Flynn
7
+ module EnvironmentVariables
8
+
9
+
10
+ def adjust_env_vars
11
+ ensure_required_env_vars_are_defined unless ENV["SATORIX_#{ current_branch }_ENFORCE_ENV_VAR_DEFINITION"] == 'false'
12
+ env_unset
13
+ env_set
14
+ end
15
+
16
+
17
+ def aeev_key_exists?
18
+ !(run_command('flynn env', quiet: true) =~ /#{ exported_aeevs_key }=/mi).nil?
19
+ end
20
+
21
+
22
+ def aeev_prefix
23
+ # AEEV - Application Exportable Environment Variable
24
+ "AEEV_#{ current_branch }_"
25
+ end
26
+
27
+
28
+ def ci_provided_env_vars
29
+ {}.tap do |vars|
30
+ ENV.each do |key, value|
31
+ vars[key.sub(aeev_prefix, '')] = value.sub('***EMPTY_STRING***', '') if key.start_with?(aeev_prefix)
32
+ end
33
+ end
34
+ end
35
+
36
+
37
+ def current_flynn_keys
38
+ aeev_key_exists? ? run_command("flynn env get #{ exported_aeevs_key }", quiet: true).split : []
39
+ end
40
+
41
+
42
+ def desired_env_vars
43
+ ci_provided_env_vars.tap do |vars|
44
+ vars[exported_aeevs_key] = (vars.keys << exported_aeevs_key).sort.join("\n")
45
+ end
46
+ end
47
+
48
+
49
+ def ensure_required_env_vars_are_defined(configuration_file: 'config/secrets.yml')
50
+ # TODO : handle new Rails secrets methods, like encrypted secrets
51
+ if File.file?(configuration_file)
52
+ secrets = YAML.load_file(configuration_file)
53
+
54
+ all_secrets = {}
55
+ all_secrets.merge!(secrets['shared']) if secrets['shared']
56
+ all_secrets.merge!(secrets['production']) if secrets['production']
57
+
58
+ required = all_secrets.to_yaml.scan(/ENV\[['"](?<var>[A-Z0-9_.]+)['"]\]/).flatten.uniq
59
+ set = ci_provided_env_vars.keys
60
+
61
+ missing = required - set
62
+
63
+ if missing.empty?
64
+ log "All required environment variables from #{ configuration_file } have been defined."
65
+ else
66
+ log_error "Environment variables specified in #{ configuration_file } were not defined for the #{ current_branch.downcase } branch."
67
+ log_error "\nPlease define the following variables in your dashboard:\n#{ missing.join("\n") }\n"
68
+ log_error_and_abort 'Missing required environment variables.'
69
+ end
70
+ else
71
+ log "No #{ configuration_file } exists, skipping environment variable enforcement."
72
+ end
73
+ end
74
+
75
+
76
+ def env_set
77
+ if env_vars_to_set.empty?
78
+ log 'No new environment variables to set.'
79
+ else
80
+ keys_and_values = env_vars_to_set.map { |k, v| "#{ k }=#{ v }" }
81
+ run_command(['flynn', 'env', 'set', keys_and_values].flatten, filtered_text: env_vars_to_set.values)
82
+ end
83
+ end
84
+
85
+
86
+ def env_unset
87
+ if env_vars_to_unset.empty?
88
+ log 'No existing environment variables to unset.'
89
+ else
90
+ run_command "flynn env unset #{ env_vars_to_unset.join(' ') }"
91
+ end
92
+ end
93
+
94
+
95
+ def env_vars
96
+ @_env_vars ||= begin
97
+ {}.tap do |vars|
98
+ current_flynn_keys.each { |key| vars[key] = run_command("flynn env get #{ key }", quiet: true).chomp }
99
+ end
100
+ end
101
+ end
102
+
103
+
104
+ def env_vars_to_set
105
+ @_env_vars_to_set ||= desired_env_vars.reject { |k, v| env_vars.key?(k) && env_vars[k] == v }
106
+ end
107
+
108
+
109
+ def env_vars_to_unset
110
+ @_env_vars_to_unset ||= env_vars.keys - desired_env_vars.keys
111
+ end
112
+
113
+
114
+ def exported_aeevs_key
115
+ 'AEEV_KEYS'
116
+ end
117
+
118
+
119
+ end
120
+ end
121
+ end
122
+ end
123
+ end
@@ -0,0 +1,79 @@
1
+ module Satorix
2
+ module CI
3
+ module Deploy
4
+ module Flynn
5
+ module Resources
6
+
7
+
8
+ def add_resources
9
+ if resources_to_add.empty?
10
+ log 'No resources to add.'
11
+ else
12
+ resources_to_add.each { |resource| run_command "flynn resource add #{ resource }" }
13
+ end
14
+ end
15
+
16
+
17
+ def available_resources
18
+ %w(postgres mysql mongodb redis)
19
+ end
20
+
21
+
22
+ def current_resource_provider_names
23
+ resource.split("\n").drop(1).map(&:split).map(&:last)
24
+ end
25
+
26
+
27
+ def desired_resource_provider_names
28
+ names = ENV[resource_provider_key].to_s.split
29
+ disallowed = names - available_resources
30
+ unless disallowed.empty?
31
+ log_error_and_abort("Invalid resource#{ 's' if disallowed.length > 1 }: #{ disallowed.join(' ') }")
32
+ end
33
+ names
34
+ end
35
+
36
+
37
+ def remove_resources
38
+ if resources_to_remove.empty?
39
+ log 'No resources to remove.'
40
+ else
41
+ log "The following previously allocated resources are no longer defined in #{ resource_provider_key }:"
42
+ log resources_to_remove.join(' ')
43
+ log ''
44
+ log 'To remove them, use the flynn resource command: https://flynn.io/docs/cli#resource'
45
+ end
46
+ end
47
+
48
+
49
+ def resource
50
+ run_command('flynn resource', quiet: true).chomp
51
+ end
52
+
53
+
54
+ def resource_provider_key
55
+ "FLYNN_#{ current_branch }_RESOURCES"
56
+ end
57
+
58
+
59
+ def resources_to_add
60
+ desired_resource_provider_names - current_resource_provider_names
61
+ end
62
+
63
+
64
+ def resources_to_remove
65
+ current_resource_provider_names - desired_resource_provider_names
66
+ end
67
+
68
+
69
+ def set_resources
70
+ add_resources
71
+ remove_resources
72
+ end
73
+
74
+
75
+ end
76
+ end
77
+ end
78
+ end
79
+ end