release_manager 0.3.0

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