satorix 0.0.1 → 1.5.3

Sign up to get free protection for your applications and to get access to all the features.
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