summaryrefslogtreecommitdiff
path: root/backends/gitlab-ce
blob: 3b6cc9076812edbcc0fe47bb8864644bccf2df4d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
#!/usr/bin/env ruby
# coding: utf-8

# http://docs.gitlab.com/ee/workflow/repository_mirroring.html
# https://gitlab.com/gitlab-org/gitlab-ee/issues/767

require 'net/http'
require 'uri'
require 'cgi'
require 'json'

class GitLabCE
	def initialize(api_uri, api_key, project_id)
		@api_uri = URI(api_uri)
		unless @api_uri.path.end_with?("/")
			@api_uri.path += "/"
		end
		@api_key = api_key.to_s
		@project_id = project_id.to_s

		@connections = {}
		@cache = {}

		# API docs suck, just look at `lib/api/projects.rb`
		@vars = [
			:builds_enabled,                                  # create | create-user | edit
			:container_registry_enabled,                      # create |             | edit
			:default_branch                                   #        | create-user | edit
			:description,                                     # create | create-user | edit
			:import_url,                                      # create | create-user |
			:issues_enabled,                                  # create | create-user | edit
			:lfs_enabled,                                     # create | create-user | edit
			:merge_requests_enabled,                          # create | create-user | edit
			:name,                                            # create | create-user | edit
			:namespace_id,                                    # create |             |
			:only_allow_merge_if_build_succeeds,              # create | create-user | edit
			:path,                                            # create |             | edit
			:public,                                          # create | create-user | edit
			:public_builds,                                   # create | create-user | edit
			:request_access_enabled,                          # create | create-user | edit
			:shared_runners_enabled,                          # create | create-user | edit
			:snippets_enabled,                                # create | create-user | edit
			:visibility_level,                                # create | create-user | edit
			:wiki_enabled,                                    # create | create-user | edit
			:only_allow_merge_if_all_discussions_are_resolved # create | create-user | edit
		]

		@vars = [
			"builds_enabled",
			"container_registry_enabled",
			"default_branch",
			"description",
			"issues_enabled",
			"lfs_enabled",
			"merge_requests_enabled",
			"name",
			"only_allow_merge_if_all_discussions_are_resolved",
			"only_allow_merge_if_build_succeeds",
			"path",
			"public",
			"public_builds",
			"request_access_enabled",
			"shared_runners_enabled",
			"snippets_enabled",
			"visibility_level",
			"wiki_enabled",
		]
	end

	def _connection(uri)
		key=URI(uri.scheme+":")
		key.host = uri.host
		key.port = uri.port

		@connections[key] ||= Net::HTTP::start(uri.host, uri.port, :use_ssl => uri.scheme == 'https')
		return @connections[key]
	end

	def _info
		unless @cache.has_key?(:info)
			req = Net::HTTP::Get.new(@api_uri + "projects/" + CGI::escape(@project_id))
			req.add_field("PRIVATE-TOKEN", @api_key)
			con = _connection(req.uri)
			res = con.request(req)
			if res.code != "200"
				throw res
			end
			@cache[:info] = JSON::parse(res.body)
		end
		return @cache[:info]
	end

	def get_meta
		return _info.select{|k,v| @vars.include?(k)}
	end

	def set_meta(map)
		illegal = map.select{|k,v| not @vars.include?(k)}
		if illegal.count > 0
			throw illegal
		end

		req = Net::HTTP::Put.new(@api_uri + "projects/" + CGI::escape(_info["id"].to_s))
		req.add_field("PRIVATE-TOKEN", @api_key)
		req.add_field("Content-Type", "application/json")
		req.body = JSON::dump(map)
		con = _connection(req.uri)
		res = con.request(req)
		if res.code != "200"
			throw res
		end
		@cache[:info] = JSON::parse(res.body)
		return get_meta
	end

	def pushURL
		return _info["ssh_url_to_repo"]
	end

	def pullURL
		return _info["http_url_to_repo"]
	end

	def create(id, map)
		if map.has_key?("mirror")
			map["import_url"] = map["mirror"]
			map.delete("mirror")
		end
		req = Net::HTTP::Post.new(@api_uri + "projects")
		req.add_field("PRIVATE-TOKEN", @api_key)
		req.add_field("Content-Type", "application/json")
		req.body = JSON::dump(map)
		con = _connection(req.uri)
		res = con.request(req)
	end

	def capabilities
		return [
			[ "get-meta", @vars ].flatten,
			[ "set-meta", @vars ].flatten,
			[ "push-url" ],
			[ "pull-url" ],
		]
	end

	def finish
		@connections.each do |k,v|
			v.finish()
		end
		@connections = {}
	end
end