Skip to content

Commit

Permalink
[Code] enable ssh protocol, only read ssh key pairs from data folder.
Browse files Browse the repository at this point in the history
  • Loading branch information
spacedragon committed Apr 3, 2019
1 parent 8132915 commit 80e07a5
Show file tree
Hide file tree
Showing 13 changed files with 249 additions and 83 deletions.
2 changes: 1 addition & 1 deletion x-pack/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@
"@elastic/javascript-typescript-langserver": "^0.1.21",
"@elastic/lsp-extension": "^0.1.1",
"@elastic/node-crypto": "0.1.2",
"@elastic/nodegit": "0.25.0-alpha.11",
"@elastic/nodegit": "0.25.0-alpha.12",
"@elastic/numeral": "2.3.2",
"@kbn/babel-preset": "1.0.0",
"@kbn/es-query": "1.0.0",
Expand Down
11 changes: 11 additions & 0 deletions x-pack/plugins/code/common/repository_utils.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ test('Repository url parsing', () => {
url: 'https://github.com/apache/sqoop',
name: 'sqoop',
org: 'apache',
protocol: 'https',
});

// Valid git url with .git suffix.
Expand All @@ -23,6 +24,7 @@ test('Repository url parsing', () => {
uri: 'github.com/apache/sqoop',
url: 'https://github.com/apache/sqoop.git',
name: 'sqoop',
protocol: 'https',
org: 'apache',
});

Expand All @@ -39,6 +41,7 @@ test('Repository url parsing', () => {
url: 'git://a/b',
name: 'b',
org: '_',
protocol: 'git',
});

const repo5 = RepositoryUtils.buildRepository('git://a/b/c');
Expand All @@ -47,13 +50,15 @@ test('Repository url parsing', () => {
url: 'git://a/b/c',
name: 'c',
org: 'b',
protocol: 'git',
});

const repo6 = RepositoryUtils.buildRepository('[email protected]:foo/bar.git');
expect(repo6).toEqual({
uri: 'github.com/foo/bar',
url: '[email protected]:foo/bar.git',
name: 'bar',
protocol: 'ssh',
org: 'foo',
});

Expand All @@ -63,6 +68,7 @@ test('Repository url parsing', () => {
url: 'ssh://[email protected]:foo/bar.git',
name: 'bar',
org: 'foo',
protocol: 'ssh',
});
});

Expand All @@ -73,6 +79,7 @@ test('Repository url parsing with non standard segments', () => {
url: 'git://a/b/c/d',
name: 'd',
org: 'b_c',
protocol: 'git',
});

const repo2 = RepositoryUtils.buildRepository('git://a/b/c/d/e');
Expand All @@ -81,13 +88,15 @@ test('Repository url parsing with non standard segments', () => {
url: 'git://a/b/c/d/e',
name: 'e',
org: 'b_c_d',
protocol: 'git',
});

const repo3 = RepositoryUtils.buildRepository('git://a');
expect(repo3).toEqual({
uri: 'a/_/_',
url: 'git://a',
name: '_',
protocol: 'git',
org: '_',
});
});
Expand All @@ -99,6 +108,7 @@ test('Repository url parsing with port', () => {
url: 'ssh://[email protected]:27017/gitolite-admin',
name: 'gitolite-admin',
org: 'mine',
protocol: 'ssh',
});

const repo2 = RepositoryUtils.buildRepository(
Expand All @@ -108,6 +118,7 @@ test('Repository url parsing with port', () => {
uri: 'mydomain.com:27017/elastic/gitolite-admin',
url: 'ssh://[email protected]:27017/elastic/gitolite-admin',
name: 'gitolite-admin',
protocol: 'ssh',
org: 'elastic',
});
});
Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/code/common/repository_utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ export class RepositoryUtils {
url: repo.href as string,
name,
org,
protocol: repo.protocol,
};
}

