Skip to content

Commit 19ec9a0

Browse files
authored
Merge pull request #171 from SAP/ssh-key
use ssh key to clone private github repos
2 parents 96914b3 + 97b0a32 commit 19ec9a0

9 files changed

Lines changed: 95 additions & 29 deletions

File tree

deploy/infrabox/templates/_helpers.tpl

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,11 +95,13 @@ https://{{- required "host is required" .Values.host -}}:{{- .Values.port -}}
9595
{{ end }}
9696

9797
{{ define "mounts_gerrit" }}
98+
{{ if .Values.gerrit.enabled }}
9899
-
99100
name: gerrit-ssh
100101
mountPath: /tmp/gerrit
101102
readOnly: true
102103
{{ end }}
104+
{{ end }}
103105

104106
{{ define "volumes_gerrit" }}
105107
{{ if .Values.gerrit.enabled }}

deploy/infrabox/templates/function_crd.yaml

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ spec:
1515
memory: 1Gi
1616
env:
1717
{{ include "env_general" . | indent 4 }}
18-
{{ include "env_gerrit" . | indent 4 }}
1918
-
2019
name: INFRABOX_JOB_STORAGE_DRIVER
2120
value: {{ .Values.job.storage_driver }}
@@ -34,11 +33,6 @@ spec:
3433
-
3534
mountPath: /local-cache
3635
name: local-cache
37-
{{ end }}
38-
{{ if .Values.gerrit.enabled }}
39-
-
40-
mountPath: /var/run/gerrit/
41-
name: gerrit-ssh
4236
{{ end }}
4337
volumes:
4438
-
@@ -54,9 +48,3 @@ spec:
5448
hostPath:
5549
path: {{ default "/tmp/infrabox/local_cache" .Values.local_cache.host_path }}
5650
{{ end }}
57-
{{ if .Values.gerrit.enabled }}
58-
-
59-
name: gerrit-ssh
60-
secret:
61-
secretName: infrabox-gerrit-ssh
62-
{{ end }}

deploy/infrabox/templates/scheduler/deployment.yaml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,8 @@ spec:
3535
value: "443"
3636
volumeMounts:
3737
{{ include "mounts_rsa_private" . | indent 16 }}
38+
{{ include "mounts_gerrit" . | indent 16 }}
3839
volumes:
3940
{{ include "volumes_database" . | indent 16 }}
4041
{{ include "volumes_rsa" . | indent 16 }}
42+
{{ include "volumes_gerrit" . | indent 16 }}

src/api/handlers/projects/projects.py

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,8 @@
1010
from pyinfraboxutils.ibflask import OK
1111
from pyinfraboxutils.ibopa import opa_push_project_data, opa_push_collaborator_data
1212

13+
from Crypto.PublicKey import RSA
14+
1315
ns = api.namespace('Projects',
1416
path='/api/v1/projects',
1517
description='Project related operations')
@@ -156,11 +158,15 @@ def post(self):
156158
owner = split[0]
157159
repo_name = split[1]
158160

