From 18d92fc5b809601d07aeda5d2727e0b29acf4aa1 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 May 2021 03:22:25 +0000 Subject: [PATCH 1/7] Bump lodash from 4.17.15 to 4.17.21 in /server Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.21. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.21) Signed-off-by: dependabot[bot] --- server/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/package-lock.json b/server/package-lock.json index 7b7eedc..955c98c 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -6483,9 +6483,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash.memoize": { "version": "4.1.2", From 9e7bc28e8cb3e24719aea5cd55e70950942ec87b Mon Sep 17 00:00:00 2001 From: Emil Hummel Date: Wed, 12 May 2021 15:52:48 +0200 Subject: [PATCH 2/7] kafka-multi-cluster (#21) --- .gitignore | 4 +- .../Features/Factories/LocalhostRestClient.cs | 8 +++- .../src/Tika.RestClient/Client.cs | 12 +++--- .../src/Tika.RestClient/ClientOptions.cs | 37 ++++++++++++++++++- .../Factories/RestClientFactory.cs | 21 ++++++++--- .../Features/Acls/AclsClient.cs | 18 +++++---- .../Features/Acls/IAclsClient.cs | 6 +-- .../Features/ApiKeys/ApiKeysClient.cs | 24 +++++++----- .../Features/ApiKeys/IApiKeysClient.cs | 6 +-- .../Features/ApiKeys/Models/ApiKey.cs | 1 + .../ServiceAccounts/IServiceAccountsClient.cs | 6 +-- .../ServiceAccounts/ServiceAccountsClient.cs | 18 +++++---- .../Features/Topics/ITopicsClient.cs | 8 ++-- .../Features/Topics/TopicsClient.cs | 21 ++++++----- .../src/Tika.RestClient/Utilities.cs | 20 ++++++++++ server/src/server/config.ts | 12 ++++++ .../server/wrapper/connected/CCloudTopics.ts | 19 +++++++--- .../connected/CcloudAccessControlLists.ts | 9 +++-- .../server/wrapper/connected/CcloudApiKeys.ts | 8 +++- .../server/wrapper/connected/CcloudCluster.ts | 6 ++- server/src/server/wrapper/definitions.d.ts | 1 + .../notConnected/NotConnectedApiKeys.ts | 3 +- 22 files changed, 195 insertions(+), 73 deletions(-) create mode 100644 server/src/server/config.ts diff --git a/.gitignore b/.gitignore index a880d96..db0d8ab 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,8 @@ # Created by https://www.gitignore.io/api/node,visualstudiocode # Edit at https://www.gitignore.io/?templates=node,visualstudiocode +.output + ### Node ### # Logs logs @@ -129,4 +131,4 @@ obj/ *.svclog *.scc -.idea \ No newline at end of file +.idea diff --git a/clients/dotnet-core-rest/src/Tika.RestClient.IntegrationTests/Features/Factories/LocalhostRestClient.cs b/clients/dotnet-core-rest/src/Tika.RestClient.IntegrationTests/Features/Factories/LocalhostRestClient.cs index e90b59e..472dbd8 100644 --- a/clients/dotnet-core-rest/src/Tika.RestClient.IntegrationTests/Features/Factories/LocalhostRestClient.cs +++ b/clients/dotnet-core-rest/src/Tika.RestClient.IntegrationTests/Features/Factories/LocalhostRestClient.cs @@ -9,8 +9,14 @@ public static class LocalhostRestClient public static IRestClient Create() { var httpClient = new HttpClient {BaseAddress = new Uri("http://localhost:3000/")}; + var clientOptions = new ClientOptions + { + TIKA_ENABLE_MULTI_CLUSTER = false, + TIKA_API_ENDPOINT = "http://localhost:3000", + TIKA_MULTI_CLUSTER_HOSTNAME_PREFIX = null + }; - var restClient = RestClientFactory.Create(httpClient); + var restClient = RestClientFactory.Create(httpClient, clientOptions); return restClient; } diff --git a/clients/dotnet-core-rest/src/Tika.RestClient/Client.cs b/clients/dotnet-core-rest/src/Tika.RestClient/Client.cs index 8399d78..024ecec 100644 --- a/clients/dotnet-core-rest/src/Tika.RestClient/Client.cs +++ b/clients/dotnet-core-rest/src/Tika.RestClient/Client.cs @@ -1,4 +1,5 @@ using System.Net.Http; +using Microsoft.Extensions.Options; using Tika.RestClient.Features.Acls; using Tika.RestClient.Features.ApiKeys; using Tika.RestClient.Features.ServiceAccounts; @@ -9,18 +10,19 @@ namespace Tika.RestClient internal class Client : IRestClient { private HttpClient _httpClient; + private ClientOptions _clientOptions; public ITopicsClient Topics { get; } public IServiceAccountsClient ServiceAccounts { get; } public IApiKeysClient ApiKeys { get; } public IAclsClient Acls { get; } - public Client(HttpClient httpClient) + public Client(HttpClient httpClient, ClientOptions clientOptions) { _httpClient = httpClient; - Topics = new TopicsClient(httpClient); - ServiceAccounts = new ServiceAccountsClient(httpClient); - ApiKeys = new ApiKeysClient(httpClient); - Acls = new AclsClient(httpClient); + Topics = new TopicsClient(httpClient, clientOptions); + ServiceAccounts = new ServiceAccountsClient(httpClient, clientOptions); + ApiKeys = new ApiKeysClient(httpClient, clientOptions); + Acls = new AclsClient(httpClient, clientOptions); } public void Dispose() diff --git a/clients/dotnet-core-rest/src/Tika.RestClient/ClientOptions.cs b/clients/dotnet-core-rest/src/Tika.RestClient/ClientOptions.cs index b7a9d2b..19b3305 100644 --- a/clients/dotnet-core-rest/src/Tika.RestClient/ClientOptions.cs +++ b/clients/dotnet-core-rest/src/Tika.RestClient/ClientOptions.cs @@ -1,3 +1,4 @@ +using System; using Microsoft.Extensions.Configuration; namespace Tika.RestClient @@ -5,12 +6,46 @@ namespace Tika.RestClient public class ClientOptions { public string TIKA_API_ENDPOINT { get; set; } + public bool TIKA_ENABLE_MULTI_CLUSTER { get; set; } + public string TIKA_MULTI_CLUSTER_HOSTNAME_PREFIX { get; set; } public ClientOptions() {} public ClientOptions(IConfiguration conf) { - TIKA_API_ENDPOINT = conf["TIKA_API_ENDPOINT"]; + // Main config + // Will be ignored if TIKA_ENABLE_MULTI_CLUSTER is enabled + TIKA_API_ENDPOINT = ConfToString(conf, "TIKA_API_ENDPOINT", null); + + // Enable features + TIKA_ENABLE_MULTI_CLUSTER = ConfToBool(conf, "TIKA_ENABLE_MULTI_CLUSTER", false); + + // Multi-cluster config + TIKA_MULTI_CLUSTER_HOSTNAME_PREFIX = ConfToString(conf, "TIKA_MULTI_CLUSTER_HOSTNAME_PREFIX", "http://tika-"); + } + + private static bool ConfToBool(IConfiguration conf, string key, bool defaultValue) + { + var val = conf[key]; + + if (bool.TryParse(val, out bool result)) + { + return result; + } + + return defaultValue; + } + + private static string ConfToString(IConfiguration conf, string key, string defaultValue) + { + var val = conf[key]; + + if (String.IsNullOrEmpty(val)) + { + return defaultValue; + } + + return val; } } } \ No newline at end of file diff --git a/clients/dotnet-core-rest/src/Tika.RestClient/Factories/RestClientFactory.cs b/clients/dotnet-core-rest/src/Tika.RestClient/Factories/RestClientFactory.cs index b9c542f..c47cdb9 100644 --- a/clients/dotnet-core-rest/src/Tika.RestClient/Factories/RestClientFactory.cs +++ b/clients/dotnet-core-rest/src/Tika.RestClient/Factories/RestClientFactory.cs @@ -6,19 +6,28 @@ namespace Tika.RestClient.Factories { public static class RestClientFactory { - public static IRestClient Create(HttpClient httpClient) + public static IRestClient Create(HttpClient httpClient, ClientOptions options, string cluster = "") { - return new Client(httpClient); + return new Client(httpClient, options); } - public static IRestClient CreateFromConfiguration(HttpClient httpClient, IOptions options) + public static IRestClient CreateFromConfiguration(HttpClient httpClient, IOptions options, string cluster = "") { - if (options.Value?.TIKA_API_ENDPOINT == null) + if (options.Value?.TIKA_API_ENDPOINT == null && options.Value?.TIKA_ENABLE_MULTI_CLUSTER != true) { throw new TikaRestClientInvalidConfigurationException("TIKA_API_ENDPOINT"); } - httpClient.BaseAddress = new Uri(options.Value?.TIKA_API_ENDPOINT); - return new Client(httpClient); + + if (options.Value?.TIKA_ENABLE_MULTI_CLUSTER == false) + { + httpClient.BaseAddress = new Uri(options.Value?.TIKA_API_ENDPOINT); + } + else + { + httpClient.BaseAddress = new Uri($"{options.Value?.TIKA_MULTI_CLUSTER_HOSTNAME_PREFIX}-{cluster}:3000"); + } + + return new Client(httpClient, options.Value); } } diff --git a/clients/dotnet-core-rest/src/Tika.RestClient/Features/Acls/AclsClient.cs b/clients/dotnet-core-rest/src/Tika.RestClient/Features/Acls/AclsClient.cs index 18f2b78..745e8f3 100644 --- a/clients/dotnet-core-rest/src/Tika.RestClient/Features/Acls/AclsClient.cs +++ b/clients/dotnet-core-rest/src/Tika.RestClient/Features/Acls/AclsClient.cs @@ -3,6 +3,7 @@ using System.Net.Http; using System.Text; using System.Threading.Tasks; +using Microsoft.Extensions.Options; using Newtonsoft.Json; using Tika.RestClient.Features.Acls.Models; @@ -12,16 +13,18 @@ public class AclsClient : IAclsClient { private const string ACLS_ROUTE = "/access-control-lists"; private readonly HttpClient _httpClient; + private readonly ClientOptions _clientOptions; - public AclsClient(HttpClient httpClient) + public AclsClient(HttpClient httpClient, ClientOptions options) { _httpClient = httpClient; + _clientOptions = options; } - public async Task> GetAllAsync() + public async Task> GetAllAsync(string clusterId = null) { var httpResponseMessage = await _httpClient.GetAsync( - new Uri(ACLS_ROUTE, UriKind.Relative) + new Uri(Utilities.MakeUrl(_clientOptions, ACLS_ROUTE, clusterId), UriKind.Absolute) ); var acls = await Utilities.Parse>(httpResponseMessage); @@ -29,7 +32,7 @@ public async Task> GetAllAsync() return acls; } - public async Task CreateAsync(AclCreateDelete aclCreateDelete) + public async Task CreateAsync(AclCreateDelete aclCreateDelete, string clusterId = null) { var payload = JsonConvert.SerializeObject(new { @@ -47,12 +50,12 @@ public async Task CreateAsync(AclCreateDelete aclCreateDelete) ); await _httpClient.PostAsync( - new Uri(ACLS_ROUTE, UriKind.Relative), + new Uri(Utilities.MakeUrl(_clientOptions, ACLS_ROUTE, clusterId), UriKind.Absolute), content ); } - public async Task DeleteAsync(AclCreateDelete aclDelete) + public async Task DeleteAsync(AclCreateDelete aclDelete, string clusterId = null) { var payload = JsonConvert.SerializeObject(new { @@ -69,9 +72,8 @@ public async Task DeleteAsync(AclCreateDelete aclDelete) "application/json" ); - var httpResponseMessage = await _httpClient.PostAsync( - new Uri(ACLS_ROUTE + "/delete", UriKind.Relative), + new Uri(Utilities.MakeUrl(_clientOptions, ACLS_ROUTE + "/delete", clusterId), UriKind.Absolute), content ); diff --git a/clients/dotnet-core-rest/src/Tika.RestClient/Features/Acls/IAclsClient.cs b/clients/dotnet-core-rest/src/Tika.RestClient/Features/Acls/IAclsClient.cs index feb578d..7d5a28b 100644 --- a/clients/dotnet-core-rest/src/Tika.RestClient/Features/Acls/IAclsClient.cs +++ b/clients/dotnet-core-rest/src/Tika.RestClient/Features/Acls/IAclsClient.cs @@ -6,8 +6,8 @@ namespace Tika.RestClient.Features.Acls { public interface IAclsClient { - Task> GetAllAsync(); - Task CreateAsync(AclCreateDelete aclCreateDelete); - Task DeleteAsync(AclCreateDelete aclDelete); + Task> GetAllAsync(string clusterId = null); + Task CreateAsync(AclCreateDelete aclCreateDelete, string clusterId = null); + Task DeleteAsync(AclCreateDelete aclDelete, string clusterId = null); } } \ No newline at end of file diff --git a/clients/dotnet-core-rest/src/Tika.RestClient/Features/ApiKeys/ApiKeysClient.cs b/clients/dotnet-core-rest/src/Tika.RestClient/Features/ApiKeys/ApiKeysClient.cs index 1cb2f4a..936bf4f 100644 --- a/clients/dotnet-core-rest/src/Tika.RestClient/Features/ApiKeys/ApiKeysClient.cs +++ b/clients/dotnet-core-rest/src/Tika.RestClient/Features/ApiKeys/ApiKeysClient.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.Linq; using System.Net.Http; using System.Text; using System.Threading.Tasks; @@ -12,24 +13,28 @@ public class ApiKeysClient : IApiKeysClient { private const string APIKEYS_ROUTE = "/api-keys"; private readonly HttpClient _httpClient; + private readonly ClientOptions _clientOptions; - public ApiKeysClient(HttpClient httpClient) + public ApiKeysClient(HttpClient httpClient, ClientOptions clientOptions) { _httpClient = httpClient; + _clientOptions = clientOptions; } - public async Task> GetAllAsync() + public async Task> GetAllAsync(string clusterId = null) { + var httpResponseMessage = await _httpClient.GetAsync( - new Uri(APIKEYS_ROUTE, UriKind.Relative) + new Uri(Utilities.MakeUrl(_clientOptions, APIKEYS_ROUTE, clusterId), UriKind.Absolute) ); - var serviceAccounts = await Utilities.Parse>(httpResponseMessage); + var apiKeys = await Utilities.Parse>(httpResponseMessage); + apiKeys = apiKeys.Where(key => key.Resource.ToLower().Equals(clusterId.ToLower())); - return serviceAccounts; + return apiKeys; } - public async Task CreateAsync(ApiKeyCreate apiKeyCreate) + public async Task CreateAsync(ApiKeyCreate apiKeyCreate, string clusterId = null) { var payload = JsonConvert.SerializeObject(new { @@ -44,7 +49,7 @@ public async Task CreateAsync(ApiKeyCreate apiKeyCreate) ); var response = await _httpClient.PostAsync( - new Uri(APIKEYS_ROUTE, UriKind.Relative), + new Uri(Utilities.MakeUrl(_clientOptions, APIKEYS_ROUTE, clusterId), UriKind.Absolute), content ); @@ -53,10 +58,11 @@ public async Task CreateAsync(ApiKeyCreate apiKeyCreate) return apiKey; } - public async Task DeleteAsync(string key) + public async Task DeleteAsync(string key, string clusterId = null) { + var httpResponseMessage = await _httpClient.DeleteAsync( - new Uri(APIKEYS_ROUTE + "/" + key, UriKind.Relative) + new Uri(Utilities.MakeUrl(_clientOptions, APIKEYS_ROUTE + "/" + key, clusterId), UriKind.Absolute) ); httpResponseMessage.EnsureSuccessStatusCode(); diff --git a/clients/dotnet-core-rest/src/Tika.RestClient/Features/ApiKeys/IApiKeysClient.cs b/clients/dotnet-core-rest/src/Tika.RestClient/Features/ApiKeys/IApiKeysClient.cs index 26e19c0..9ddd483 100644 --- a/clients/dotnet-core-rest/src/Tika.RestClient/Features/ApiKeys/IApiKeysClient.cs +++ b/clients/dotnet-core-rest/src/Tika.RestClient/Features/ApiKeys/IApiKeysClient.cs @@ -6,8 +6,8 @@ namespace Tika.RestClient.Features.ApiKeys { public interface IApiKeysClient { - Task> GetAllAsync(); - Task CreateAsync(ApiKeyCreate apiKeyCreate); - Task DeleteAsync(string key); + Task> GetAllAsync(string clusterId = null); + Task CreateAsync(ApiKeyCreate apiKeyCreate, string clusterId = null); + Task DeleteAsync(string key, string clusterId = null); } } \ No newline at end of file diff --git a/clients/dotnet-core-rest/src/Tika.RestClient/Features/ApiKeys/Models/ApiKey.cs b/clients/dotnet-core-rest/src/Tika.RestClient/Features/ApiKeys/Models/ApiKey.cs index 79ea953..2e5eaf7 100644 --- a/clients/dotnet-core-rest/src/Tika.RestClient/Features/ApiKeys/Models/ApiKey.cs +++ b/clients/dotnet-core-rest/src/Tika.RestClient/Features/ApiKeys/Models/ApiKey.cs @@ -6,5 +6,6 @@ public class ApiKey public string Secret { get; set; } public string Description { get; set; } public string Owner { get; set; } + public string Resource { get; set; } } } \ No newline at end of file diff --git a/clients/dotnet-core-rest/src/Tika.RestClient/Features/ServiceAccounts/IServiceAccountsClient.cs b/clients/dotnet-core-rest/src/Tika.RestClient/Features/ServiceAccounts/IServiceAccountsClient.cs index aec1e63..21f5066 100644 --- a/clients/dotnet-core-rest/src/Tika.RestClient/Features/ServiceAccounts/IServiceAccountsClient.cs +++ b/clients/dotnet-core-rest/src/Tika.RestClient/Features/ServiceAccounts/IServiceAccountsClient.cs @@ -6,8 +6,8 @@ namespace Tika.RestClient.Features.ServiceAccounts { public interface IServiceAccountsClient { - Task> GetAllAsync(); - Task CreateAsync(ServiceAccountCreateCommand serviceAccountCreateCommand); - Task DeleteAsync(string id); + Task> GetAllAsync(string clusterId = null); + Task CreateAsync(ServiceAccountCreateCommand serviceAccountCreateCommand, string clusterId = null); + Task DeleteAsync(string id, string clusterId = null); } } \ No newline at end of file diff --git a/clients/dotnet-core-rest/src/Tika.RestClient/Features/ServiceAccounts/ServiceAccountsClient.cs b/clients/dotnet-core-rest/src/Tika.RestClient/Features/ServiceAccounts/ServiceAccountsClient.cs index 05e78ad..9e18866 100644 --- a/clients/dotnet-core-rest/src/Tika.RestClient/Features/ServiceAccounts/ServiceAccountsClient.cs +++ b/clients/dotnet-core-rest/src/Tika.RestClient/Features/ServiceAccounts/ServiceAccountsClient.cs @@ -12,16 +12,19 @@ public class ServiceAccountsClient : IServiceAccountsClient { private const string SERVICE_ACCOUNTS_ROUTE = "/service-accounts"; private readonly HttpClient _httpClient; + private readonly ClientOptions _clientOptions; - public ServiceAccountsClient(HttpClient httpClient) + public ServiceAccountsClient(HttpClient httpClient, ClientOptions clientOptions) { _httpClient = httpClient; + _clientOptions = clientOptions; } - public async Task> GetAllAsync() + public async Task> GetAllAsync(string clusterId = null) { + var httpResponseMessage = await _httpClient.GetAsync( - new Uri(SERVICE_ACCOUNTS_ROUTE, UriKind.Relative) + new Uri(Utilities.MakeUrl(_clientOptions, SERVICE_ACCOUNTS_ROUTE, clusterId), UriKind.Absolute) ); var serviceAccounts = await Utilities.Parse>(httpResponseMessage); @@ -29,7 +32,7 @@ public async Task> GetAllAsync() return serviceAccounts; } - public async Task CreateAsync(ServiceAccountCreateCommand serviceAccountCreateCommand) + public async Task CreateAsync(ServiceAccountCreateCommand serviceAccountCreateCommand, string clusterId = null) { var payload = JsonConvert.SerializeObject(serviceAccountCreateCommand); @@ -40,7 +43,7 @@ public async Task CreateAsync(ServiceAccountCreateCommand servic ); var response = await _httpClient.PostAsync( - new Uri(SERVICE_ACCOUNTS_ROUTE, UriKind.Relative), + new Uri(Utilities.MakeUrl(_clientOptions, SERVICE_ACCOUNTS_ROUTE, clusterId), UriKind.Absolute), content ); @@ -49,10 +52,11 @@ public async Task CreateAsync(ServiceAccountCreateCommand servic return serviceAccount; } - public async Task DeleteAsync(string id) + public async Task DeleteAsync(string id, string clusterId = null) { + var httpResponseMessage = await _httpClient.DeleteAsync( - new Uri(SERVICE_ACCOUNTS_ROUTE + "/" + id, UriKind.Relative) + new Uri(Utilities.MakeUrl(_clientOptions, SERVICE_ACCOUNTS_ROUTE + "/" + id, clusterId), UriKind.Absolute) ); httpResponseMessage.EnsureSuccessStatusCode(); diff --git a/clients/dotnet-core-rest/src/Tika.RestClient/Features/Topics/ITopicsClient.cs b/clients/dotnet-core-rest/src/Tika.RestClient/Features/Topics/ITopicsClient.cs index 1ae3c9d..669ec40 100644 --- a/clients/dotnet-core-rest/src/Tika.RestClient/Features/Topics/ITopicsClient.cs +++ b/clients/dotnet-core-rest/src/Tika.RestClient/Features/Topics/ITopicsClient.cs @@ -7,11 +7,11 @@ namespace Tika.RestClient.Features.Topics { public interface ITopicsClient { - Task> GetAllAsync(); - Task DescribeAsync(string topicName); + Task> GetAllAsync(string clusterId = null); + Task DescribeAsync(string topicName, string clusterId = null); - Task CreateAsync(TopicCreate topicCreate); - Task DeleteAsync(string topicName); + Task CreateAsync(TopicCreate topicCreate, string clusterId = null); + Task DeleteAsync(string topicName, string clusterId = null); } } \ No newline at end of file diff --git a/clients/dotnet-core-rest/src/Tika.RestClient/Features/Topics/TopicsClient.cs b/clients/dotnet-core-rest/src/Tika.RestClient/Features/Topics/TopicsClient.cs index e1586be..91fc8c6 100644 --- a/clients/dotnet-core-rest/src/Tika.RestClient/Features/Topics/TopicsClient.cs +++ b/clients/dotnet-core-rest/src/Tika.RestClient/Features/Topics/TopicsClient.cs @@ -14,16 +14,18 @@ internal class TopicsClient : ITopicsClient { private const string TOPICS_ROUTE = "/topics"; private readonly HttpClient _httpClient; + private readonly ClientOptions _clientOptions; - public TopicsClient(HttpClient httpClient) + public TopicsClient(HttpClient httpClient, ClientOptions clientOptions) { _httpClient = httpClient; + _clientOptions = clientOptions; } - public async Task> GetAllAsync() + public async Task> GetAllAsync(string clusterId = null) { var httpResponseMessage = await _httpClient.GetAsync( - new Uri(TOPICS_ROUTE, UriKind.Relative) + new Uri(Utilities.MakeUrl(_clientOptions, TOPICS_ROUTE, clusterId), UriKind.Absolute) ); var topics = await Utilities.Parse>(httpResponseMessage); @@ -32,7 +34,7 @@ public async Task> GetAllAsync() } /// Thrown when topic with given name already exists - public async Task CreateAsync(TopicCreate topicCreate) + public async Task CreateAsync(TopicCreate topicCreate, string clusterId = null) { var payload = JsonConvert.SerializeObject(topicCreate); @@ -43,7 +45,7 @@ public async Task CreateAsync(TopicCreate topicCreate) ); var res = await _httpClient.PostAsync( - new Uri(TOPICS_ROUTE, UriKind.Relative), + new Uri(Utilities.MakeUrl(_clientOptions, TOPICS_ROUTE, clusterId), UriKind.Absolute), content ); @@ -58,19 +60,20 @@ public async Task CreateAsync(TopicCreate topicCreate) } } - public async Task DeleteAsync(string topicName) + public async Task DeleteAsync(string topicName, string clusterId = null) { + var httpResponseMessage = await _httpClient.DeleteAsync( - new Uri(TOPICS_ROUTE + "/" + topicName, UriKind.Relative) + new Uri(Utilities.MakeUrl(_clientOptions, TOPICS_ROUTE + "/" + topicName, clusterId), UriKind.Absolute) ); httpResponseMessage.EnsureSuccessStatusCode(); } - public async Task DescribeAsync(string topicName) + public async Task DescribeAsync(string topicName, string clusterId = null) { var httpResponseMessage = await _httpClient.GetAsync( - new Uri(TOPICS_ROUTE + "/" + topicName, UriKind.Relative) + new Uri(Utilities.MakeUrl(_clientOptions, TOPICS_ROUTE + "/" + topicName, clusterId), UriKind.Absolute) ); var topicDescription = await Utilities.Parse(httpResponseMessage); diff --git a/clients/dotnet-core-rest/src/Tika.RestClient/Utilities.cs b/clients/dotnet-core-rest/src/Tika.RestClient/Utilities.cs index 14ee411..c127ba1 100644 --- a/clients/dotnet-core-rest/src/Tika.RestClient/Utilities.cs +++ b/clients/dotnet-core-rest/src/Tika.RestClient/Utilities.cs @@ -1,3 +1,4 @@ +using System; using System.Net.Http; using System.Threading.Tasks; using Newtonsoft.Json; @@ -14,5 +15,24 @@ public static async Task Parse(HttpResponseMessage response) var data = JsonConvert.DeserializeObject(content); return data; } + + public static string MakeUrl(ClientOptions clientOptions, string path, string cluster = null) + { + if (clientOptions.TIKA_ENABLE_MULTI_CLUSTER) + { + return $"{clientOptions.TIKA_MULTI_CLUSTER_HOSTNAME_PREFIX}{cluster}:3000{path}"; + } + else + { + return $"{clientOptions.TIKA_API_ENDPOINT}{path}"; + } + } + + } + + public class UrlResult + { + public string Url { get; set; } + public UriKind UriKind { get; set; } } } \ No newline at end of file diff --git a/server/src/server/config.ts b/server/src/server/config.ts new file mode 100644 index 0000000..dbfe090 --- /dev/null +++ b/server/src/server/config.ts @@ -0,0 +1,12 @@ +export class Config { + clusterId: string; + environmentId: string; +} + +export function GetConfig() : Config { + let payload = new Config(); + payload.clusterId = process.env.TIKA_CCLOUD_CLUSTER_ID; + payload.environmentId = process.env.TIKA_CCLOUD_ENVIRONMENT_ID + + return payload; +} \ No newline at end of file diff --git a/server/src/server/wrapper/connected/CCloudTopics.ts b/server/src/server/wrapper/connected/CCloudTopics.ts index 5c61b62..e5c2c35 100644 --- a/server/src/server/wrapper/connected/CCloudTopics.ts +++ b/server/src/server/wrapper/connected/CCloudTopics.ts @@ -1,13 +1,14 @@ import { parse, parseTopicDescription } from "./../parser"; import { executeCli } from "./executeCli"; import { TopicAlreadyExistsException } from "../model/error"; - +import { GetConfig } from "../../config"; export class CcloudTopics implements Topics { async getTopics(): Promise { + let config = GetConfig(); - let result = await executeCli(["kafka", "topic", "list", "--cluster", process.env.TIKA_CCLOUD_CLUSTER_ID]); + let result = await executeCli(["kafka", "topic", "list", "--cluster", config.clusterId, "--environment", config.environmentId]); result = parse(result) .filter(t => t.Name.startsWith("_confluent") === false) @@ -17,7 +18,8 @@ export class CcloudTopics implements Topics { } async describeTopic(name: string): Promise { - let consoleLines = await executeCli(["kafka", "topic", "describe", name, "--cluster", process.env.TIKA_CCLOUD_CLUSTER_ID]); + let config = GetConfig(); + let consoleLines = await executeCli(["kafka", "topic", "describe", name, "--cluster", config.clusterId, "--environment", config.environmentId]); var topic = parseTopicDescription(consoleLines); @@ -27,6 +29,7 @@ export class CcloudTopics implements Topics { async createTopic(topic: Topic): Promise { return await new Promise(async (resolve, reject) => { + let config = GetConfig(); try { if (topic.Configurations === undefined || topic.Configurations === null) { @@ -34,7 +37,8 @@ export class CcloudTopics implements Topics { "kafka", "topic", "create", topic.Name, "--partitions", topic.PartitionCount + "", - "--cluster", process.env.TIKA_CCLOUD_CLUSTER_ID + "--cluster", config.clusterId, + "--environment", config.environmentId ]); return resolve(); @@ -54,7 +58,8 @@ export class CcloudTopics implements Topics { "create", topic.Name, "--partitions", topic.PartitionCount + "", "--config", configsString, - "--cluster", process.env.TIKA_CCLOUD_CLUSTER_ID + "--cluster", config.clusterId, + "--environment", config.environmentId ]); return resolve(); @@ -89,10 +94,12 @@ export class CcloudTopics implements Topics { } async deleteTopic(name: string): Promise { + let config = GetConfig(); await executeCli([ "kafka", "topic", "delete", name, - "--cluster", process.env.TIKA_CCLOUD_CLUSTER_ID + "--cluster", config.clusterId, + "--environment", config.environmentId ]); } } diff --git a/server/src/server/wrapper/connected/CcloudAccessControlLists.ts b/server/src/server/wrapper/connected/CcloudAccessControlLists.ts index c0fcd8e..a265341 100644 --- a/server/src/server/wrapper/connected/CcloudAccessControlLists.ts +++ b/server/src/server/wrapper/connected/CcloudAccessControlLists.ts @@ -1,10 +1,11 @@ import { parse } from "./../parser"; import { executeCli } from "./executeCli"; - +import { GetConfig } from "../../config"; export class CcloudAccessControlLists implements AccessControlLists { async getAccessControlLists(): Promise { - let result = await executeCli(["kafka", "acl", "list", "--cluster", process.env.TIKA_CCLOUD_CLUSTER_ID]); + let config = GetConfig(); + let result = await executeCli(["kafka", "acl", "list", "--cluster", config.clusterId, "--environment", config.environmentId]); let resultObjects = parse(result) as AccessControlList[]; resultObjects.forEach(elem => { @@ -62,9 +63,11 @@ export class CcloudAccessControlLists implements AccessControlLists { topicPrefix: string, consumerGroupPrefix: string ): string[] { + let config = GetConfig(); let command = [ "kafka", "acl", createOrDelete, - "--cluster", process.env.TIKA_CCLOUD_CLUSTER_ID, + "--cluster", config.clusterId, + "--environment", config.environmentId, "--service-account", serviceAccountId + "", "--operation", operation ]; diff --git a/server/src/server/wrapper/connected/CcloudApiKeys.ts b/server/src/server/wrapper/connected/CcloudApiKeys.ts index 9a7f4cc..e9916a8 100644 --- a/server/src/server/wrapper/connected/CcloudApiKeys.ts +++ b/server/src/server/wrapper/connected/CcloudApiKeys.ts @@ -1,14 +1,18 @@ import { parse, parseSideColumns } from "./../parser"; import {executeCli } from "./executeCli"; +import { GetConfig } from "../../config"; export class CcloudApiKeys implements ApiKeys { ccloud: CCloudCliWrapper; async createApiKey(serviceAccountId: number, description: string): Promise { + let config = GetConfig(); + let cliOutput = await executeCli([ "api-key", "create", - "--resource", process.env.TIKA_CCLOUD_CLUSTER_ID, + "--resource", config.clusterId, + "--environment", config.environmentId, "--service-account", serviceAccountId + "", "--description", description] ); @@ -27,7 +31,7 @@ export class CcloudApiKeys implements ApiKeys { let cliObjects = parse(cliOutput); let apiKeys = cliObjects.map(function (obj) { - return { Key: obj.Key, Description: obj.Description, Owner: obj.Owner } as ApiKey + return { Key: obj.Key, Description: obj.Description, Owner: obj.Owner, Resource: obj.ResourceID } as ApiKey }); return apiKeys; diff --git a/server/src/server/wrapper/connected/CcloudCluster.ts b/server/src/server/wrapper/connected/CcloudCluster.ts index 5ce1563..316aabe 100644 --- a/server/src/server/wrapper/connected/CcloudCluster.ts +++ b/server/src/server/wrapper/connected/CcloudCluster.ts @@ -1,10 +1,14 @@ import { parse, parseSideColumns } from "./../parser"; import {executeCli } from "./executeCli"; +import { GetConfig } from "../../config"; + export class CcloudCluster { ccloud: CCloudCliWrapper; async list(): Promise { - let result = await executeCli(["kafka", "cluster", "list"]); + let config = GetConfig(); + + let result = await executeCli(["kafka", "cluster", "list", "--environment", config.environmentId]); parse(result); console.log("\n::SEP::\n"); console.log(result); diff --git a/server/src/server/wrapper/definitions.d.ts b/server/src/server/wrapper/definitions.d.ts index 5c0ff07..d262e35 100644 --- a/server/src/server/wrapper/definitions.d.ts +++ b/server/src/server/wrapper/definitions.d.ts @@ -19,6 +19,7 @@ type ApiKey = { Key: string; Description: string; Owner: string; + Resource: string; } type AccessControlList = { diff --git a/server/src/server/wrapper/notConnected/NotConnectedApiKeys.ts b/server/src/server/wrapper/notConnected/NotConnectedApiKeys.ts index 71070d3..bc3dda6 100644 --- a/server/src/server/wrapper/notConnected/NotConnectedApiKeys.ts +++ b/server/src/server/wrapper/notConnected/NotConnectedApiKeys.ts @@ -21,7 +21,8 @@ export class NotConnectedApiKeys implements ApiKeys { let apiKey: ApiKey = { Key: key, Description: description, - Owner: serviceAccountId.toString() + Owner: serviceAccountId.toString(), + Resource: "" }; this.apiKeys.push(apiKey); From 82ec7fd8381e994b740c710b780cbffab0d3358a Mon Sep 17 00:00:00 2001 From: Emil Hummel Date: Wed, 19 May 2021 15:13:15 +0200 Subject: [PATCH 3/7] Feat/updated deletion script to support multi cluster (#24) * Updated remove-topics.ps1 with multi cluster support * Added remove-topics-from-capsvc.ps1 script --- scripts/remove-topics-from-capsvc.ps1 | 45 +++++++++++++++++++++++++++ scripts/remove-topics.ps1 | 24 +++++--------- scripts/topics.csv | 1 + 3 files changed, 54 insertions(+), 16 deletions(-) create mode 100644 scripts/remove-topics-from-capsvc.ps1 create mode 100644 scripts/topics.csv diff --git a/scripts/remove-topics-from-capsvc.ps1 b/scripts/remove-topics-from-capsvc.ps1 new file mode 100644 index 0000000..f920ee9 --- /dev/null +++ b/scripts/remove-topics-from-capsvc.ps1 @@ -0,0 +1,45 @@ +[CmdletBinding()] + +param( + [Parameter(Mandatory = $False, Position = 0, ValueFromPipeline = $false)] + [string] + $TopicsPath = "", + + [Parameter(Mandatory = $False, Position = 1, ValueFromPipeline = $false)] + [switch] + $DisableDryRun = $false, + + [Parameter(Mandatory = $False, Position = 2, ValueFromPipeline = $false)] + [string] + $Token = "", + + [Parameter(Mandatory = $False, Position = 3, ValueFromPipeline = $false)] + [string] + $CapsvcEndpoint = "" +) + +$Topics = Get-Content $TopicsPath | Out-String | ConvertFrom-Csv + +if ($DisableDryRun) { + + Write-Host "Topics:`n" + foreach ($Topic in $topics) { + Write-Host $Topic + $headers=@{} + $headers.Add("authorization", "Bearer $($Token)") + Invoke-WebRequest -Uri "$($CapsvcEndpoint)/api/v1/topics/$($Topic.name)?clusterId=$($Topic.clusterUUID)" -Method DELETE -Headers $headers + } + + Write-Host "`n" + +} else { + Write-Host "::DryRun::`n" + + Write-Host "CapSvc endpoint: $($CapsvcEndpoint)" + + Write-Host "Topics to be deleted:" + foreach ($Topic in $Topics) { + Write-Host "$($Topic.name) - $($Topic.clusterUUID)" + } + +} \ No newline at end of file diff --git a/scripts/remove-topics.ps1 b/scripts/remove-topics.ps1 index bfb2421..526b854 100644 --- a/scripts/remove-topics.ps1 +++ b/scripts/remove-topics.ps1 @@ -2,37 +2,29 @@ param( [Parameter(Mandatory = $False, Position = 0, ValueFromPipeline = $false)] - [string[]] - $Topics = "", - - [Parameter(Mandatory = $False, Position = 1, ValueFromPipeline = $false)] [string] - $Cluster = "", + $TopicsPath = "", - [Parameter(Mandatory = $False, Position = 2, ValueFromPipeline = $false)] + [Parameter(Mandatory = $False, Position = 1, ValueFromPipeline = $false)] [switch] $DisableDryRun = $false ) +$Topics = Get-Content $TopicsPath | Out-String | ConvertFrom-Csv + + if ($DisableDryRun) { Write-Host "Topics:`n" foreach ($Topic in $topics) { Write-Host $Topic - Invoke-Expression "ccloud kafka topic delete $($Topic) --cluster $($Cluster)" + Invoke-Expression "ccloud kafka topic delete $($Topic.name) --cluster $($Topic.clusterId) --environment $($Topic.environmentId)" } Write-Host "`n" } else { - Write-Host "::DryRun::`n`n" - - Write-Host "Topics to be deleted:`n" - foreach ($Topic in $Topics) { - Write-Host $Topic - Write-Host "`n" - } - + Write-Host "::DryRun::`n`n" # Commands that will be run if this is the case @@ -40,7 +32,7 @@ if ($DisableDryRun) { Write-Host "Topics:`n" foreach ($Topic in $Topics) { - Write-Host "ccloud kafka topic delete $($Topic) --cluster $($Cluster)" + Write-Host "ccloud kafka topic delete $($Topic.name) --cluster $($Topic.clusterId) --environment $($Topic.environmentId)" } } \ No newline at end of file diff --git a/scripts/topics.csv b/scripts/topics.csv new file mode 100644 index 0000000..20c8438 --- /dev/null +++ b/scripts/topics.csv @@ -0,0 +1 @@ +name,clusterUUID,clusterId,environmentId \ No newline at end of file From d9591d1511defb82bb9872d270a7a0a45c1c6556 Mon Sep 17 00:00:00 2001 From: Emil Hummel Date: Tue, 24 Aug 2021 21:00:39 +0200 Subject: [PATCH 4/7] Added healthcheck & metrics (#27) * Added healthcheck & metrics * Use Python 3.X for awscli due to awscli deprecating 2.x support --- azure-pipelines.yml | 4 +- server/package-lock.json | 292 ++++++++++++++++++++++++++++++++++++- server/package.json | 4 +- server/src/server/index.ts | 32 +++- 4 files changed, 323 insertions(+), 9 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index 7c650b6..fd16dad 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -24,8 +24,8 @@ steps: - bash: | set -eu -o pipefail - sudo pip install setuptools - sudo pip install awscli + sudo pip3 install setuptools + sudo pip3 install awscli export AWS_SECRET_ACCESS_KEY=$(AWS_SECRET_ACCESS_KEY) cp ${DOWNLOADSECUREFILE_SECUREFILEPATH} ./ccloud-config diff --git a/server/package-lock.json b/server/package-lock.json index 7b7eedc..f5b4d87 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -1150,6 +1150,87 @@ "@types/yargs": "^13.0.0" } }, + "@sentry/core": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@sentry/core/-/core-6.11.0.tgz", + "integrity": "sha512-09TB+f3pqEq8LFahFWHO6I/4DxHo+NcS52OkbWMDqEi6oNZRD7PhPn3i14LfjsYVv3u3AESU8oxSEGbFrr2UjQ==", + "requires": { + "@sentry/hub": "6.11.0", + "@sentry/minimal": "6.11.0", + "@sentry/types": "6.11.0", + "@sentry/utils": "6.11.0", + "tslib": "^1.9.3" + } + }, + "@sentry/hub": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@sentry/hub/-/hub-6.11.0.tgz", + "integrity": "sha512-pT9hf+ZJfVFpoZopoC+yJmFNclr4NPqPcl2cgguqCHb69DklD1NxgBNWK8D6X05qjnNFDF991U6t1mxP9HrGuw==", + "requires": { + "@sentry/types": "6.11.0", + "@sentry/utils": "6.11.0", + "tslib": "^1.9.3" + } + }, + "@sentry/minimal": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@sentry/minimal/-/minimal-6.11.0.tgz", + "integrity": "sha512-XkZ7qrdlGp4IM/gjGxf1Q575yIbl5RvPbg+WFeekpo16Ufvzx37Mr8c2xsZaWosISVyE6eyFpooORjUlzy8EDw==", + "requires": { + "@sentry/hub": "6.11.0", + "@sentry/types": "6.11.0", + "tslib": "^1.9.3" + } + }, + "@sentry/node": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@sentry/node/-/node-6.11.0.tgz", + "integrity": "sha512-vbk+V/n7ZIFD8rHPYy03t/gIG5V7LGdjU4qJxVDgNZzticfWPnd2sLgle/r+l60XF6SKW/epG4rnxnBcgPdWaw==", + "requires": { + "@sentry/core": "6.11.0", + "@sentry/hub": "6.11.0", + "@sentry/tracing": "6.11.0", + "@sentry/types": "6.11.0", + "@sentry/utils": "6.11.0", + "cookie": "^0.4.1", + "https-proxy-agent": "^5.0.0", + "lru_map": "^0.3.3", + "tslib": "^1.9.3" + }, + "dependencies": { + "cookie": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.1.tgz", + "integrity": "sha512-ZwrFkGJxUR3EIoXtO+yVE69Eb7KlixbaeAWfBQB9vVsNn/o+Yw69gBWSSDK825hQNdN+wF8zELf3dFNl/kxkUA==" + } + } + }, + "@sentry/tracing": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@sentry/tracing/-/tracing-6.11.0.tgz", + "integrity": "sha512-9VA1/SY++WeoMQI4K6n/sYgIdRtCu9NLWqmGqu/5kbOtESYFgAt1DqSyqGCr00ZjQiC2s7tkDkTNZb38K6KytQ==", + "requires": { + "@sentry/hub": "6.11.0", + "@sentry/minimal": "6.11.0", + "@sentry/types": "6.11.0", + "@sentry/utils": "6.11.0", + "tslib": "^1.9.3" + } + }, + "@sentry/types": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@sentry/types/-/types-6.11.0.tgz", + "integrity": "sha512-gm5H9eZhL6bsIy/h3T+/Fzzz2vINhHhqd92CjHle3w7uXdTdFV98i2pDpErBGNTSNzbntqOMifYEB5ENtZAvcg==" + }, + "@sentry/utils": { + "version": "6.11.0", + "resolved": "https://registry.npmjs.org/@sentry/utils/-/utils-6.11.0.tgz", + "integrity": "sha512-IOvyFHcnbRQxa++jO+ZUzRvFHEJ1cZjrBIQaNVc0IYF0twUOB5PTP6joTcix38ldaLeapaPZ9LGfudbvYvxkdg==", + "requires": { + "@sentry/types": "6.11.0", + "tslib": "^1.9.3" + } + }, "@types/babel__core": { "version": "7.1.3", "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.3.tgz", @@ -1277,9 +1358,9 @@ "integrity": "sha512-FwI9gX75FgVBJ7ywgnq/P7tw+/o1GUbtP0KzbtusLigAOgIgNISRK0ZPl4qertvXSIE8YbsVJueQ90cDt9YYyw==" }, "@types/node": { - "version": "12.12.17", - "resolved": "https://registry.npmjs.org/@types/node/-/node-12.12.17.tgz", - "integrity": "sha512-Is+l3mcHvs47sKy+afn2O1rV4ldZFU7W8101cNlOd+MRbjM4Onida8jSZnJdTe/0Pcf25g9BNIUsuugmE6puHA==" + "version": "12.20.20", + "resolved": "https://registry.npmjs.org/@types/node/-/node-12.20.20.tgz", + "integrity": "sha512-kqmxiJg4AT7rsSPIhO6eoBIx9mNwwpeH42yjtgQh6X2ANSpLpvToMXv+LMFdfxpwG1FZXZ41OGZMiUAtbBLEvg==" }, "@types/range-parser": { "version": "1.2.3", @@ -1609,6 +1690,14 @@ "integrity": "sha512-7evsyfH1cLOCdAzZAd43Cic04yKydNx0cF+7tiA19p1XnLLPU4dpCQOqpjqwokFe//vS0QqfqqjCS2JkiIs0cA==", "dev": true }, + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "requires": { + "debug": "4" + } + }, "ajv": { "version": "6.10.2", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.2.tgz", @@ -2106,6 +2195,11 @@ "file-uri-to-path": "1.0.0" } }, + "bintrees": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/bintrees/-/bintrees-1.0.1.tgz", + "integrity": "sha1-DmVcm5wkNeqraL9AJyJtK1WjRSQ=" + }, "bluebird": { "version": "3.7.2", "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.7.2.tgz", @@ -2148,6 +2242,11 @@ } } }, + "boolean": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/boolean/-/boolean-3.1.4.tgz", + "integrity": "sha512-3hx0kwU3uzG6ReQ3pnaFQPSktpBw6RHN3/ivDKEuU8g1XSfafowyvDnadjv1xp8IZqhtSukxlwv9bF6FhX8m0w==" + }, "boxen": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/boxen/-/boxen-1.3.0.tgz", @@ -3001,6 +3100,11 @@ "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", "dev": true }, + "deepmerge": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.2.2.tgz", + "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==" + }, "define-properties": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", @@ -3046,6 +3150,11 @@ } } }, + "delay": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/delay/-/delay-5.0.0.tgz", + "integrity": "sha512-ReEBKkIfe4ya47wlPYf/gu5ib6yUG0/Aez0JQZQz94kiWtRQvZIQbTiehsnwHvLSWJnQdhVeqYue7Id1dKr0qw==" + }, "delayed-stream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz", @@ -3082,6 +3191,11 @@ "integrity": "sha1-9B8cEL5LAOh7XxPaaAdZ8sW/0+I=", "dev": true }, + "detect-node": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/detect-node/-/detect-node-2.1.0.tgz", + "integrity": "sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==" + }, "diff": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", @@ -3656,6 +3770,15 @@ "uuid.v4": "^1.0.0" } }, + "express-prom-bundle": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/express-prom-bundle/-/express-prom-bundle-6.4.1.tgz", + "integrity": "sha512-Sg0svLQe/SS5z1tHDTVfZVjNumobiDlXM0jmemt5Dm9K6BX8z9yCwEr93zbko6fNMR4zKav77iPfxUWi6gAjNA==", + "requires": { + "on-finished": "^2.3.0", + "url-value-parser": "^2.0.0" + } + }, "extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -3773,12 +3896,49 @@ "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=" }, + "fast-json-stringify": { + "version": "2.7.8", + "resolved": "https://registry.npmjs.org/fast-json-stringify/-/fast-json-stringify-2.7.8.tgz", + "integrity": "sha512-HRSGwEWe0/5EH7GEaWg1by4dInnBb1WFf4umMPr+lL5xb0VP0VbpNGklp4L0/BseD+BmtIZpjqJjnLFwaQ21dg==", + "requires": { + "ajv": "^6.11.0", + "deepmerge": "^4.2.2", + "rfdc": "^1.2.0", + "string-similarity": "^4.0.1" + }, + "dependencies": { + "ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "requires": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "fast-deep-equal": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" + } + } + }, "fast-levenshtein": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", "dev": true }, + "fast-printf": { + "version": "1.6.9", + "resolved": "https://registry.npmjs.org/fast-printf/-/fast-printf-1.6.9.tgz", + "integrity": "sha512-FChq8hbz65WMj4rstcQsFB0O7Cy++nmbNfLYnD9cYv2cRn8EG6k/MGn9kO/tjO66t09DLDugj3yL+V2o6Qftrg==", + "requires": { + "boolean": "^3.1.4" + } + }, "fb-watchman": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.1.tgz", @@ -4696,6 +4856,14 @@ "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==" }, + "globalthis": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.2.tgz", + "integrity": "sha512-ZQnSFO1la8P7auIOQECnm0sSuoMeaSq0EEdXMBFF2QJO4uNcwbyhSgG3MruWNbFTqCLmxVwGOl7LZ9kASvHdeQ==", + "requires": { + "define-properties": "^1.1.3" + } + }, "got": { "version": "6.7.1", "resolved": "https://registry.npmjs.org/got/-/got-6.7.1.tgz", @@ -4903,11 +5071,37 @@ "sshpk": "^1.7.0" } }, + "http-terminator": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/http-terminator/-/http-terminator-3.0.0.tgz", + "integrity": "sha512-YdNsDQgsHuxBSOWWhkQHMgOD7c5CU3e9u+pokp9tI6BwJ8LjUhJYBO+k2a3NXoDXbToSm7OQk4RzNTooPQP5IQ==", + "requires": { + "delay": "^5.0.0", + "roarr": "^4.0.10", + "type-fest": "^0.20.2" + }, + "dependencies": { + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + } + } + }, "https-browserify": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/https-browserify/-/https-browserify-1.0.0.tgz", "integrity": "sha1-7AbBDgo0wPL68Zn3/X/Hj//QPHM=" }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "requires": { + "agent-base": "6", + "debug": "4" + } + }, "iconv-lite": { "version": "0.4.24", "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", @@ -5147,6 +5341,11 @@ "ci-info": "^1.5.0" } }, + "is-circular": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-circular/-/is-circular-1.0.2.tgz", + "integrity": "sha512-YttjnrswnUYRVJvxCvu8z+PGMUSzC2JttP0OEXezlAEdp3EXzhf7IZ3j0gRAybJBQupedIZFhY61Tga6E0qASA==" + }, "is-data-descriptor": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", @@ -6355,8 +6554,7 @@ "json-stringify-safe": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz", - "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=", - "dev": true + "integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=" }, "json5": { "version": "2.1.1", @@ -6428,6 +6626,19 @@ "type-check": "~0.3.2" } }, + "lightship": { + "version": "6.7.2", + "resolved": "https://registry.npmjs.org/lightship/-/lightship-6.7.2.tgz", + "integrity": "sha512-13V+ZiElVx+IpxrJ3jJjfVIID9p0tfhmeqrfMi7IdWuM8tKTmhS8CAGHTUzQM9bvB19/TsztTghYXyJf5j7s5A==", + "requires": { + "@sentry/node": "^6.2.5", + "delay": "^5.0.0", + "express": "^4.17.1", + "http-terminator": "^3.0.0", + "roarr": "^4.2.5", + "serialize-error": "^8.0.1" + } + }, "load-json-file": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-4.0.0.tgz", @@ -6536,6 +6747,11 @@ "yallist": "^3.0.2" } }, + "lru_map": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/lru_map/-/lru_map-0.3.3.tgz", + "integrity": "sha1-tcg1G5Rky9dQM1p5ZQoOwOVhGN0=" + }, "make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", @@ -7605,6 +7821,14 @@ "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", "dev": true }, + "prom-client": { + "version": "13.2.0", + "resolved": "https://registry.npmjs.org/prom-client/-/prom-client-13.2.0.tgz", + "integrity": "sha512-wGr5mlNNdRNzEhRYXgboUU2LxHWIojxscJKmtG3R8f4/KiWqyYgXTLHs0+Ted7tG3zFT7pgHJbtomzZ1L0ARaQ==", + "requires": { + "tdigest": "^0.1.1" + } + }, "promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", @@ -8195,6 +8419,11 @@ "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==" }, + "rfdc": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/rfdc/-/rfdc-1.3.0.tgz", + "integrity": "sha512-V2hovdzFbOi77/WajaSMXk2OLm+xNIeQdMMuB7icj7bk6zi2F8GGAxigcnDFpJHbNyNcgyJDiP+8nOrY5cZGrA==" + }, "rimraf": { "version": "2.7.1", "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", @@ -8212,6 +8441,21 @@ "inherits": "^2.0.1" } }, + "roarr": { + "version": "4.2.5", + "resolved": "https://registry.npmjs.org/roarr/-/roarr-4.2.5.tgz", + "integrity": "sha512-ZSs1hr2gyWickWDr2Yw0qcuef+EJKwZtNxUj7poxvIDxVq+ZvQreVNdPVLHonWpavBeZaOcAGVFV5xM/HqRR8g==", + "requires": { + "boolean": "^3.0.2", + "detect-node": "^2.0.5", + "fast-json-stringify": "^2.5.2", + "fast-printf": "^1.6.4", + "globalthis": "^1.0.2", + "is-circular": "^1.0.2", + "json-stringify-safe": "^5.0.1", + "semver-compare": "^1.0.0" + } + }, "rsvp": { "version": "4.8.5", "resolved": "https://registry.npmjs.org/rsvp/-/rsvp-4.8.5.tgz", @@ -8405,6 +8649,11 @@ "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==" }, + "semver-compare": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/semver-compare/-/semver-compare-1.0.0.tgz", + "integrity": "sha1-De4hahyUGrN+nvsXiPavxf9VN/w=" + }, "semver-diff": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/semver-diff/-/semver-diff-2.1.0.tgz", @@ -8456,6 +8705,21 @@ } } }, + "serialize-error": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/serialize-error/-/serialize-error-8.1.0.tgz", + "integrity": "sha512-3NnuWfM6vBYoy5gZFvHiYsVbafvI9vZv/+jlIigFn4oP4zjNPK3LhcY0xSCgeb1a5L8jO71Mit9LlNoi2UfDDQ==", + "requires": { + "type-fest": "^0.20.2" + }, + "dependencies": { + "type-fest": { + "version": "0.20.2", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", + "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==" + } + } + }, "serialize-javascript": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/serialize-javascript/-/serialize-javascript-2.1.2.tgz", @@ -8886,6 +9150,11 @@ } } }, + "string-similarity": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/string-similarity/-/string-similarity-4.0.4.tgz", + "integrity": "sha512-/q/8Q4Bl4ZKAPjj8WerIBJWALKkaPRfrvhfF8k/B23i4nzrlRj2/go1m90In7nG/3XDSbOo0+pu6RvCTM9RGMQ==" + }, "string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -8989,6 +9258,14 @@ "resolved": "https://registry.npmjs.org/tapable/-/tapable-1.1.3.tgz", "integrity": "sha512-4WK/bYZmj8xLr+HUCODHGF1ZFzsYffasLUgEiMBY4fgtltdO6B4WJtlSbPaDTLpYTcGVwM2qLnFTICEcNxs3kA==" }, + "tdigest": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/tdigest/-/tdigest-0.1.1.tgz", + "integrity": "sha1-Ljyyw56kSeVdHmzZEReszKRYgCE=", + "requires": { + "bintrees": "1.0.1" + } + }, "term-size": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/term-size/-/term-size-1.2.0.tgz", @@ -9616,6 +9893,11 @@ "prepend-http": "^1.0.1" } }, + "url-value-parser": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/url-value-parser/-/url-value-parser-2.0.3.tgz", + "integrity": "sha512-FjIX+Q9lYmDM9uYIGdMYfQW0uLbWVwN2NrL2ayAI7BTOvEwzH+VoDdNquwB9h4dFAx+u6mb0ONLa3sHD5DvyvA==" + }, "use": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", diff --git a/server/package.json b/server/package.json index bb05aac..ff937af 100644 --- a/server/package.json +++ b/server/package.json @@ -26,13 +26,14 @@ "@babel/core": "^7.7.5", "@babel/preset-env": "^7.7.6", "@types/express": "^4.17.2", - "@types/node": "^12.12.17", "@typescript-eslint/eslint-plugin": "^2.11.0", "@typescript-eslint/parser": "^2.11.0", "babel-loader": "^8.0.6", "express": "^4.17.1", "express-mw-correlation-id": "^5.2.0", + "express-prom-bundle": "^6.4.1", "prettier": "^1.19.1", + "prom-client": "^13.2.0", "regenerator-runtime": "^0.13.3", "ts-loader": "^6.2.1", "typescript": "^3.7.3", @@ -41,6 +42,7 @@ }, "devDependencies": { "@types/jest": "^24.0.23", + "@types/node": "^12.20.20", "eslint": "^6.7.2", "eslint-plugin-prettier": "^3.1.1", "jest": "^24.9.0", diff --git a/server/src/server/index.ts b/server/src/server/index.ts index bc788b0..93f88be 100644 --- a/server/src/server/index.ts +++ b/server/src/server/index.ts @@ -9,16 +9,33 @@ import { RequestError } from "./api/middleware/requestErrorMiddleware"; import { ResponseLogger } from "./api/middleware/responseLoggerMiddleware"; const express = require("express"); const setCorrelationId = require('express-mw-correlation-id'); +const promBundle = require("express-prom-bundle"); +import * as promClient from 'prom-client'; +import { GetConfig } from "./config"; + +const promMetrics = promBundle({includePath: true}); + +const confluentUp = new promClient.Gauge( + { + name: 'tika_confluent_up', + help: 'tika_confluent_up_help', + labelNames: ['kafkaCluster'] + } +); const app = express(); app.use(setCorrelationId()); +app.use(promMetrics); app.use(express.json()); app.use(RequestLogger); app.use(ResponseLogger); + var cc: CCloudCliWrapper; const apiImplementationToUse = process.env.TIKA_API_IMPLEMENTATION || "connected"; +const appConfig = GetConfig(); + console.info("Using api implementation:", apiImplementationToUse); switch (apiImplementationToUse.valueOf()) { @@ -32,6 +49,19 @@ switch (apiImplementationToUse.valueOf()) { cc = new Ccloud(); } +// Healthcheck +app.get("/healthz", async (_ : any, res : any) => { + try { + let topics = await cc.Kafka.Topics.getTopics(); + confluentUp.set({kafkaCluster: appConfig.clusterId}, 1); + res.sendStatus(200); + } catch (error) { + confluentUp.set({kafkaCluster: appConfig.clusterId}, 0); + console.log("Health check error: ", error); + res.sendStatus(500); + } +}); + const serviceAccountsInterface = new ServiceAccountsInterface(); serviceAccountsInterface.configureApp( cc.ServiceAccounts, @@ -67,4 +97,4 @@ const port = process.env.port || 3000; app.listen(port, () => { console.info(`tika is listening on port ${port}...`); -}); \ No newline at end of file +}); From 000bec3f05f92b601d10f9eb824e60c437ac2a05 Mon Sep 17 00:00:00 2001 From: Emil Hummel Date: Wed, 25 Aug 2021 10:58:21 +0200 Subject: [PATCH 5/7] Use UserId column instead of ServiceAccountId due to ccloud breaking change (#29) --- .../Features/Acls/GetAllAclsScenario.cs | 2 +- .../src/Tika.RestClient/Features/Acls/Models/Acl.cs | 3 ++- .../src/server/wrapper/connected/CcloudAccessControlLists.ts | 2 +- server/src/server/wrapper/definitions.d.ts | 1 + .../wrapper/notConnected/NotConnectedAccessControlLists.ts | 1 + 5 files changed, 6 insertions(+), 3 deletions(-) diff --git a/clients/dotnet-core-rest/src/Tika.RestClient.IntegrationTests/Features/Acls/GetAllAclsScenario.cs b/clients/dotnet-core-rest/src/Tika.RestClient.IntegrationTests/Features/Acls/GetAllAclsScenario.cs index fc046ae..3cc5713 100644 --- a/clients/dotnet-core-rest/src/Tika.RestClient.IntegrationTests/Features/Acls/GetAllAclsScenario.cs +++ b/clients/dotnet-core-rest/src/Tika.RestClient.IntegrationTests/Features/Acls/GetAllAclsScenario.cs @@ -60,7 +60,7 @@ private void Then_the_acl_is_returned() .Where(acl => acl.Operation == _aclCreateDelete.Operation) .Where(acl => acl.Name == _aclCreateDelete.TopicPrefix) .Where(acl => acl.ConsumerGroupPrefix == _aclCreateDelete.ConsumerGroupPrefix) - .Single(acl => acl.ServiceAccountId == _aclCreateDelete.ServiceAccountId); + .Single(acl => acl.UserId == _aclCreateDelete.ServiceAccountId); } } } \ No newline at end of file diff --git a/clients/dotnet-core-rest/src/Tika.RestClient/Features/Acls/Models/Acl.cs b/clients/dotnet-core-rest/src/Tika.RestClient/Features/Acls/Models/Acl.cs index 933bda5..a286372 100644 --- a/clients/dotnet-core-rest/src/Tika.RestClient/Features/Acls/Models/Acl.cs +++ b/clients/dotnet-core-rest/src/Tika.RestClient/Features/Acls/Models/Acl.cs @@ -2,7 +2,8 @@ namespace Tika.RestClient.Features.Acls.Models { public class Acl { - public long ServiceAccountId { get; set; } + public long UserId { get; set; } + public string ServiceAccountId { get; set; } public string Permission { get; set; } public string Resource { get; set; } public string Operation { get; set; } diff --git a/server/src/server/wrapper/connected/CcloudAccessControlLists.ts b/server/src/server/wrapper/connected/CcloudAccessControlLists.ts index a265341..8610108 100644 --- a/server/src/server/wrapper/connected/CcloudAccessControlLists.ts +++ b/server/src/server/wrapper/connected/CcloudAccessControlLists.ts @@ -9,7 +9,7 @@ export class CcloudAccessControlLists implements AccessControlLists { let resultObjects = parse(result) as AccessControlList[]; resultObjects.forEach(elem => { - elem.ServiceAccountId = elem.ServiceAccountId.split(':')[1]; + elem.UserId = elem.UserId.split(':')[1]; }); return resultObjects; diff --git a/server/src/server/wrapper/definitions.d.ts b/server/src/server/wrapper/definitions.d.ts index d262e35..f69e8f4 100644 --- a/server/src/server/wrapper/definitions.d.ts +++ b/server/src/server/wrapper/definitions.d.ts @@ -23,6 +23,7 @@ type ApiKey = { } type AccessControlList = { + UserId: string; ServiceAccountId: string; Permission: string; Operation: string; diff --git a/server/src/server/wrapper/notConnected/NotConnectedAccessControlLists.ts b/server/src/server/wrapper/notConnected/NotConnectedAccessControlLists.ts index 4f242d2..392baec 100644 --- a/server/src/server/wrapper/notConnected/NotConnectedAccessControlLists.ts +++ b/server/src/server/wrapper/notConnected/NotConnectedAccessControlLists.ts @@ -82,6 +82,7 @@ export class NotConnectedAccessControlLists implements AccessControlLists { if (topicPrefix !== undefined) { name = topicPrefix; } else if (consumerGroupPrefix !== undefined) { name = consumerGroupPrefix } let accessControlList: AccessControlList = { + UserId: serviceAccountId + "", ServiceAccountId: serviceAccountId + "", Permission: allow ? "ALLOW" : "DENY", Operation: operation, From ea1ebc4d3cf16963b51ac5704acbae71df1c39bd Mon Sep 17 00:00:00 2001 From: Peter West Date: Mon, 6 Sep 2021 13:57:07 +0100 Subject: [PATCH 6/7] vmImage updated to ubuntu20.04 --- azure-pipelines.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/azure-pipelines.yml b/azure-pipelines.yml index fd16dad..cdeebb4 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -7,7 +7,7 @@ trigger: - master pool: - vmImage: 'Ubuntu-16.04' + vmImage: 'Ubuntu-20.04' steps: - task: InstallSSHKey@0 @@ -31,4 +31,4 @@ steps: cp ${DOWNLOADSECUREFILE_SECUREFILEPATH} ./ccloud-config cd server make release BUILD_NUMBER=$(Build.BuildId) - displayName: 'Build a deployment artifact' \ No newline at end of file + displayName: 'Build a deployment artifact' From 69629682d1176d49eb5815deba854ba375ddb193 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 11 May 2021 03:22:25 +0000 Subject: [PATCH 7/7] Bump lodash from 4.17.15 to 4.17.21 in /server Bumps [lodash](https://github.com/lodash/lodash) from 4.17.15 to 4.17.21. - [Release notes](https://github.com/lodash/lodash/releases) - [Commits](https://github.com/lodash/lodash/compare/4.17.15...4.17.21) Signed-off-by: dependabot[bot] --- server/package-lock.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/server/package-lock.json b/server/package-lock.json index f5b4d87..1b3fd96 100644 --- a/server/package-lock.json +++ b/server/package-lock.json @@ -6694,9 +6694,9 @@ } }, "lodash": { - "version": "4.17.15", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.15.tgz", - "integrity": "sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==" + "version": "4.17.21", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", + "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==" }, "lodash.memoize": { "version": "4.1.2",