Expand Down
1 change: 1 addition & 0 deletions x-pack/plugins/code/model/repository.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ export interface Repository {
org?: string;
defaultBranch?: string;
revision?: string;
protocol?: string;
// The timestamp of next update for this repository.
nextUpdateTimestamp?: Date;
// The timestamp of next index for this repository.
Expand Down
61 changes: 61 additions & 0 deletions x-pack/plugins/code/server/__tests__/repository_service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
/*
* Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one
* or more contributor license agreements. Licensed under the Elastic License;
* you may not use this file except in compliance with the Elastic License.
*/

import assert from 'assert';
// import { generateKeyPairSync } from 'crypto';
import fs from 'fs';
import * as os from 'os';
import path from 'path';
import rimraf from 'rimraf';
import { RepositoryUtils } from '../../common/repository_utils';
import { RepositoryService } from '../repository_service';
import { ConsoleLogger } from '../utils/console_logger';

describe('repository service test', () => {
const log = new ConsoleLogger();
const baseDir = fs.mkdtempSync(path.join(os.tmpdir(), 'code_test'));
log.debug(baseDir);
const repoDir = path.join(baseDir, 'repo');
const credsDir = path.join(baseDir, 'credentials');
// @ts-ignore
before(() => {
fs.mkdirSync(credsDir);
fs.mkdirSync(repoDir);
});
// @ts-ignore
after(() => {
return rimraf.sync(baseDir);
});
const service = new RepositoryService(repoDir, credsDir, log);

it('can not clone a repo by ssh without a key', async () => {
const repo = RepositoryUtils.buildRepository(
'[email protected]:elastic/TypeScript-Node-Starter.git'
);
await assert.rejects(service.clone(repo));
// @ts-ignore
}).timeout(60000);

/*it('can clone a repo by ssh with a key', async () => {
const repo = RepositoryUtils.buildRepository('[email protected]:elastic/code.git');
const { publicKey, privateKey } = generateKeyPairSync('rsa', {
modulusLength: 4096,
publicKeyEncoding: {
type: 'pkcs1',
format: 'pem',
},
privateKeyEncoding: {
type: 'pkcs1',
format: 'pem',
},
});
fs.writeFileSync(path.join(credsDir, 'id_rsa.pub'), publicKey);
fs.writeFileSync(path.join(credsDir, 'id_rsa'), privateKey);
const result = await service.clone(repo);
assert.ok(fs.existsSync(path.join(repoDir, result.repo.uri)));
}).timeout(60000); */
});
6 changes: 5 additions & 1 deletion x-pack/plugins/code/server/queue/clone_worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,11 @@ export class CloneWorker extends AbstractGitWorker {
}

this.log.info(`Execute clone job for ${url}`);
const repoService = this.repoServiceFactory.newInstance(this.serverOptions.repoPath, this.log);
const repoService = this.repoServiceFactory.newInstance(
this.serverOptions.repoPath,
this.serverOptions.credsPath,
this.log
);
const repo = RepositoryUtils.buildRepository(url);
return await repoService.clone(repo, (progress: number, cloneProgress?: CloneProgress) => {
this.updateProgress(repo.uri, progress, cloneProgress);
Expand Down
6 changes: 5 additions & 1 deletion x-pack/plugins/code/server/queue/delete_worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,11 @@ export class DeleteWorker extends AbstractWorker {
this.cancellationService.cancelIndexJob(uri);

// 2. Delete repository on local fs.
const repoService = this.repoServiceFactory.newInstance(this.serverOptions.repoPath, this.log);
const repoService = this.repoServiceFactory.newInstance(
this.serverOptions.repoPath,
this.serverOptions.credsPath,
this.log
);
const deleteRepoPromise = this.deletePromiseWrapper(repoService.remove(uri), 'git data', uri);

// 3. Delete ES indices and aliases
Expand Down
14 changes: 9 additions & 5 deletions x-pack/plugins/code/server/queue/update_worker.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
* you may not use this file except in compliance with the Elastic License.
*/

import { CloneWorkerResult } from '../../model';
import { CloneWorkerResult, Repository } from '../../model';
import { EsClient, Esqueue } from '../lib/esqueue';
import { Logger } from '../log';
import { RepositoryServiceFactory } from '../repository_service_factory';
Expand All @@ -26,10 +26,14 @@ export class UpdateWorker extends AbstractGitWorker {
}

public async executeJob(job: Job) {
const { uri } = job.payload;
this.log.info(`Execute update job for ${uri}`);
const repoService = this.repoServiceFactory.newInstance(this.serverOptions.repoPath, this.log);
return await repoService.update(uri);
const repo: Repository = job.payload;
this.log.info(`Execute update job for ${repo.uri}`);
const repoService = this.repoServiceFactory.newInstance(
this.serverOptions.repoPath,
this.serverOptions.credsPath,
this.log
);
return await repoService.update(repo);
}

public async onJobCompleted(job: Job, res: CloneWorkerResult) {
Expand Down
Loading

0 comments on commit 80e07a5

Please sign in to comment.