diff --git a/docs/opc-publisher/commandline.md b/docs/opc-publisher/commandline.md index 823c94540e..268177509c 100644 --- a/docs/opc-publisher/commandline.md +++ b/docs/opc-publisher/commandline.md @@ -18,7 +18,6 @@ When both environment variable and CLI argument are provided, the command line o ╚██████╔╝██║ ╚██████╗ ██║ ╚██████╔╝██████╔╝███████╗██║███████║██║ ██║███████╗██║ ██║ ╚═════╝ ╚═╝ ╚═════╝ ╚═╝ ╚═════╝ ╚═════╝ ╚══════╝╚═╝╚══════╝╚═╝ ╚═╝╚══════╝╚═╝ ╚═╝ 2.9.4 (.NET 8.0.1/win-x64/OPC Stack 1.5.373.3) - General ------- @@ -67,6 +66,11 @@ General reports its runtime state using a restart message. Default: `False` (disabled) + --api-key, --ApiKey=VALUE + Sets the api key that must be used to authenticate + calls on the publisher REST endpoint. + Default: `not set` (Key will be generated if not + available) --doa, --disableopenapi, --DisableOpenApiEndpoint[=VALUE] Disable the OPC Publisher Open API endpoint exposed by the built-in HTTP server. diff --git a/src/Azure.IIoT.OpcUa.Publisher.Module/src/Runtime/CommandLine.cs b/src/Azure.IIoT.OpcUa.Publisher.Module/src/Runtime/CommandLine.cs index 1d48c8eb40..31d7c8a4ca 100644 --- a/src/Azure.IIoT.OpcUa.Publisher.Module/src/Runtime/CommandLine.cs +++ b/src/Azure.IIoT.OpcUa.Publisher.Module/src/Runtime/CommandLine.cs @@ -81,6 +81,9 @@ public CommandLine(string[] args, CommandLineLogger? logger = null) { $"rs|runtimestatereporting:|{PublisherConfig.EnableRuntimeStateReportingKey}:", "Enable that when publisher starts or restarts it reports its runtime state using a restart message.\nDefault: `False` (disabled)\n", (bool? b) => this[PublisherConfig.EnableRuntimeStateReportingKey] = b?.ToString() ?? "True"}, + { $"api-key=|{PublisherConfig.ApiKeyOverrideKey}=", + "Sets the api key that must be used to authenticate calls on the publisher REST endpoint.\nDefault: `not set` (Key will be generated if not available) \n", + s => this[PublisherConfig.ApiKeyOverrideKey] = s}, { $"doa|disableopenapi:|{PublisherConfig.DisableOpenApiEndpointKey}:", "Disable the OPC Publisher Open API endpoint exposed by the built-in HTTP server.\nDefault: `False` (enabled).\n", (bool? b) => this[PublisherConfig.DisableOpenApiEndpointKey] = b?.ToString() ?? "True" }, diff --git a/src/Azure.IIoT.OpcUa.Publisher.Service.WebApi/src/Azure.IIoT.OpcUa.Publisher.Service.WebApi.csproj b/src/Azure.IIoT.OpcUa.Publisher.Service.WebApi/src/Azure.IIoT.OpcUa.Publisher.Service.WebApi.csproj index 06dfa80aba..8f1dfd407c 100644 --- a/src/Azure.IIoT.OpcUa.Publisher.Service.WebApi/src/Azure.IIoT.OpcUa.Publisher.Service.WebApi.csproj +++ b/src/Azure.IIoT.OpcUa.Publisher.Service.WebApi/src/Azure.IIoT.OpcUa.Publisher.Service.WebApi.csproj @@ -20,7 +20,7 @@ - + diff --git a/src/Azure.IIoT.OpcUa.Publisher/src/Runtime/PublisherConfig.cs b/src/Azure.IIoT.OpcUa.Publisher/src/Runtime/PublisherConfig.cs index 2abbc0fc56..b2abdffe19 100644 --- a/src/Azure.IIoT.OpcUa.Publisher/src/Runtime/PublisherConfig.cs +++ b/src/Azure.IIoT.OpcUa.Publisher/src/Runtime/PublisherConfig.cs @@ -63,6 +63,7 @@ public sealed class PublisherConfig : PostConfigureOptionBase public const string RenewTlsCertificateOnStartupKey = "RenewTlsCertificateOnStartup"; public const string DefaultTransportKey = "DefaultTransport"; public const string DefaultQualityOfServiceKey = "DefaultQualityOfService"; + public const string ApiKeyOverrideKey = "ApiKey"; #pragma warning restore CS1591 // Missing XML comment for publicly visible type or member /// @@ -380,6 +381,11 @@ public override void PostConfigure(string? name, PublisherOptions options) } options.DefaultNamespaceFormat = namespaceFormat; } + + if (options.ApiKeyOverride == null) + { + options.ApiKeyOverride = GetStringOrDefault(ApiKeyOverrideKey); + } } /// diff --git a/src/Azure.IIoT.OpcUa.Publisher/src/Runtime/PublisherOptions.cs b/src/Azure.IIoT.OpcUa.Publisher/src/Runtime/PublisherOptions.cs index 8094325082..f266529bca 100644 --- a/src/Azure.IIoT.OpcUa.Publisher/src/Runtime/PublisherOptions.cs +++ b/src/Azure.IIoT.OpcUa.Publisher/src/Runtime/PublisherOptions.cs @@ -199,5 +199,10 @@ public sealed class PublisherOptions /// Scale test option /// public int? ScaleTestCount { get; set; } + + /// + /// Allow setting or overriding the current api key + /// + public string? ApiKeyOverride { get; set; } } } diff --git a/src/Azure.IIoT.OpcUa.Publisher/src/Services/RuntimeStateReporter.cs b/src/Azure.IIoT.OpcUa.Publisher/src/Services/RuntimeStateReporter.cs index c3c5133ad3..d4947a1c19 100644 --- a/src/Azure.IIoT.OpcUa.Publisher/src/Services/RuntimeStateReporter.cs +++ b/src/Azure.IIoT.OpcUa.Publisher/src/Services/RuntimeStateReporter.cs @@ -172,9 +172,21 @@ private async Task UpdateApiKeyAndCertificateAsync() ApiKey = (string?)apiKeyStore.State[OpcUa.Constants.TwinPropertyApiKeyKey]; _logger.LogInformation("Api Key exists in {Store} store...", apiKeyStore.Name); } - else + + if (!string.IsNullOrWhiteSpace(_options.Value.ApiKeyOverride) && + ApiKey != _options.Value.ApiKeyOverride) + { + Debug.Assert(_stores.Count > 0); + _logger.LogInformation("Using Api Key provided in configuration..."); + ApiKey = _options.Value.ApiKeyOverride; + + _stores[0].State.Add(OpcUa.Constants.TwinPropertyApiKeyKey, ApiKey); + } + + if (string.IsNullOrWhiteSpace(ApiKey)) { Debug.Assert(_stores.Count > 0); + _logger.LogInformation("Generating new Api Key in {Store} store...", _stores[0].Name); ApiKey = RandomNumberGenerator.GetBytes(20).ToBase64String();