Skip to content

Instantly share code, notes, and snippets.

@erossignon
Created May 27, 2020 18:32
Show Gist options
  • Save erossignon/5b2a5ff9edf7abd72d604414def13c2b to your computer and use it in GitHub Desktop.
Save erossignon/5b2a5ff9edf7abd72d604414def13c2b to your computer and use it in GitHub Desktop.

Revisions

  1. erossignon created this gist May 27, 2020.
    161 changes: 161 additions & 0 deletions get_endpoints.ts
    Original file line number Diff line number Diff line change
    @@ -0,0 +1,161 @@
    #!/usr/bin/env ts-node
    // tslint:disable:no-console
    import * as chalk from "chalk";
    import * as fs from "fs";
    import * as path from "path";
    import * as yargs from "yargs";

    import {
    ApplicationType,
    coerceMessageSecurityMode,
    coerceSecurityPolicy,
    MessageSecurityMode,
    OPCUAClient,
    OPCUAClientOptions,
    SecurityPolicy,
    } from "node-opcua";
    import { Certificate, toPem } from "node-opcua-crypto";

    // tslint:disable:no-var-requires
    const Table = require("easy-table");
    const treeify = require("treeify");

    // ts-node bin/simple_client.ts --endpoint opc.tcp://localhost:53530/OPCUA/SimulationServer --node "ns=5;s=Sinusoid1"
    const argv = yargs(process.argv)
    .wrap(132)

    .option("endpoint", {
    alias: "e",
    demandOption: true,
    describe: "the end point to connect to "
    })
    .option("securityMode", {
    alias: "s",
    default: "None",
    describe: "the security mode ( None Sign SignAndEncrypt )"
    })
    .option("securityPolicy", {
    alias: "P",
    default: "None",
    describe: "the policy mode : (" + Object.keys(SecurityPolicy).join(" - ") + ")"
    })
    .option("discovery", {
    alias: "D",
    describe: "specify the endpoint uri of discovery server (by default same as server endpoint uri)"
    })
    .example("get_endpoints --endpoint opc.tcp://localhost:49230", "")
    .argv;

    const securityMode = coerceMessageSecurityMode(argv.securityMode!);
    if (securityMode === MessageSecurityMode.Invalid) {
    throw new Error("Invalid Security mode");
    }

    const securityPolicy = coerceSecurityPolicy(argv.securityPolicy!);
    if (securityPolicy === SecurityPolicy.Invalid) {
    throw new Error("Invalid securityPolicy");
    }


    console.log(chalk.cyan("securityMode = "), securityMode.toString());
    console.log(chalk.cyan("securityPolicy = "), securityPolicy.toString());

    const endpointUrl = argv.endpoint as string;

    if (!endpointUrl) {
    yargs.showHelp();
    process.exit(0);
    }
    const discoveryUrl = argv.discovery ? argv.discovery as string : endpointUrl;

    async function main() {

    const optionsInitial: OPCUAClientOptions = {

    securityMode,
    securityPolicy,

    endpoint_must_exist: false,

    connectionStrategy: {
    initialDelay: 2000,
    maxDelay: 10 * 1000,
    maxRetry: 10
    },

    discoveryUrl
    };

    const client = OPCUAClient.create(optionsInitial);

    client.on("backoff", (retry: number, delay: number) => {
    console.log(chalk.bgWhite.yellow("backoff attempt #"), retry, " retrying in ", delay / 1000.0, " seconds");
    });

    console.log(" connecting to ", chalk.cyan.bold(endpointUrl));
    console.log(" strategy", client.connectionStrategy);

    try {
    await client.connect(endpointUrl);
    } catch (err) {
    console.log(chalk.red(" Cannot connect to ") + endpointUrl);
    console.log(" Error = ", err.message);
    return;
    }

    const endpoints = await client.getEndpoints();

    if (argv.debug) {
    fs.writeFileSync("tmp/endpoints.log", JSON.stringify(endpoints, null, " "));
    console.log(treeify.asTree(endpoints, true));
    }

    const table = new Table();

    let serverCertificate: Certificate | undefined;

    let i = 0;
    for (const endpoint of endpoints) {
    table.cell("endpoint", endpoint.endpointUrl + "");
    table.cell("Application URI", endpoint.server.applicationUri);
    table.cell("Product URI", endpoint.server.productUri);
    table.cell("Application Name", endpoint.server.applicationName.text);
    table.cell("securityLevel", endpoint.securityLevel);
    table.cell("Security Mode", chalk.cyan(MessageSecurityMode[endpoint.securityMode].toString()));
    table.cell("securityPolicyUri", chalk.cyan(endpoint.securityPolicyUri));
    table.cell("Type", ApplicationType[endpoint.server.applicationType]);
    table.cell("certificate", "..." /*endpoint.serverCertificate*/);
    endpoint.server.discoveryUrls = endpoint.server.discoveryUrls || [];
    table.cell("discoveryUrls", endpoint.server.discoveryUrls.join(" - "));

    serverCertificate = endpoint.serverCertificate;

    const certificate_filename = path.join(__dirname, "../certificates/PKI/server_certificate" + i + ".pem");

    if (serverCertificate) {
    fs.writeFile(certificate_filename, toPem(serverCertificate, "CERTIFICATE"), () => {/**/
    });
    }
    table.newRow();
    i++;
    }
    console.log(table.toString());

    for (const endpoint of endpoints) {
    console.log("Identify Token for : Security Mode=", chalk.cyan(MessageSecurityMode[endpoint.securityMode].toString()), " Policy=", chalk.cyan(endpoint.securityPolicyUri));
    const table2 = new Table();
    for (const token of endpoint.userIdentityTokens!) {
    table2.cell("policyId", token.policyId);
    table2.cell("tokenType", token.tokenType.toString());
    table2.cell("issuedTokenType", token.issuedTokenType);
    table2.cell("issuerEndpointUrl", token.issuerEndpointUrl);
    table2.cell("securityPolicyUri", token.securityPolicyUri);
    table2.newRow();
    }
    console.log(table2.toString());
    }
    await client.disconnect();
    console.log("success !! ");
    process.exit(0);
    }
    main();