release_manager 0.3.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.
Files changed (45) hide show
  1. checksums.yaml +7 -0
  2. data/.bash_profile +27 -0
  3. data/.dockerignore +1 -0
  4. data/.env +3 -0
  5. data/.gitignore +13 -0
  6. data/.rspec +2 -0
  7. data/CHANGELOG.md +55 -0
  8. data/Dockerfile +14 -0
  9. data/Gemfile +14 -0
  10. data/Gemfile.lock +72 -0
  11. data/LICENSE.txt +21 -0
  12. data/README.md +311 -0
  13. data/Rakefile +6 -0
  14. data/app_startup_script.sh +4 -0
  15. data/bin/console +14 -0
  16. data/bin/setup +8 -0
  17. data/docker-compose.yml +37 -0
  18. data/exe/bump-changelog +5 -0
  19. data/exe/deploy-mod +5 -0
  20. data/exe/release-mod +5 -0
  21. data/exe/sandbox-create +13 -0
  22. data/lib/release_manager.rb +33 -0
  23. data/lib/release_manager/changelog.rb +130 -0
  24. data/lib/release_manager/cli/deploy_mod_cli.rb +44 -0
  25. data/lib/release_manager/cli/release_mod_cli.rb +43 -0
  26. data/lib/release_manager/cli/sandbox_create_cli.rb +138 -0
  27. data/lib/release_manager/control_mod.rb +83 -0
  28. data/lib/release_manager/control_repo.rb +35 -0
  29. data/lib/release_manager/errors.rb +13 -0
  30. data/lib/release_manager/git/credentials.rb +98 -0
  31. data/lib/release_manager/git/utilites.rb +263 -0
  32. data/lib/release_manager/logger.rb +52 -0
  33. data/lib/release_manager/module_deployer.rb +77 -0
  34. data/lib/release_manager/puppet_module.rb +211 -0
  35. data/lib/release_manager/puppetfile.rb +148 -0
  36. data/lib/release_manager/release.rb +174 -0
  37. data/lib/release_manager/sandbox.rb +272 -0
  38. data/lib/release_manager/vcs_manager.rb +22 -0
  39. data/lib/release_manager/vcs_manager/gitlab_adapter.rb +112 -0
  40. data/lib/release_manager/vcs_manager/vcs_adapter.rb +22 -0
  41. data/lib/release_manager/version.rb +3 -0
  42. data/lib/release_manager/workflow_action.rb +5 -0
  43. data/release_manager.gemspec +38 -0
  44. data/setup_repos.rb +95 -0
  45. metadata +175 -0
