Skip to content

Commit

Permalink
feat(keychain): add rust keychain plugin vault implementation
Browse files Browse the repository at this point in the history
This is partially a new feature, partially an example to
demonstrate how one can develop a plugin written in
in rust that then will be callable by other (non-rust) plugins
that are hosted inside a Cactus node's API server(s).

99% of the rust code here was generated by the command below:

docker run --rm -v "${PWD}:/local" openapitools/openapi-generator-cli generate \
    --input-spec https://raw.githubusercontent.com/petermetz/cactus/feat/cmd-api-server/out-of-process-plugin-Instances-for-language-Independence-170/packages/cactus-plugin-keychain-vault/src/main/json/openapi.json \
    --generator-name rust-server \
    -o /local/gen/rust-server

The only thing that was then added to the generated rust code
is the logic that uses the vault client create to do the
get/set operations in vault and parses the environment
variables for the vault token, host.
Still a to-do for the above to have a proper has/delete method
in the rust code which was not implemented due to time constraints.

Also added a Typescript implementation of the vault keychain plugin
just so that we can have a full end to end test coverage of all the
variants of configurations where the plugin is local vs. remote.

Signed-off-by: Peter Somogyvari <peter.somogyvari@accenture.com>
  • Loading branch information
petermetz committed Jan 14, 2021
1 parent 3a0acf4 commit 6dcdb8a
Show file tree
Hide file tree
Showing 37 changed files with 5,601 additions and 139 deletions.
2 changes: 2 additions & 0 deletions packages/cactus-cmd-api-server/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,8 @@
"uuid": "7.0.2"
},
"devDependencies": {
"@hyperledger/cactus-plugin-keychain-vault": "0.3.0",
"@hyperledger/cactus-test-tooling": "0.3.0",
"@types/compression": "1.7.0",
"@types/convict": "5.2.1",
"@types/cors": "2.8.6",
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
import test, { Test } from "tape-promise/tape";
import { v4 as uuidv4 } from "uuid";

import { LogLevelDesc } from "@hyperledger/cactus-common";

import { ApiServer, ConfigService } from "../../../main/typescript/public-api";

import {
CactusKeychainVaultServer,
Containers,
K_DEFAULT_VAULT_DEV_ROOT_TOKEN,
K_DEFAULT_VAULT_HTTP_PORT,
VaultTestServer,
} from "@hyperledger/cactus-test-tooling";

import { DefaultApi } from "@hyperledger/cactus-plugin-keychain-vault";
import { PluginImportType } from "@hyperledger/cactus-core-api";

test("NodeJS API server + Rust plugin work together", async (t: Test) => {
const vaultTestContainer = new VaultTestServer({});
await vaultTestContainer.start();

const ci = await Containers.getById(vaultTestContainer.containerId);
const vaultIpAddr = await Containers.getContainerInternalIp(ci);
t.comment(`Container VaultTestServer has IPv4: ${vaultIpAddr}`);

test.onFinish(async () => {
await vaultTestContainer.stop();
await vaultTestContainer.destroy();
});

const hostPortVault = await vaultTestContainer.getHostPortHttp();
t.comment(`Container VaultTestServer (Port=${hostPortVault}) started OK`);
const vaultHost = `http://${vaultIpAddr}:${K_DEFAULT_VAULT_HTTP_PORT}`;

const pluginContainer = new CactusKeychainVaultServer({
envVars: [
`VAULT_HOST=${vaultHost}`,
`VAULT_TOKEN=${K_DEFAULT_VAULT_DEV_ROOT_TOKEN}`,
"HOST=0.0.0.0:8080",
],
});
await pluginContainer.start();

test.onFinish(async () => {
await pluginContainer.stop();
await pluginContainer.destroy();
});

const hostPort = await pluginContainer.getHostPortHttp();
t.comment(`CactusKeychainVaultServer (Port=${hostPort}) started OK`);

const configuration = { basePath: `http://localhost:${hostPort}` };
const apiClient = new DefaultApi(configuration);

const configService = new ConfigService();
const apiServerOptions = configService.newExampleConfig();
apiServerOptions.configFile = "";
apiServerOptions.apiCorsDomainCsv = "*";
apiServerOptions.apiPort = 0;
apiServerOptions.cockpitPort = 0;
apiServerOptions.apiTlsEnabled = false;
apiServerOptions.plugins = [
{
packageName: "@hyperledger/cactus-plugin-keychain-vault",
type: PluginImportType.REMOTE,
options: {
keychainId: "_keychainId_",
instanceId: "_instanceId_",
remoteConfig: configuration,
},
},
];
const config = configService.newExampleConfigConvict(apiServerOptions);

const apiServer = new ApiServer({
config: config.getProperties(),
});

await t.doesNotReject(apiServer.start(), "Started API server OK");
test.onFinish(() => apiServer.shutdown());

const key = uuidv4();
const expected = uuidv4();

await apiClient.setKeychainEntry({ key, value: expected });
const {
data: { value: actual },
} = await apiClient.getKeychainEntry({ key });

t.equal(actual, expected, "Keychain stored value matches input OK");

t.end();
});

0 comments on commit 6dcdb8a

Please sign in to comment.