161+
clone_url = repo['clone_url']
162+
if repo['private']:
163+
clone_url = repo['ssh_url']
164+
159165
g.db.execute('''
160166
INSERT INTO repository (name, html_url, clone_url, github_id,
161167
private, project_id, github_owner)
162168
VALUES (%s, %s, %s, %s, %s, %s, %s)
163-
''', [repo['name'], repo['html_url'], repo['clone_url'],
169+
''', [repo['name'], repo['html_url'], clone_url,
164170
repo['id'], repo['private'], project_id, repo['owner']['login']])
165171

166172
insecure_ssl = "0"
@@ -200,6 +206,31 @@ def post(self):
200206
UPDATE repository SET github_hook_id = %s
201207
WHERE github_id = %s
202208
''', [hook['id'], repo['id']])
209+
210+
# deploy key
211+
key = RSA.generate(2048)
212+
private_key = key.exportKey('PEM')
213+
public_key = key.publickey().exportKey('OpenSSH')
214+
deploy_key_config = {
215+
'title': "InfraBox",
216+
'key': public_key,
217+
'read_only': True
218+
}
219+
220+
url = '%s/repos/%s/%s/keys' % (os.environ['INFRABOX_GITHUB_API_URL'],
221+
owner, repo_name)
222+
223+
# TODO(ib-steffen): allow custom ca bundles
224+
r = requests.post(url, headers=headers, json=deploy_key_config, verify=False)
225+
226+
if r.status_code != 201:
227+
abort(400, 'Failed to create deploy key')
228+
229+
g.db.execute('''
230+
UPDATE repository SET private_key = %s
231+
WHERE github_id = %s
232+
''', [private_key, repo['id']])
233+
203234
elif typ == 'gerrit':
204235
g.db.execute('''
205236
INSERT INTO repository (name, private, project_id, html_url, clone_url, github_id)

src/db/migrations/00022.sql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
ALTER TABLE repository ADD COLUMN private_key text;

src/github/trigger/trigger.py

Lines changed: 5 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -121,11 +121,10 @@ def create_build(self, commit_id, project_id):
121121
build_id = result[0][0]
122122
return build_id
123123

124-
def create_job(self, commit_id, clone_url, build_id, project_id, github_private_repo, branch, env=None, fork=False):
124+
def create_job(self, commit_id, clone_url, build_id, project_id, branch, env=None, fork=False):
125125
git_repo = {
126126
"commit": commit_id,
127127
"clone_url": clone_url,
128-
"github_private_repo": github_private_repo,
129128
"branch": branch,
130129
"fork": fork
131130
}
@@ -168,13 +167,12 @@ def create_push(self, c, repository, branch, tag):
168167
return
169168

170169
result = self.execute('''
171-
SELECT id, project_id, private
170+
SELECT id, project_id
172171
FROM repository
173172
WHERE github_id = %s''', [repository['id']])[0]
174173

175174
repo_id = result[0]
176175
project_id = result[1]
177-
github_repo_private = result[2]
178176
commit_id = None
179177

180178
result = self.execute('''
@@ -226,7 +224,7 @@ def create_push(self, c, repository, branch, tag):
226224

227225
build_id = self.create_build(commit_id, project_id)
228226
self.create_job(c['id'], repository['clone_url'], build_id,
229-
project_id, github_repo_private, branch)
227+
project_id, branch)
230228

231229
def handle_push(self, event):
232230
result = self.execute('''
@@ -275,7 +273,7 @@ def handle_pull_request(self, event):
275273
return res(200, 'action ignored')
276274

277275
result = self.execute('''
278-
SELECT id, project_id, private FROM repository WHERE github_id = %s;
276+
SELECT id, project_id FROM repository WHERE github_id = %s;
279277
''', [event['repository']['id']])
280278

281279
if not result:
@@ -285,7 +283,6 @@ def handle_pull_request(self, event):
285283

286284
repo_id = result[0]
287285
project_id = result[1]
288-
github_repo_private = result[2]
289286

290287
result = self.execute('''
291288
SELECT build_on_push FROM project WHERE id = %s;
@@ -398,7 +395,7 @@ def handle_pull_request(self, event):
398395
build_id = self.create_build(commit_id, project_id)
399396
self.create_job(event['pull_request']['head']['sha'],
400397
event['pull_request']['head']['repo']['clone_url'],
401-
build_id, project_id, github_repo_private, branch, env=env, fork=is_fork)
398+
build_id, project_id, branch, env=env, fork=is_fork)
402399

403400
self.conn.commit()
404401

src/job/entrypoint.sh

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,14 +31,14 @@ else
3131
echo "Using host docker daemon socket"
3232
fi
3333

34-
if [ -f /var/run/gerrit/id_rsa ]; then
34+
if [ ! -z "$INFRABOX_GIT_PRIVATE_KEY" ]; then
3535
echo "Setting private key"
3636
eval `ssh-agent -s`
37-
cp /var/run/gerrit/id_rsa ~/.ssh/id_rsa
37+
echo $INFRABOX_GIT_PRIVATE_KEY > ~/.ssh/id_rsa
3838
chmod 600 ~/.ssh/id_rsa
3939
echo "StrictHostKeyChecking no" > ~/.ssh/config
4040
ssh-add ~/.ssh/id_rsa
41-
ssh-keyscan -p $INFRABOX_GERRIT_PORT $INFRABOX_GERRIT_HOSTNAME >> ~/.ssh/known_hosts
41+
ssh-keyscan -p $INFRABOX_GIT_PORT $INFRABOX_GIT_HOSTNAME >> ~/.ssh/known_hosts
4242
else
4343
echo "No private key configured"
4444
fi

src/job/job.py

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,6 @@ def get_source(self):
211211
repo = self.job['repo']
212212
clone_url = repo['clone_url']
213213
branch = repo.get('branch', None)
214-
private = repo.get('github_private_repo', False)
215214
clone_all = repo.get('full_history', False)
216215
ref = repo.get('ref', None)
217216

@@ -229,10 +228,6 @@ def get_source(self):
229228
if not repo_clone:
230229
return
231230

232-
if private:
233-
clone_url = clone_url.replace('github.com',
234-
'%[email protected]' % self.repository['github_api_token'])
235-
236231
self.clone_repo(commit, clone_url, branch, ref, clone_all, submodules=repo_submodules)
237232
elif self.project['type'] == 'upload':
238233
c.collect("Downloading Source")

src/scheduler/kubernetes/scheduler.py

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -570,6 +570,56 @@ def kube_job(self, job_id, cpu, mem, services=None):
570570
'value': str(cpu)
571571
}]
572572

573+
# Get ssh key for private repos
574+
cursor = self.conn.cursor()
575+
cursor.execute('''
576+
SELECT p.type, p.id
577+
FROM project p
578+
JOIN job j
579+
ON j.project_id = p.id
580+
WHERE j.id = %s
581+
''', [job_id])
582+
result = cursor.fetchone()
583+
cursor.close()
584+
585+
project_type = result[0]
586+
project_id = result[1]
587+
588+
private_key = None
589+
if project_type == 'github':
590+
cursor = self.conn.cursor()
591+
cursor.execute('''
592+
SELECT r.private_key
593+
FROM repository r
594+
WHERE r.project_id = %s
595+
''', [project_id])
596+
result = cursor.fetchone()
597+
cursor.close()
598+
private_key = result[0]
599+
600+
env += [{
601+
'name': 'INFRABOX_GIT_PORT',
602+
'value': '443'
603+
}, {
604+
'name': 'INFRABOX_GIT_HOSTNAME',
605+
'value': 'github.com'
606+
}, {
607+
'name': 'INFRABOX_GIT_PRIVATE_KEY',
608+
'value': private_key
609+
}]
610+
elif project_type == 'gerrit':
611+
with open(os.environ['INFRABOX_GERRIT_KEY_FILENAME']) as key:
612+
env += [{
613+
'name': 'INFRABOX_GIT_PORT',
614+
'value': os.environ['INFRABOX_GERRIT_PORT']
615+
}, {
616+
'name': 'INFRABOX_GIT_HOSTNAME',
617+
'value': os.environ['INFRABOX_GERRIT_HOSTNAME']
618+
}, {
619+
'name': 'INFRABOX_GIT_PRIVATE_KEY',
620+
'value': key.read()
621+
}]
622+
573623
root_url = os.environ['INFRABOX_ROOT_URL']
574624

575625
if services:

0 commit comments

Comments
 (0)