@@ -0,0 +1,112 @@
1
+ require 'release_manager/vcs_manager/vcs_adapter'
2
+ require 'gitlab'
3
+ module ReleaseManager
4
+ module VCSManager
5
+ class GitlabAdapter < ReleaseManager::VCSManager::VcsAdapter
6
+ attr_reader :client
7
+
8
+ def initialize
9
+ @client = Gitlab.client
10
+ end
11
+
12
+ # creates an instance of the gitlab adapter
13
+ def self.create
14
+ new
15
+ end
16
+
17
+ # adds the ssh key to the user of the token
18
+ def add_ssh_key(public_key_filename = nil)
19
+ public_key_filename ||= File.expand_path(File.join(ENV['HOME'], '.ssh', 'id_rsa.pub'))
20
+ title = "#{ENV['USER']}@#{ENV['HOST']}"
21
+ raise InvalidSshkey.new("Ssh key does not exist #{public_key_filename}") unless File.exist?(public_key_filename)
22
+ begin
23
+ client.create_ssh_key(title, File.read(public_key_filename))
24
+ logger.info("Adding ssh key #{public_key_filename} to gitlab")
25
+ rescue Gitlab::Error::BadRequest => e
26
+ # if the key is already added no need to do anything else
27
+ return unless e.response_status == 400
28
+ end
29
+ end
30
+
31
+ def project_name(project_id)
32
+ client.projects(project_id)
33
+ end
34
+
35
+ # https://docs.gitlab.com/ee/api/members.html
36
+ def add_permission(username, project_id, access_level = 20)
37
+ begin
38
+ project_name = client.project(project_id).path_with_namespace
39
+ user = client.user_search(username).find{|u| u.username == username}
40
+ unless user
41
+ logger.warn("No user found for #{username}")
42
+ return
43
+ end
44
+ unless check_access?(username, project_id, access_level)
45
+ logger.info("Adding member #{username} to project #{project_name}")
46
+ client.add_team_member(project_id, user.id, access_level)
47
+ end
48
+ rescue Gitlab::Error::BadRequest => e
49
+ # if the key is already added no need to do anything else
50
+ logger.warn(e.message)
51
+ end
52
+ end
53
+
54
+ def check_access?(username, project_id, access_level)
55
+ client.team_members(project_id).find { |user| user.username == username && user.access_level == access_level}
56
+ end
57
+
58
+ # https://docs.gitlab.com/ee/api/members.html
59
+ def add_permissions(project_id, user_ids = [], access_level = 20)
60
+ user_ids.map {|id| add_permission(id, project_id, access_level)}
61
+ end
62
+
63
+ # @return String - the branch name that was created
64
+ def create_repo_branch(repo_id, branch_name)
65
+ Gitlab.repo_create_branch(repo_id, branch_name)
66
+ end
67
+
68
+ def clone_repo(branch_name, mod_name, url, repos_dir)
69
+ path = File.join(repos_dir, mod_name)
70
+ Rugged::Repository.clone_at(url, path, checkout_branch: branch_name)
71
+ end
72
+
73
+ # TODO: extract this out to an adapter
74
+ # replaces namespace from the url with the supplied or default namespace
75
+ def swap_namespace(url, namespace = nil)
76
+ url.gsub(/\:([\w-]+)\//, ":#{namespace || Gitlab.user.username}/")
77
+ end
78
+
79
+ # @return [Gitlab::ObjectifiedHash] Information about the forked project
80
+ # @param [ControlMod] the module you want to fork
81
+ # TODO: extract this out to an adapter
82
+ # def create_repo_fork(url, namespace = nil )
83
+ # new_url = swap_namespace(url, namespace)
84
+ # repo = repo_exists?(new_url)
85
+ # unless repo
86
+ # upstream_repo_id = repo_id(url)
87
+ # logger.info("Forking project from #{url} to #{new_url}")
88
+ # repo = Gitlab.create_fork(upstream_repo_id)
89
+ # # gitlab lies about having completed the forking process, so lets sleep until it is actually done
90
+ # loop do
91
+ # sleep(1)
92
+ # break if repo_exists?(repo.ssh_url_to_repo)
93
+ # end
94
+ # end
95
+ # repo
96
+ # end
97
+ #
98
+ # # @param [String] url - the git url of the repository
99
+ # # @return [Boolean] returns the project object (true) if found, false otherwise
100
+ # # TODO: extract this out to an adapter
101
+ # def repo_exists?(url)
102
+ # upstream_repo_id = repo_id(url)
103
+ # begin
104
+ # Gitlab.project(upstream_repo_id)
105
+ # rescue
106
+ # false
107
+ # end
108
+ # end
109
+
110
+ end
111
+ end
112
+ end
@@ -0,0 +1,22 @@
1
+ require 'release_manager/logger'
2
+ require 'release_manager/errors'
3
+
4
+ module ReleaseManager
5
+ module VCSManager
6
+ class VcsAdapter
7
+ include ReleaseManager::Logger
8
+
9
+ def self.create
10
+ raise NotImplementedError
11
+ end
12
+
13
+ def add_ssh_key(public_key)
14
+ raise NotImplementedError
15
+ end
16
+
17
+ def add_permission(user, repo)
18
+ raise NotImplementedError
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,3 @@
1
+ module ReleaseManager
2
+ VERSION = "0.3.0"
3
+ end
@@ -0,0 +1,5 @@
1
+ class WorkflowAction
2
+ def self.check_requirements
3
+ raise NotImplementedError
4
+ end
5
+ end
@@ -0,0 +1,38 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'release_manager/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "release_manager"
8
+ spec.version = ReleaseManager::VERSION
9
+ spec.authors = ["Corey Osman"]
10
+ spec.email = ["corey@nwops.io"]
11
+
12
+ spec.summary = %q{Release tools for puppet code}
13
+ spec.description = %q{Release management tools for releasing modules and r10k control repos}
14
+ spec.homepage = ""
15
+ spec.license = "MIT"
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'] = "TODO: Set to 'http://mygemserver.com'"
21
+ else
22
+ raise "RubyGems 2.0 or newer is required to protect against " \
23
+ "public gem pushes."
24
+ end
25
+
26
+ spec.files = `git ls-files -z`.split("\x0").reject do |f|
27
+ f.match(%r{^(test|spec|features)/})
28
+ end
29
+ spec.bindir = "exe"
30
+ spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
31
+ spec.require_paths = ["lib"]
32
+ spec.add_runtime_dependency "gitlab", "~>3.7.0"
33
+ spec.add_runtime_dependency "rugged"
34
+ spec.add_development_dependency "bundler", "~> 1.14"
35
+ spec.add_development_dependency "pry"
36
+ spec.add_development_dependency "rake", "~> 10.0"
37
+ spec.add_development_dependency "rspec", "~> 3.0"
38
+ end
data/setup_repos.rb ADDED
@@ -0,0 +1,95 @@
1
+ #!/usr/bin/env ruby
2
+ require 'gitlab'
3
+
4
+ def client
5
+ @client ||= Gitlab.client
6
+ end
7
+
8
+ def devops_group
9
+ unless @devops_group
10
+ begin
11
+ @devops_group = client.create_group('devops', 'devops')
12
+ rescue Gitlab::Error::BadRequest => e
13
+ if e.response_status == 400
14
+ @devops_group = client.group('devops')
15
+ end
16
+ end
17
+ end
18
+ @devops_group
19
+ end
20
+
21
+ def create_puppet_file(proj)
22
+ begin
23
+ client.create_file(proj.id, 'Puppetfile', 'master', puppetfile_content, 'init commit')
24
+ rescue Gitlab::Error::BadRequest => e
25
+ if e.response_status == 400
26
+ # already created
27
+ end
28
+ end
29
+ end
30
+
31
+ def create_control_repo
32
+ begin
33
+ proj = client.create_project('control-repo', namespace_id: devops_group.id)
34
+ client.create_branch(proj.id, 'dev')
35
+ client.create_branch(proj.id, 'production')
36
+ create_puppet_file(proj)
37
+ rescue Gitlab::Error::BadRequest => e
38
+ if e.response_status == 400
39
+ # already created
40
+ proj = client.project("devops%2Fcontrol-repo")
41
+ create_puppet_file(proj)
42
+ end
43
+ end
44
+ end
45
+
46
+ def modules
47
+ <<-EOF
48
+ # Example42 v4.x modules (Used in various profiles)
49
+ mod 'docker',
50
+ :git => 'https://github.com/example42/puppet-docker'
51
+ mod 'network',
52
+ :git => 'https://github.com/example42/puppet-network'
53
+ mod 'apache',
54
+ :git => 'https://github.com/example42/puppet-apache',
55
+ :branch => '4.x'
56
+ mod 'puppet',
57
+ :git => 'https://github.com/example42/puppet-puppet',
58
+ :branch => 'master'
59
+ mod 'rails',
60
+ :git => 'https://github.com/example42/puppet-rails'
61
+ mod 'ansible',
62
+ :git => 'https://github.com/example42/puppet-ansible'
63
+ mod 'icinga',
64
+ :git => 'https://github.com/example42/puppet-icinga',
65
+ :branch => '4.x'
66
+
67
+ EOF
68
+
69
+ end
70
+
71
+ def puppetfile_content
72
+ @puppetfile_content ||= ''
73
+ end
74
+
75
+ def mod(name, *args)
76
+ url = args.first[:git]
77
+ begin
78
+ proj = client.create_project(name, import_url: url, namespace_id: devops_group.id)
79
+ rescue Gitlab::Error::BadRequest => e
80
+ if e.response_status == 400
81
+ proj = client.project("devops%2F#{name}")
82
+ end
83
+ end
84
+ args.first[:git] = proj.ssh_url_to_repo
85
+ data = args.first.sort.map { |k, v| ":#{k} => '#{v}'" }.join(",\n ")
86
+ puppetfile_content << "mod '#{name}',\n #{data}\n\n"
87
+ end
88
+
89
+ eval(modules)
90
+ create_control_repo
91
+
92
+ client.create_user('joe@foo.org', 'password', 'joe', { name: 'Joe Smith' })
93
+
94
+ # add the ssh key
95
+ # create_ssh_key(title, key)
metadata ADDED
@@ -0,0 +1,175 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: release_manager
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.3.0
5
+ platform: ruby
6
+ authors:
7
+ - Corey Osman
8
+ autorequire:
9
+ bindir: exe
10
+ cert_chain: []
11
+ date: 2017-05-15 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: gitlab
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ~>
18
+ - !ruby/object:Gem::Version
19
+ version: 3.7.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ~>
25
+ - !ruby/object:Gem::Version
26
+ version: 3.7.0
27
+ - !ruby/object:Gem::Dependency
28
+ name: rugged
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - '>='
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - '>='
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: bundler
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - ~>
46
+ - !ruby/object:Gem::Version
47
+ version: '1.14'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - ~>
53
+ - !ruby/object:Gem::Version
54
+ version: '1.14'
55
+ - !ruby/object:Gem::Dependency
56
+ name: pry
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - '>='
60
+ - !ruby/object:Gem::Version
61
+ version: '0'
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - '>='
67
+ - !ruby/object:Gem::Version
68
+ version: '0'
69
+ - !ruby/object:Gem::Dependency
70
+ name: rake
71
+ requirement: !ruby/object:Gem::Requirement
72
+ requirements:
73
+ - - ~>
74
+ - !ruby/object:Gem::Version
75
+ version: '10.0'
76
+ type: :development
77
+ prerelease: false
78
+ version_requirements: !ruby/object:Gem::Requirement
79
+ requirements:
80
+ - - ~>
81
+ - !ruby/object:Gem::Version
82
+ version: '10.0'
83
+ - !ruby/object:Gem::Dependency
84
+ name: rspec
85
+ requirement: !ruby/object:Gem::Requirement
86
+ requirements:
87
+ - - ~>
88
+ - !ruby/object:Gem::Version
89
+ version: '3.0'
90
+ type: :development
91
+ prerelease: false
92
+ version_requirements: !ruby/object:Gem::Requirement
93
+ requirements:
94
+ - - ~>
95
+ - !ruby/object:Gem::Version
96
+ version: '3.0'
97
+ description: Release management tools for releasing modules and r10k control repos
98
+ email:
99
+ - corey@nwops.io
100
+ executables:
101
+ - bump-changelog
102
+ - deploy-mod
103
+ - release-mod
104
+ - sandbox-create
105
+ extensions: []
106
+ extra_rdoc_files: []
107
+ files:
108
+ - .bash_profile
109
+ - .dockerignore
110
+ - .env
111
+ - .gitignore
112
+ - .rspec
113
+ - CHANGELOG.md
114
+ - Dockerfile
115
+ - Gemfile
116
+ - Gemfile.lock
117
+ - LICENSE.txt
118
+ - README.md
119
+ - Rakefile
120
+ - app_startup_script.sh
121
+ - bin/console
122
+ - bin/setup
123
+ - docker-compose.yml
124
+ - exe/bump-changelog
125
+ - exe/deploy-mod
126
+ - exe/release-mod
127
+ - exe/sandbox-create
128
+ - lib/release_manager.rb
129
+ - lib/release_manager/changelog.rb
130
+ - lib/release_manager/cli/deploy_mod_cli.rb
131
+ - lib/release_manager/cli/release_mod_cli.rb
132
+ - lib/release_manager/cli/sandbox_create_cli.rb
133
+ - lib/release_manager/control_mod.rb
134
+ - lib/release_manager/control_repo.rb
135
+ - lib/release_manager/errors.rb
136
+ - lib/release_manager/git/credentials.rb
137
+ - lib/release_manager/git/utilites.rb
138
+ - lib/release_manager/logger.rb
139
+ - lib/release_manager/module_deployer.rb
140
+ - lib/release_manager/puppet_module.rb
141
+ - lib/release_manager/puppetfile.rb
142
+ - lib/release_manager/release.rb
143
+ - lib/release_manager/sandbox.rb
144
+ - lib/release_manager/vcs_manager.rb
145
+ - lib/release_manager/vcs_manager/gitlab_adapter.rb
146
+ - lib/release_manager/vcs_manager/vcs_adapter.rb
147
+ - lib/release_manager/version.rb
148
+ - lib/release_manager/workflow_action.rb
149
+ - release_manager.gemspec
150
+ - setup_repos.rb
151
+ homepage: ''
152
+ licenses:
153
+ - MIT
154
+ metadata: {}
155
+ post_install_message:
156
+ rdoc_options: []
157
+ require_paths:
158
+ - lib
159
+ required_ruby_version: !ruby/object:Gem::Requirement
160
+ requirements:
161
+ - - '>='
162
+ - !ruby/object:Gem::Version
163
+ version: '0'
164
+ required_rubygems_version: !ruby/object:Gem::Requirement
165
+ requirements:
166
+ - - '>='
167
+ - !ruby/object:Gem::Version
168
+ version: '0'
169
+ requirements: []
170
+ rubyforge_project:
171
+ rubygems_version: 2.0.14.1
172
+ signing_key:
173
+ specification_version: 4
174
+ summary: Release tools for puppet code
175
+ test_files: []