@backstage/plugin-catalog-backend-module-puppetdb 0.2.3-next.0 → 0.2.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -1,5 +1,30 @@
1
1
  # @backstage/plugin-catalog-backend-module-puppetdb
2
2
 
3
+ ## 0.2.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 4b60e0c: Small tweaks to API reports to make them valid
8
+ - Updated dependencies
9
+ - @backstage/plugin-catalog-node@1.13.1
10
+ - @backstage/backend-plugin-api@1.0.1
11
+ - @backstage/catalog-model@1.7.0
12
+ - @backstage/config@1.2.0
13
+ - @backstage/errors@1.2.4
14
+ - @backstage/types@1.1.1
15
+
16
+ ## 0.2.3-next.1
17
+
18
+ ### Patch Changes
19
+
20
+ - Updated dependencies
21
+ - @backstage/plugin-catalog-node@1.13.1-next.1
22
+ - @backstage/backend-plugin-api@1.0.1-next.1
23
+ - @backstage/catalog-model@1.7.0
24
+ - @backstage/config@1.2.0
25
+ - @backstage/errors@1.2.4
26
+ - @backstage/types@1.1.1
27
+
3
28
  ## 0.2.3-next.0
4
29
 
5
30
  ### Patch Changes
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-catalog-backend-module-puppetdb__alpha",
3
- "version": "0.2.3-next.0",
3
+ "version": "0.2.3",
4
4
  "main": "../dist/alpha.cjs.js",
5
5
  "types": "../dist/alpha.d.ts"
6
6
  }
package/dist/alpha.cjs.js CHANGED
@@ -2,37 +2,9 @@
2
2
 
3
3
  Object.defineProperty(exports, '__esModule', { value: true });
4
4
 
5
- var backendPluginApi = require('@backstage/backend-plugin-api');
6
- var alpha = require('@backstage/plugin-catalog-node/alpha');
7
- var PuppetDbEntityProvider = require('./cjs/PuppetDbEntityProvider-DT7iF87I.cjs.js');
8
- require('uuid');
9
- require('@backstage/catalog-model');
10
- require('lodash');
11
- require('node-fetch');
12
- require('@backstage/errors');
5
+ var catalogModulePuppetDbEntityProvider = require('./module/catalogModulePuppetDbEntityProvider.cjs.js');
13
6
 
14
- const catalogModulePuppetDbEntityProvider = backendPluginApi.createBackendModule({
15
- pluginId: "catalog",
16
- moduleId: "puppetdb-entity-provider",
17
- register(env) {
18
- env.registerInit({
19
- deps: {
20
- catalog: alpha.catalogProcessingExtensionPoint,
21
- config: backendPluginApi.coreServices.rootConfig,
22
- logger: backendPluginApi.coreServices.logger,
23
- scheduler: backendPluginApi.coreServices.scheduler
24
- },
25
- async init({ catalog, config, logger, scheduler }) {
26
- catalog.addEntityProvider(
27
- PuppetDbEntityProvider.PuppetDbEntityProvider.fromConfig(config, {
28
- logger,
29
- scheduler
30
- })
31
- );
32
- }
33
- });
34
- }
35
- });
36
7
 
37
- exports.default = catalogModulePuppetDbEntityProvider;
8
+
9
+ exports.default = catalogModulePuppetDbEntityProvider.catalogModulePuppetDbEntityProvider;
38
10
  //# sourceMappingURL=alpha.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"alpha.cjs.js","sources":["../src/module/catalogModulePuppetDbEntityProvider.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n coreServices,\n createBackendModule,\n} from '@backstage/backend-plugin-api';\nimport { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';\nimport { PuppetDbEntityProvider } from '../providers/PuppetDbEntityProvider';\n\n/**\n * Registers the `PuppetDbEntityProvider` with the catalog processing extension point.\n *\n * @alpha\n */\nexport const catalogModulePuppetDbEntityProvider = createBackendModule({\n pluginId: 'catalog',\n moduleId: 'puppetdb-entity-provider',\n register(env) {\n env.registerInit({\n deps: {\n catalog: catalogProcessingExtensionPoint,\n config: coreServices.rootConfig,\n logger: coreServices.logger,\n scheduler: coreServices.scheduler,\n },\n async init({ catalog, config, logger, scheduler }) {\n catalog.addEntityProvider(\n PuppetDbEntityProvider.fromConfig(config, {\n logger,\n scheduler,\n }),\n );\n },\n });\n },\n});\n"],"names":["createBackendModule","catalogProcessingExtensionPoint","coreServices","PuppetDbEntityProvider"],"mappings":";;;;;;;;;;;;;AA4BO,MAAM,sCAAsCA,oCAAoB,CAAA;AAAA,EACrE,QAAU,EAAA,SAAA;AAAA,EACV,QAAU,EAAA,0BAAA;AAAA,EACV,SAAS,GAAK,EAAA;AACZ,IAAA,GAAA,CAAI,YAAa,CAAA;AAAA,MACf,IAAM,EAAA;AAAA,QACJ,OAAS,EAAAC,qCAAA;AAAA,QACT,QAAQC,6BAAa,CAAA,UAAA;AAAA,QACrB,QAAQA,6BAAa,CAAA,MAAA;AAAA,QACrB,WAAWA,6BAAa,CAAA,SAAA;AAAA,OAC1B;AAAA,MACA,MAAM,IAAK,CAAA,EAAE,SAAS,MAAQ,EAAA,MAAA,EAAQ,WAAa,EAAA;AACjD,QAAQ,OAAA,CAAA,iBAAA;AAAA,UACNC,6CAAA,CAAuB,WAAW,MAAQ,EAAA;AAAA,YACxC,MAAA;AAAA,YACA,SAAA;AAAA,WACD,CAAA;AAAA,SACH,CAAA;AAAA,OACF;AAAA,KACD,CAAA,CAAA;AAAA,GACH;AACF,CAAC;;;;"}
1
+ {"version":3,"file":"alpha.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;"}
package/dist/index.cjs.js CHANGED
@@ -1,17 +1,14 @@
1
1
  'use strict';
2
2
 
3
- var PuppetDbEntityProvider = require('./cjs/PuppetDbEntityProvider-DT7iF87I.cjs.js');
4
- require('@backstage/backend-plugin-api');
5
- require('uuid');
6
- require('@backstage/catalog-model');
7
- require('lodash');
8
- require('node-fetch');
9
- require('@backstage/errors');
3
+ var PuppetDbEntityProvider = require('./providers/PuppetDbEntityProvider.cjs.js');
4
+ var constants = require('./providers/constants.cjs.js');
5
+ var constants$1 = require('./puppet/constants.cjs.js');
6
+ var transformers = require('./puppet/transformers.cjs.js');
10
7
 
11
8
 
12
9
 
13
- exports.ANNOTATION_PUPPET_CERTNAME = PuppetDbEntityProvider.ANNOTATION_PUPPET_CERTNAME;
14
- exports.DEFAULT_PROVIDER_ID = PuppetDbEntityProvider.DEFAULT_PROVIDER_ID;
15
10
  exports.PuppetDbEntityProvider = PuppetDbEntityProvider.PuppetDbEntityProvider;
16
- exports.defaultResourceTransformer = PuppetDbEntityProvider.defaultResourceTransformer;
11
+ exports.DEFAULT_PROVIDER_ID = constants.DEFAULT_PROVIDER_ID;
12
+ exports.ANNOTATION_PUPPET_CERTNAME = constants$1.ANNOTATION_PUPPET_CERTNAME;
13
+ exports.defaultResourceTransformer = transformers.defaultResourceTransformer;
17
14
  //# sourceMappingURL=index.cjs.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;;;;"}
1
+ {"version":3,"file":"index.cjs.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;;;;"}
package/dist/index.d.ts CHANGED
@@ -158,11 +158,10 @@ declare class PuppetDbEntityProvider implements EntityProvider {
158
158
  * Creates an instance of {@link PuppetDbEntityProvider}.
159
159
  *
160
160
  * @param config - Configuration of the provider.
161
- * @param logger - The instance of a {@link LoggerService}.
162
- * @param taskRunner - The instance of {@link SchedulerServiceTaskRunner}.
161
+ * @param logger - The instance of a {@link @backstage/backend-plugin-api#LoggerService}.
162
+ * @param taskRunner - The instance of {@link @backstage/backend-plugin-api#SchedulerServiceTaskRunner}.
163
163
  * @param transformer - A {@link ResourceTransformer} function.
164
164
  *
165
- * @private
166
165
  */
167
166
  private constructor();
168
167
  /** {@inheritdoc @backstage/plugin-catalog-node#EntityProvider.connect} */
@@ -172,9 +171,7 @@ declare class PuppetDbEntityProvider implements EntityProvider {
172
171
  /**
173
172
  * Creates a function that can be used to schedule a refresh of the catalog.
174
173
  *
175
- * @param taskRunner - The instance of {@link SchedulerServiceTaskRunner}.
176
- *
177
- * @private
174
+ * @param taskRunner - The instance of {@link @backstage/backend-plugin-api#SchedulerServiceTaskRunner}.
178
175
  */
179
176
  private createScheduleFn;
180
177
  /**
@@ -0,0 +1,31 @@
1
+ 'use strict';
2
+
3
+ var backendPluginApi = require('@backstage/backend-plugin-api');
4
+ var alpha = require('@backstage/plugin-catalog-node/alpha');
5
+ var PuppetDbEntityProvider = require('../providers/PuppetDbEntityProvider.cjs.js');
6
+
7
+ const catalogModulePuppetDbEntityProvider = backendPluginApi.createBackendModule({
8
+ pluginId: "catalog",
9
+ moduleId: "puppetdb-entity-provider",
10
+ register(env) {
11
+ env.registerInit({
12
+ deps: {
13
+ catalog: alpha.catalogProcessingExtensionPoint,
14
+ config: backendPluginApi.coreServices.rootConfig,
15
+ logger: backendPluginApi.coreServices.logger,
16
+ scheduler: backendPluginApi.coreServices.scheduler
17
+ },
18
+ async init({ catalog, config, logger, scheduler }) {
19
+ catalog.addEntityProvider(
20
+ PuppetDbEntityProvider.PuppetDbEntityProvider.fromConfig(config, {
21
+ logger,
22
+ scheduler
23
+ })
24
+ );
25
+ }
26
+ });
27
+ }
28
+ });
29
+
30
+ exports.catalogModulePuppetDbEntityProvider = catalogModulePuppetDbEntityProvider;
31
+ //# sourceMappingURL=catalogModulePuppetDbEntityProvider.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"catalogModulePuppetDbEntityProvider.cjs.js","sources":["../../src/module/catalogModulePuppetDbEntityProvider.ts"],"sourcesContent":["/*\n * Copyright 2022 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n coreServices,\n createBackendModule,\n} from '@backstage/backend-plugin-api';\nimport { catalogProcessingExtensionPoint } from '@backstage/plugin-catalog-node/alpha';\nimport { PuppetDbEntityProvider } from '../providers/PuppetDbEntityProvider';\n\n/**\n * Registers the `PuppetDbEntityProvider` with the catalog processing extension point.\n *\n * @alpha\n */\nexport const catalogModulePuppetDbEntityProvider = createBackendModule({\n pluginId: 'catalog',\n moduleId: 'puppetdb-entity-provider',\n register(env) {\n env.registerInit({\n deps: {\n catalog: catalogProcessingExtensionPoint,\n config: coreServices.rootConfig,\n logger: coreServices.logger,\n scheduler: coreServices.scheduler,\n },\n async init({ catalog, config, logger, scheduler }) {\n catalog.addEntityProvider(\n PuppetDbEntityProvider.fromConfig(config, {\n logger,\n scheduler,\n }),\n );\n },\n });\n },\n});\n"],"names":["createBackendModule","catalogProcessingExtensionPoint","coreServices","PuppetDbEntityProvider"],"mappings":";;;;;;AA4BO,MAAM,sCAAsCA,oCAAoB,CAAA;AAAA,EACrE,QAAU,EAAA,SAAA;AAAA,EACV,QAAU,EAAA,0BAAA;AAAA,EACV,SAAS,GAAK,EAAA;AACZ,IAAA,GAAA,CAAI,YAAa,CAAA;AAAA,MACf,IAAM,EAAA;AAAA,QACJ,OAAS,EAAAC,qCAAA;AAAA,QACT,QAAQC,6BAAa,CAAA,UAAA;AAAA,QACrB,QAAQA,6BAAa,CAAA,MAAA;AAAA,QACrB,WAAWA,6BAAa,CAAA,SAAA;AAAA,OAC1B;AAAA,MACA,MAAM,IAAK,CAAA,EAAE,SAAS,MAAQ,EAAA,MAAA,EAAQ,WAAa,EAAA;AACjD,QAAQ,OAAA,CAAA,iBAAA;AAAA,UACNC,6CAAA,CAAuB,WAAW,MAAQ,EAAA;AAAA,YACxC,MAAA;AAAA,YACA,SAAA;AAAA,WACD,CAAA;AAAA,SACH,CAAA;AAAA,OACF;AAAA,KACD,CAAA,CAAA;AAAA,GACH;AACF,CAAC;;;;"}
@@ -1,13 +1,12 @@
1
1
  'use strict';
2
2
 
3
- var backendPluginApi = require('@backstage/backend-plugin-api');
3
+ var PuppetDbEntityProviderConfig = require('./PuppetDbEntityProviderConfig.cjs.js');
4
4
  var uuid = require('uuid');
5
+ var constants = require('../puppet/constants.cjs.js');
6
+ var transformers = require('../puppet/transformers.cjs.js');
5
7
  var catalogModel = require('@backstage/catalog-model');
6
8
  var lodash = require('lodash');
7
- var fetch = require('node-fetch');
8
- var errors = require('@backstage/errors');
9
-
10
- function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
9
+ var read = require('../puppet/read.cjs.js');
11
10
 
12
11
  function _interopNamespaceCompat(e) {
13
12
  if (e && typeof e === 'object' && 'default' in e) return e;
@@ -28,101 +27,6 @@ function _interopNamespaceCompat(e) {
28
27
  }
29
28
 
30
29
  var uuid__namespace = /*#__PURE__*/_interopNamespaceCompat(uuid);
31
- var fetch__default = /*#__PURE__*/_interopDefaultCompat(fetch);
32
-
33
- const DEFAULT_PROVIDER_ID = "default";
34
-
35
- function readProviderConfigs(config) {
36
- const providersConfig = config.getOptionalConfig(
37
- "catalog.providers.puppetdb"
38
- );
39
- if (!providersConfig) {
40
- return [];
41
- }
42
- if (providersConfig.has("baseUrl")) {
43
- return [readProviderConfig(DEFAULT_PROVIDER_ID, providersConfig)];
44
- }
45
- return providersConfig.keys().map((id) => {
46
- return readProviderConfig(id, providersConfig.getConfig(id));
47
- });
48
- }
49
- function readProviderConfig(id, config) {
50
- const baseUrl = config.getString("baseUrl").replace(/\/+$/, "");
51
- const query = config.getOptionalString("query");
52
- const schedule = config.has("schedule") ? backendPluginApi.readSchedulerServiceTaskScheduleDefinitionFromConfig(
53
- config.getConfig("schedule")
54
- ) : void 0;
55
- return {
56
- id,
57
- baseUrl,
58
- query,
59
- schedule
60
- };
61
- }
62
-
63
- const ANNOTATION_PUPPET_CERTNAME = "puppet.com/certname";
64
- const ENDPOINT_FACTSETS = "pdb/query/v4/factsets";
65
- const ENDPOINT_NODES = "pdb/query/v4/nodes";
66
- const DEFAULT_ENTITY_OWNER = "unknown";
67
-
68
- const defaultResourceTransformer = async (node, _config) => {
69
- const certName = node.certname.toLocaleLowerCase("en-US");
70
- const type = node.facts?.data?.find((e) => e.name === "is_virtual")?.value ? "virtual-machine" : "physical-server";
71
- const kernel = node.facts?.data?.find((e) => e.name === "kernel")?.value;
72
- const latest_report_status = node.latest_report_status;
73
- return {
74
- apiVersion: "backstage.io/v1beta1",
75
- kind: "Resource",
76
- metadata: {
77
- name: certName,
78
- annotations: {
79
- [ANNOTATION_PUPPET_CERTNAME]: certName
80
- },
81
- namespace: catalogModel.DEFAULT_NAMESPACE,
82
- description: node.facts?.data?.find((e) => e.name === "ipaddress")?.value?.toString(),
83
- tags: kernel ? [
84
- kernel.toString().toLocaleLowerCase("en-US"),
85
- latest_report_status.toString().toLocaleLowerCase("en-US")
86
- ] : []
87
- },
88
- spec: {
89
- type,
90
- owner: DEFAULT_ENTITY_OWNER,
91
- dependsOn: [],
92
- dependencyOf: []
93
- }
94
- };
95
- };
96
-
97
- async function readPuppetNodes(config, opts) {
98
- const transformFn = opts?.transformer ?? defaultResourceTransformer;
99
- const url = new URL(ENDPOINT_FACTSETS, config.baseUrl);
100
- if (config.query) {
101
- url.searchParams.set("query", config.query);
102
- }
103
- if (opts?.logger) {
104
- opts.logger.debug("Reading nodes from PuppetDB", { url: url.toString() });
105
- }
106
- const response = await fetch__default.default(url.toString(), {
107
- method: "GET",
108
- headers: {
109
- "Content-Type": "application/json",
110
- Accept: "application/json"
111
- }
112
- });
113
- if (!response.ok) {
114
- throw await errors.ResponseError.fromResponse(response);
115
- }
116
- const nodes = await response.json();
117
- const entities = [];
118
- for (const node of nodes) {
119
- const entity = await transformFn(node, config);
120
- if (entity) {
121
- entities.push(entity);
122
- }
123
- }
124
- return entities;
125
- }
126
30
 
127
31
  class PuppetDbEntityProvider {
128
32
  config;
@@ -142,14 +46,14 @@ class PuppetDbEntityProvider {
142
46
  if (!deps.schedule && !deps.scheduler) {
143
47
  throw new Error("Either schedule or scheduler must be provided.");
144
48
  }
145
- return readProviderConfigs(config).map((providerConfig) => {
49
+ return PuppetDbEntityProviderConfig.readProviderConfigs(config).map((providerConfig) => {
146
50
  if (!deps.schedule && !providerConfig.schedule) {
147
51
  throw new Error(
148
52
  `No schedule provided neither via code nor config for puppet-provider:${providerConfig.id}.`
149
53
  );
150
54
  }
151
55
  const taskRunner = deps.schedule ?? deps.scheduler.createScheduledTaskRunner(providerConfig.schedule);
152
- const transformer = deps.transformer ?? defaultResourceTransformer;
56
+ const transformer = deps.transformer ?? transformers.defaultResourceTransformer;
153
57
  return new PuppetDbEntityProvider(
154
58
  providerConfig,
155
59
  deps.logger,
@@ -162,11 +66,10 @@ class PuppetDbEntityProvider {
162
66
  * Creates an instance of {@link PuppetDbEntityProvider}.
163
67
  *
164
68
  * @param config - Configuration of the provider.
165
- * @param logger - The instance of a {@link LoggerService}.
166
- * @param taskRunner - The instance of {@link SchedulerServiceTaskRunner}.
69
+ * @param logger - The instance of a {@link @backstage/backend-plugin-api#LoggerService}.
70
+ * @param taskRunner - The instance of {@link @backstage/backend-plugin-api#SchedulerServiceTaskRunner}.
167
71
  * @param transformer - A {@link ResourceTransformer} function.
168
72
  *
169
- * @private
170
73
  */
171
74
  constructor(config, logger, taskRunner, transformer) {
172
75
  this.config = config;
@@ -188,9 +91,7 @@ class PuppetDbEntityProvider {
188
91
  /**
189
92
  * Creates a function that can be used to schedule a refresh of the catalog.
190
93
  *
191
- * @param taskRunner - The instance of {@link SchedulerServiceTaskRunner}.
192
- *
193
- * @private
94
+ * @param taskRunner - The instance of {@link @backstage/backend-plugin-api#SchedulerServiceTaskRunner}.
194
95
  */
195
96
  createScheduleFn(taskRunner) {
196
97
  return async () => {
@@ -225,7 +126,7 @@ class PuppetDbEntityProvider {
225
126
  throw new Error("Not initialized");
226
127
  }
227
128
  const { markReadComplete } = trackProgress(logger);
228
- const entities = await readPuppetNodes(this.config, {
129
+ const entities = await read.readPuppetNodes(this.config, {
229
130
  logger,
230
131
  transformer: this.transformer
231
132
  });
@@ -241,7 +142,7 @@ class PuppetDbEntityProvider {
241
142
  }
242
143
  }
243
144
  function withLocations(baseUrl, entity) {
244
- const location = `${baseUrl}/${ENDPOINT_NODES}/${entity.metadata?.name}`;
145
+ const location = `${baseUrl}/${constants.ENDPOINT_NODES}/${entity.metadata?.name}`;
245
146
  return lodash.merge(
246
147
  {
247
148
  metadata: {
@@ -273,8 +174,5 @@ function trackProgress(logger) {
273
174
  return { markReadComplete };
274
175
  }
275
176
 
276
- exports.ANNOTATION_PUPPET_CERTNAME = ANNOTATION_PUPPET_CERTNAME;
277
- exports.DEFAULT_PROVIDER_ID = DEFAULT_PROVIDER_ID;
278
177
  exports.PuppetDbEntityProvider = PuppetDbEntityProvider;
279
- exports.defaultResourceTransformer = defaultResourceTransformer;
280
- //# sourceMappingURL=PuppetDbEntityProvider-DT7iF87I.cjs.js.map
178
+ //# sourceMappingURL=PuppetDbEntityProvider.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PuppetDbEntityProvider.cjs.js","sources":["../../src/providers/PuppetDbEntityProvider.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n EntityProvider,\n EntityProviderConnection,\n} from '@backstage/plugin-catalog-node';\nimport {\n PuppetDbEntityProviderConfig,\n readProviderConfigs,\n} from './PuppetDbEntityProviderConfig';\nimport { Config } from '@backstage/config';\nimport * as uuid from 'uuid';\nimport { defaultResourceTransformer, ResourceTransformer } from '../puppet';\nimport {\n ANNOTATION_LOCATION,\n ANNOTATION_ORIGIN_LOCATION,\n Entity,\n} from '@backstage/catalog-model';\nimport { merge } from 'lodash';\nimport { readPuppetNodes } from '../puppet/read';\nimport { ENDPOINT_NODES } from '../puppet/constants';\nimport {\n SchedulerService,\n SchedulerServiceTaskRunner,\n LoggerService,\n} from '@backstage/backend-plugin-api';\n\n/**\n * Reads nodes from [PuppetDB](https://www.puppet.com/docs/puppet/6/puppetdb_overview.html)\n * based on the provided query and registers them as Resource entities in the catalog.\n *\n * @public\n */\nexport class PuppetDbEntityProvider implements EntityProvider {\n private readonly config: PuppetDbEntityProviderConfig;\n private readonly logger: LoggerService;\n private readonly scheduleFn: () => Promise<void>;\n private readonly transformer: ResourceTransformer;\n private connection?: EntityProviderConnection;\n\n /**\n * Creates instances of {@link PuppetDbEntityProvider} from a configuration.\n *\n * @param config - The configuration to read provider information from.\n * @param deps - The dependencies for {@link PuppetDbEntityProvider}.\n *\n * @returns A list of {@link PuppetDbEntityProvider} instances.\n */\n static fromConfig(\n config: Config,\n deps: {\n logger: LoggerService;\n schedule?: SchedulerServiceTaskRunner;\n scheduler?: SchedulerService;\n transformer?: ResourceTransformer;\n },\n ): PuppetDbEntityProvider[] {\n if (!deps.schedule && !deps.scheduler) {\n throw new Error('Either schedule or scheduler must be provided.');\n }\n\n return readProviderConfigs(config).map(providerConfig => {\n if (!deps.schedule && !providerConfig.schedule) {\n throw new Error(\n `No schedule provided neither via code nor config for puppet-provider:${providerConfig.id}.`,\n );\n }\n\n const taskRunner =\n deps.schedule ??\n deps.scheduler!.createScheduledTaskRunner(providerConfig.schedule!);\n\n const transformer = deps.transformer ?? defaultResourceTransformer;\n\n return new PuppetDbEntityProvider(\n providerConfig,\n deps.logger,\n taskRunner,\n transformer,\n );\n });\n }\n\n /**\n * Creates an instance of {@link PuppetDbEntityProvider}.\n *\n * @param config - Configuration of the provider.\n * @param logger - The instance of a {@link @backstage/backend-plugin-api#LoggerService}.\n * @param taskRunner - The instance of {@link @backstage/backend-plugin-api#SchedulerServiceTaskRunner}.\n * @param transformer - A {@link ResourceTransformer} function.\n *\n */\n private constructor(\n config: PuppetDbEntityProviderConfig,\n logger: LoggerService,\n taskRunner: SchedulerServiceTaskRunner,\n transformer: ResourceTransformer,\n ) {\n this.config = config;\n this.logger = logger.child({\n target: this.getProviderName(),\n });\n this.scheduleFn = this.createScheduleFn(taskRunner);\n this.transformer = transformer;\n }\n\n /** {@inheritdoc @backstage/plugin-catalog-node#EntityProvider.connect} */\n async connect(connection: EntityProviderConnection): Promise<void> {\n this.connection = connection;\n await this.scheduleFn();\n }\n\n /** {@inheritdoc @backstage/plugin-catalog-node#EntityProvider.getProviderName} */\n getProviderName(): string {\n return `puppetdb-provider:${this.config.id}`;\n }\n\n /**\n * Creates a function that can be used to schedule a refresh of the catalog.\n *\n * @param taskRunner - The instance of {@link @backstage/backend-plugin-api#SchedulerServiceTaskRunner}.\n */\n private createScheduleFn(\n taskRunner: SchedulerServiceTaskRunner,\n ): () => Promise<void> {\n return async () => {\n const taskId = `${this.getProviderName()}:refresh`;\n return taskRunner.run({\n id: taskId,\n fn: async () => {\n const logger = this.logger.child({\n class: PuppetDbEntityProvider.prototype.constructor.name,\n taskId,\n taskInstanceId: uuid.v4(),\n });\n try {\n await this.refresh(logger);\n } catch (error) {\n logger.error(\n `${this.getProviderName()} refresh failed, ${error}`,\n error,\n );\n }\n },\n });\n };\n }\n\n /**\n * Refreshes the catalog by reading nodes from PuppetDB and registering them as Resource Entities.\n *\n * @param logger - The instance of a Logger.\n */\n async refresh(logger: LoggerService) {\n if (!this.connection) {\n throw new Error('Not initialized');\n }\n\n const { markReadComplete } = trackProgress(logger);\n const entities = await readPuppetNodes(this.config, {\n logger,\n transformer: this.transformer,\n });\n const { markCommitComplete } = markReadComplete(entities);\n\n await this.connection.applyMutation({\n type: 'full',\n entities: [...entities].map(entity => ({\n locationKey: this.getProviderName(),\n entity: withLocations(this.config.baseUrl, entity),\n })),\n });\n markCommitComplete(entities);\n }\n}\n\n/**\n * Ensures the entities have required annotation data.\n *\n * @param baseUrl - The base URL of the PuppetDB instance.\n * @param entity - The entity to add the annotations to.\n *\n * @returns Entity with @{@link ANNOTATION_LOCATION} and @{@link ANNOTATION_ORIGIN_LOCATION} annotations.\n */\nfunction withLocations(baseUrl: string, entity: Entity): Entity {\n const location = `${baseUrl}/${ENDPOINT_NODES}/${entity.metadata?.name}`;\n\n return merge(\n {\n metadata: {\n annotations: {\n [ANNOTATION_LOCATION]: `url:${location}`,\n [ANNOTATION_ORIGIN_LOCATION]: `url:${location}`,\n },\n },\n },\n entity,\n ) as Entity;\n}\n\n/**\n * Tracks the progress of the PuppetDB read and commit operations.\n *\n * @param logger - The instance of a {@link @backstage/backend-plugin-api#LoggerService}.\n */\nfunction trackProgress(logger: LoggerService) {\n let timestamp = Date.now();\n\n function markReadComplete(entities: Entity[]) {\n const readDuration = ((Date.now() - timestamp) / 1000).toFixed(1);\n timestamp = Date.now();\n logger.info(\n `Read ${entities?.length ?? 0} in ${readDuration} seconds. Committing...`,\n );\n return { markCommitComplete };\n }\n\n function markCommitComplete(entities: Entity[]) {\n const commitDuration = ((Date.now() - timestamp) / 1000).toFixed(1);\n logger.info(\n `Committed ${entities?.length ?? 0} in ${commitDuration} seconds.`,\n );\n }\n\n return { markReadComplete };\n}\n"],"names":["readProviderConfigs","defaultResourceTransformer","uuid","readPuppetNodes","ENDPOINT_NODES","merge","ANNOTATION_LOCATION","ANNOTATION_ORIGIN_LOCATION"],"mappings":"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"}
@@ -0,0 +1,35 @@
1
+ 'use strict';
2
+
3
+ var backendPluginApi = require('@backstage/backend-plugin-api');
4
+ var constants = require('./constants.cjs.js');
5
+
6
+ function readProviderConfigs(config) {
7
+ const providersConfig = config.getOptionalConfig(
8
+ "catalog.providers.puppetdb"
9
+ );
10
+ if (!providersConfig) {
11
+ return [];
12
+ }
13
+ if (providersConfig.has("baseUrl")) {
14
+ return [readProviderConfig(constants.DEFAULT_PROVIDER_ID, providersConfig)];
15
+ }
16
+ return providersConfig.keys().map((id) => {
17
+ return readProviderConfig(id, providersConfig.getConfig(id));
18
+ });
19
+ }
20
+ function readProviderConfig(id, config) {
21
+ const baseUrl = config.getString("baseUrl").replace(/\/+$/, "");
22
+ const query = config.getOptionalString("query");
23
+ const schedule = config.has("schedule") ? backendPluginApi.readSchedulerServiceTaskScheduleDefinitionFromConfig(
24
+ config.getConfig("schedule")
25
+ ) : void 0;
26
+ return {
27
+ id,
28
+ baseUrl,
29
+ query,
30
+ schedule
31
+ };
32
+ }
33
+
34
+ exports.readProviderConfigs = readProviderConfigs;
35
+ //# sourceMappingURL=PuppetDbEntityProviderConfig.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"PuppetDbEntityProviderConfig.cjs.js","sources":["../../src/providers/PuppetDbEntityProviderConfig.ts"],"sourcesContent":["/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n SchedulerServiceTaskScheduleDefinition,\n readSchedulerServiceTaskScheduleDefinitionFromConfig,\n} from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport { DEFAULT_PROVIDER_ID } from './constants';\n\n/**\n * Configuration of {@link PuppetDbEntityProvider}.\n *\n * @public\n */\nexport type PuppetDbEntityProviderConfig = {\n /**\n * ID of the provider.\n */\n id: string;\n /**\n * (Required) The base URL of PuppetDB API instance.\n */\n baseUrl: string;\n /**\n * (Optional) PQL query to filter PuppetDB nodes.\n */\n query?: string;\n /**\n * (Optional) Task schedule definition for the refresh.\n */\n schedule?: SchedulerServiceTaskScheduleDefinition;\n};\n\n/**\n * Reads the configuration of the PuppetDB Entity Providers.\n *\n * @param config - The application configuration.\n *\n * @returns PuppetDB Entity Provider configurations list.\n */\nexport function readProviderConfigs(\n config: Config,\n): PuppetDbEntityProviderConfig[] {\n const providersConfig = config.getOptionalConfig(\n 'catalog.providers.puppetdb',\n );\n if (!providersConfig) {\n return [];\n }\n\n if (providersConfig.has('baseUrl')) {\n return [readProviderConfig(DEFAULT_PROVIDER_ID, providersConfig)];\n }\n\n return providersConfig.keys().map(id => {\n return readProviderConfig(id, providersConfig.getConfig(id));\n });\n}\n\n/**\n * Reads the configuration for the PuppetDB Entity Provider.\n *\n * @param id - ID of the provider.\n * @param config - The application configuration.\n *\n * @returns The PuppetDB Entity Provider configuration.\n */\nfunction readProviderConfig(\n id: string,\n config: Config,\n): PuppetDbEntityProviderConfig {\n const baseUrl = config.getString('baseUrl').replace(/\\/+$/, '');\n const query = config.getOptionalString('query');\n\n const schedule = config.has('schedule')\n ? readSchedulerServiceTaskScheduleDefinitionFromConfig(\n config.getConfig('schedule'),\n )\n : undefined;\n\n return {\n id,\n baseUrl,\n query,\n schedule,\n };\n}\n"],"names":["DEFAULT_PROVIDER_ID","readSchedulerServiceTaskScheduleDefinitionFromConfig"],"mappings":";;;;;AAsDO,SAAS,oBACd,MACgC,EAAA;AAChC,EAAA,MAAM,kBAAkB,MAAO,CAAA,iBAAA;AAAA,IAC7B,4BAAA;AAAA,GACF,CAAA;AACA,EAAA,IAAI,CAAC,eAAiB,EAAA;AACpB,IAAA,OAAO,EAAC,CAAA;AAAA,GACV;AAEA,EAAI,IAAA,eAAA,CAAgB,GAAI,CAAA,SAAS,CAAG,EAAA;AAClC,IAAA,OAAO,CAAC,kBAAA,CAAmBA,6BAAqB,EAAA,eAAe,CAAC,CAAA,CAAA;AAAA,GAClE;AAEA,EAAA,OAAO,eAAgB,CAAA,IAAA,EAAO,CAAA,GAAA,CAAI,CAAM,EAAA,KAAA;AACtC,IAAA,OAAO,kBAAmB,CAAA,EAAA,EAAI,eAAgB,CAAA,SAAA,CAAU,EAAE,CAAC,CAAA,CAAA;AAAA,GAC5D,CAAA,CAAA;AACH,CAAA;AAUA,SAAS,kBAAA,CACP,IACA,MAC8B,EAAA;AAC9B,EAAA,MAAM,UAAU,MAAO,CAAA,SAAA,CAAU,SAAS,CAAE,CAAA,OAAA,CAAQ,QAAQ,EAAE,CAAA,CAAA;AAC9D,EAAM,MAAA,KAAA,GAAQ,MAAO,CAAA,iBAAA,CAAkB,OAAO,CAAA,CAAA;AAE9C,EAAA,MAAM,QAAW,GAAA,MAAA,CAAO,GAAI,CAAA,UAAU,CAClC,GAAAC,qEAAA;AAAA,IACE,MAAA,CAAO,UAAU,UAAU,CAAA;AAAA,GAE7B,GAAA,KAAA,CAAA,CAAA;AAEJ,EAAO,OAAA;AAAA,IACL,EAAA;AAAA,IACA,OAAA;AAAA,IACA,KAAA;AAAA,IACA,QAAA;AAAA,GACF,CAAA;AACF;;;;"}
@@ -0,0 +1,6 @@
1
+ 'use strict';
2
+
3
+ const DEFAULT_PROVIDER_ID = "default";
4
+
5
+ exports.DEFAULT_PROVIDER_ID = DEFAULT_PROVIDER_ID;
6
+ //# sourceMappingURL=constants.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.cjs.js","sources":["../../src/providers/constants.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Name of the default provider when a using a simple configuration.\n *\n * @public\n */\nexport const DEFAULT_PROVIDER_ID = 'default';\n"],"names":[],"mappings":";;AAqBO,MAAM,mBAAsB,GAAA;;;;"}
@@ -0,0 +1,12 @@
1
+ 'use strict';
2
+
3
+ const ANNOTATION_PUPPET_CERTNAME = "puppet.com/certname";
4
+ const ENDPOINT_FACTSETS = "pdb/query/v4/factsets";
5
+ const ENDPOINT_NODES = "pdb/query/v4/nodes";
6
+ const DEFAULT_ENTITY_OWNER = "unknown";
7
+
8
+ exports.ANNOTATION_PUPPET_CERTNAME = ANNOTATION_PUPPET_CERTNAME;
9
+ exports.DEFAULT_ENTITY_OWNER = DEFAULT_ENTITY_OWNER;
10
+ exports.ENDPOINT_FACTSETS = ENDPOINT_FACTSETS;
11
+ exports.ENDPOINT_NODES = ENDPOINT_NODES;
12
+ //# sourceMappingURL=constants.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"constants.cjs.js","sources":["../../src/puppet/constants.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Annotation for specifying the certificate name of a node in PuppetDB.\n *\n * @public\n */\nexport const ANNOTATION_PUPPET_CERTNAME = 'puppet.com/certname';\n\n/**\n * Path of PuppetDB FactSets endpoint.\n */\nexport const ENDPOINT_FACTSETS = 'pdb/query/v4/factsets';\n\n/**\n * Path of PuppetDB Nodes endpoint.\n */\nexport const ENDPOINT_NODES = 'pdb/query/v4/nodes';\n\n/**\n * Default owner for entities created by the PuppetDB provider.\n *\n * @public\n */\nexport const DEFAULT_ENTITY_OWNER = 'unknown';\n"],"names":[],"mappings":";;AAqBO,MAAM,0BAA6B,GAAA,sBAAA;AAKnC,MAAM,iBAAoB,GAAA,wBAAA;AAK1B,MAAM,cAAiB,GAAA,qBAAA;AAOvB,MAAM,oBAAuB,GAAA;;;;;;;"}
@@ -0,0 +1,43 @@
1
+ 'use strict';
2
+
3
+ var transformers = require('./transformers.cjs.js');
4
+ var fetch = require('node-fetch');
5
+ var errors = require('@backstage/errors');
6
+ var constants = require('./constants.cjs.js');
7
+
8
+ function _interopDefaultCompat (e) { return e && typeof e === 'object' && 'default' in e ? e : { default: e }; }
9
+
10
+ var fetch__default = /*#__PURE__*/_interopDefaultCompat(fetch);
11
+
12
+ async function readPuppetNodes(config, opts) {
13
+ const transformFn = opts?.transformer ?? transformers.defaultResourceTransformer;
14
+ const url = new URL(constants.ENDPOINT_FACTSETS, config.baseUrl);
15
+ if (config.query) {
16
+ url.searchParams.set("query", config.query);
17
+ }
18
+ if (opts?.logger) {
19
+ opts.logger.debug("Reading nodes from PuppetDB", { url: url.toString() });
20
+ }
21
+ const response = await fetch__default.default(url.toString(), {
22
+ method: "GET",
23
+ headers: {
24
+ "Content-Type": "application/json",
25
+ Accept: "application/json"
26
+ }
27
+ });
28
+ if (!response.ok) {
29
+ throw await errors.ResponseError.fromResponse(response);
30
+ }
31
+ const nodes = await response.json();
32
+ const entities = [];
33
+ for (const node of nodes) {
34
+ const entity = await transformFn(node, config);
35
+ if (entity) {
36
+ entities.push(entity);
37
+ }
38
+ }
39
+ return entities;
40
+ }
41
+
42
+ exports.readPuppetNodes = readPuppetNodes;
43
+ //# sourceMappingURL=read.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"read.cjs.js","sources":["../../src/puppet/read.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { PuppetDbEntityProviderConfig } from '../providers';\nimport { PuppetNode, ResourceTransformer } from './types';\nimport { ResourceEntity } from '@backstage/catalog-model';\nimport { defaultResourceTransformer } from './transformers';\nimport fetch from 'node-fetch';\nimport { ResponseError } from '@backstage/errors';\nimport { ENDPOINT_FACTSETS } from './constants';\nimport { LoggerService } from '@backstage/backend-plugin-api';\n\n/**\n * Reads nodes and their facts from PuppetDB.\n *\n * @param config - The provider configuration.\n * @param opts - Additional options.\n */\nexport async function readPuppetNodes(\n config: PuppetDbEntityProviderConfig,\n opts?: {\n transformer?: ResourceTransformer;\n logger?: LoggerService;\n },\n): Promise<ResourceEntity[]> {\n const transformFn = opts?.transformer ?? defaultResourceTransformer;\n const url = new URL(ENDPOINT_FACTSETS, config.baseUrl);\n\n if (config.query) {\n url.searchParams.set('query', config.query);\n }\n\n if (opts?.logger) {\n opts.logger.debug('Reading nodes from PuppetDB', { url: url.toString() });\n }\n\n const response = await fetch(url.toString(), {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n const nodes = (await response.json()) as PuppetNode[];\n const entities: ResourceEntity[] = [];\n\n for (const node of nodes) {\n const entity = await transformFn(node, config);\n if (entity) {\n entities.push(entity);\n }\n }\n\n return entities;\n}\n"],"names":["defaultResourceTransformer","ENDPOINT_FACTSETS","fetch","ResponseError"],"mappings":";;;;;;;;;;;AA+BsB,eAAA,eAAA,CACpB,QACA,IAI2B,EAAA;AAC3B,EAAM,MAAA,WAAA,GAAc,MAAM,WAAe,IAAAA,uCAAA,CAAA;AACzC,EAAA,MAAM,GAAM,GAAA,IAAI,GAAI,CAAAC,2BAAA,EAAmB,OAAO,OAAO,CAAA,CAAA;AAErD,EAAA,IAAI,OAAO,KAAO,EAAA;AAChB,IAAA,GAAA,CAAI,YAAa,CAAA,GAAA,CAAI,OAAS,EAAA,MAAA,CAAO,KAAK,CAAA,CAAA;AAAA,GAC5C;AAEA,EAAA,IAAI,MAAM,MAAQ,EAAA;AAChB,IAAK,IAAA,CAAA,MAAA,CAAO,MAAM,6BAA+B,EAAA,EAAE,KAAK,GAAI,CAAA,QAAA,IAAY,CAAA,CAAA;AAAA,GAC1E;AAEA,EAAA,MAAM,QAAW,GAAA,MAAMC,sBAAM,CAAA,GAAA,CAAI,UAAY,EAAA;AAAA,IAC3C,MAAQ,EAAA,KAAA;AAAA,IACR,OAAS,EAAA;AAAA,MACP,cAAgB,EAAA,kBAAA;AAAA,MAChB,MAAQ,EAAA,kBAAA;AAAA,KACV;AAAA,GACD,CAAA,CAAA;AAED,EAAI,IAAA,CAAC,SAAS,EAAI,EAAA;AAChB,IAAM,MAAA,MAAMC,oBAAc,CAAA,YAAA,CAAa,QAAQ,CAAA,CAAA;AAAA,GACjD;AAEA,EAAM,MAAA,KAAA,GAAS,MAAM,QAAA,CAAS,IAAK,EAAA,CAAA;AACnC,EAAA,MAAM,WAA6B,EAAC,CAAA;AAEpC,EAAA,KAAA,MAAW,QAAQ,KAAO,EAAA;AACxB,IAAA,MAAM,MAAS,GAAA,MAAM,WAAY,CAAA,IAAA,EAAM,MAAM,CAAA,CAAA;AAC7C,IAAA,IAAI,MAAQ,EAAA;AACV,MAAA,QAAA,CAAS,KAAK,MAAM,CAAA,CAAA;AAAA,KACtB;AAAA,GACF;AAEA,EAAO,OAAA,QAAA,CAAA;AACT;;;;"}
@@ -0,0 +1,36 @@
1
+ 'use strict';
2
+
3
+ var catalogModel = require('@backstage/catalog-model');
4
+ var constants = require('./constants.cjs.js');
5
+
6
+ const defaultResourceTransformer = async (node, _config) => {
7
+ const certName = node.certname.toLocaleLowerCase("en-US");
8
+ const type = node.facts?.data?.find((e) => e.name === "is_virtual")?.value ? "virtual-machine" : "physical-server";
9
+ const kernel = node.facts?.data?.find((e) => e.name === "kernel")?.value;
10
+ const latest_report_status = node.latest_report_status;
11
+ return {
12
+ apiVersion: "backstage.io/v1beta1",
13
+ kind: "Resource",
14
+ metadata: {
15
+ name: certName,
16
+ annotations: {
17
+ [constants.ANNOTATION_PUPPET_CERTNAME]: certName
18
+ },
19
+ namespace: catalogModel.DEFAULT_NAMESPACE,
20
+ description: node.facts?.data?.find((e) => e.name === "ipaddress")?.value?.toString(),
21
+ tags: kernel ? [
22
+ kernel.toString().toLocaleLowerCase("en-US"),
23
+ latest_report_status.toString().toLocaleLowerCase("en-US")
24
+ ] : []
25
+ },
26
+ spec: {
27
+ type,
28
+ owner: constants.DEFAULT_ENTITY_OWNER,
29
+ dependsOn: [],
30
+ dependencyOf: []
31
+ }
32
+ };
33
+ };
34
+
35
+ exports.defaultResourceTransformer = defaultResourceTransformer;
36
+ //# sourceMappingURL=transformers.cjs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transformers.cjs.js","sources":["../../src/puppet/transformers.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ResourceTransformer } from './types';\nimport { DEFAULT_NAMESPACE, ResourceEntity } from '@backstage/catalog-model';\nimport { ANNOTATION_PUPPET_CERTNAME, DEFAULT_ENTITY_OWNER } from './constants';\n\n/**\n * A default implementation of the {@link ResourceTransformer}.\n *\n * @param node - The found PuppetDB node entry in its source format. This is the entry that you want to transform.\n * @param _config - The configuration for the entity provider.\n *\n * @returns A `ResourceEntity`.\n *\n * @public\n */\nexport const defaultResourceTransformer: ResourceTransformer = async (\n node,\n _config,\n): Promise<ResourceEntity | undefined> => {\n const certName = node.certname.toLocaleLowerCase('en-US');\n const type = node.facts?.data?.find(e => e.name === 'is_virtual')?.value\n ? 'virtual-machine'\n : 'physical-server';\n const kernel = node.facts?.data?.find(e => e.name === 'kernel')?.value;\n const latest_report_status = node.latest_report_status;\n\n return {\n apiVersion: 'backstage.io/v1beta1',\n kind: 'Resource',\n metadata: {\n name: certName,\n annotations: {\n [ANNOTATION_PUPPET_CERTNAME]: certName,\n },\n namespace: DEFAULT_NAMESPACE,\n description: node.facts?.data\n ?.find(e => e.name === 'ipaddress')\n ?.value?.toString(),\n tags: kernel\n ? [\n kernel.toString().toLocaleLowerCase('en-US'),\n latest_report_status.toString().toLocaleLowerCase('en-US'),\n ]\n : [],\n },\n spec: {\n type: type,\n owner: DEFAULT_ENTITY_OWNER,\n dependsOn: [],\n dependencyOf: [],\n },\n };\n};\n"],"names":["ANNOTATION_PUPPET_CERTNAME","DEFAULT_NAMESPACE","DEFAULT_ENTITY_OWNER"],"mappings":";;;;;AA8Ba,MAAA,0BAAA,GAAkD,OAC7D,IAAA,EACA,OACwC,KAAA;AACxC,EAAA,MAAM,QAAW,GAAA,IAAA,CAAK,QAAS,CAAA,iBAAA,CAAkB,OAAO,CAAA,CAAA;AACxD,EAAM,MAAA,IAAA,GAAO,IAAK,CAAA,KAAA,EAAO,IAAM,EAAA,IAAA,CAAK,CAAK,CAAA,KAAA,CAAA,CAAE,IAAS,KAAA,YAAY,CAAG,EAAA,KAAA,GAC/D,iBACA,GAAA,iBAAA,CAAA;AACJ,EAAM,MAAA,MAAA,GAAS,KAAK,KAAO,EAAA,IAAA,EAAM,KAAK,CAAK,CAAA,KAAA,CAAA,CAAE,IAAS,KAAA,QAAQ,CAAG,EAAA,KAAA,CAAA;AACjE,EAAA,MAAM,uBAAuB,IAAK,CAAA,oBAAA,CAAA;AAElC,EAAO,OAAA;AAAA,IACL,UAAY,EAAA,sBAAA;AAAA,IACZ,IAAM,EAAA,UAAA;AAAA,IACN,QAAU,EAAA;AAAA,MACR,IAAM,EAAA,QAAA;AAAA,MACN,WAAa,EAAA;AAAA,QACX,CAACA,oCAA0B,GAAG,QAAA;AAAA,OAChC;AAAA,MACA,SAAW,EAAAC,8BAAA;AAAA,MACX,WAAA,EAAa,IAAK,CAAA,KAAA,EAAO,IACrB,EAAA,IAAA,CAAK,CAAK,CAAA,KAAA,CAAA,CAAE,IAAS,KAAA,WAAW,CAChC,EAAA,KAAA,EAAO,QAAS,EAAA;AAAA,MACpB,MAAM,MACF,GAAA;AAAA,QACE,MAAO,CAAA,QAAA,EAAW,CAAA,iBAAA,CAAkB,OAAO,CAAA;AAAA,QAC3C,oBAAqB,CAAA,QAAA,EAAW,CAAA,iBAAA,CAAkB,OAAO,CAAA;AAAA,UAE3D,EAAC;AAAA,KACP;AAAA,IACA,IAAM,EAAA;AAAA,MACJ,IAAA;AAAA,MACA,KAAO,EAAAC,8BAAA;AAAA,MACP,WAAW,EAAC;AAAA,MACZ,cAAc,EAAC;AAAA,KACjB;AAAA,GACF,CAAA;AACF;;;;"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@backstage/plugin-catalog-backend-module-puppetdb",
3
- "version": "0.2.3-next.0",
3
+ "version": "0.2.3",
4
4
  "description": "A Backstage catalog backend module that helps integrate towards PuppetDB",
5
5
  "backstage": {
6
6
  "role": "backend-plugin-module",
@@ -53,11 +53,11 @@
53
53
  "test": "backstage-cli package test"
54
54
  },
55
55
  "dependencies": {
56
- "@backstage/backend-plugin-api": "^1.0.1-next.0",
56
+ "@backstage/backend-plugin-api": "^1.0.1",
57
57
  "@backstage/catalog-model": "^1.7.0",
58
58
  "@backstage/config": "^1.2.0",
59
59
  "@backstage/errors": "^1.2.4",
60
- "@backstage/plugin-catalog-node": "^1.13.1-next.0",
60
+ "@backstage/plugin-catalog-node": "^1.13.1",
61
61
  "@backstage/types": "^1.1.1",
62
62
  "lodash": "^4.17.21",
63
63
  "luxon": "^3.0.0",
@@ -65,8 +65,8 @@
65
65
  "uuid": "^9.0.0"
66
66
  },
67
67
  "devDependencies": {
68
- "@backstage/backend-test-utils": "^1.0.1-next.0",
69
- "@backstage/cli": "^0.28.0-next.0",
68
+ "@backstage/backend-test-utils": "^1.0.1",
69
+ "@backstage/cli": "^0.28.0",
70
70
  "@types/lodash": "^4.14.151",
71
71
  "msw": "^1.0.0"
72
72
  },
@@ -1 +0,0 @@
1
- {"version":3,"file":"PuppetDbEntityProvider-DT7iF87I.cjs.js","sources":["../../src/providers/constants.ts","../../src/providers/PuppetDbEntityProviderConfig.ts","../../src/puppet/constants.ts","../../src/puppet/transformers.ts","../../src/puppet/read.ts","../../src/providers/PuppetDbEntityProvider.ts"],"sourcesContent":["/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Name of the default provider when a using a simple configuration.\n *\n * @public\n */\nexport const DEFAULT_PROVIDER_ID = 'default';\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n SchedulerServiceTaskScheduleDefinition,\n readSchedulerServiceTaskScheduleDefinitionFromConfig,\n} from '@backstage/backend-plugin-api';\nimport { Config } from '@backstage/config';\nimport { DEFAULT_PROVIDER_ID } from './constants';\n\n/**\n * Configuration of {@link PuppetDbEntityProvider}.\n *\n * @public\n */\nexport type PuppetDbEntityProviderConfig = {\n /**\n * ID of the provider.\n */\n id: string;\n /**\n * (Required) The base URL of PuppetDB API instance.\n */\n baseUrl: string;\n /**\n * (Optional) PQL query to filter PuppetDB nodes.\n */\n query?: string;\n /**\n * (Optional) Task schedule definition for the refresh.\n */\n schedule?: SchedulerServiceTaskScheduleDefinition;\n};\n\n/**\n * Reads the configuration of the PuppetDB Entity Providers.\n *\n * @param config - The application configuration.\n *\n * @returns PuppetDB Entity Provider configurations list.\n */\nexport function readProviderConfigs(\n config: Config,\n): PuppetDbEntityProviderConfig[] {\n const providersConfig = config.getOptionalConfig(\n 'catalog.providers.puppetdb',\n );\n if (!providersConfig) {\n return [];\n }\n\n if (providersConfig.has('baseUrl')) {\n return [readProviderConfig(DEFAULT_PROVIDER_ID, providersConfig)];\n }\n\n return providersConfig.keys().map(id => {\n return readProviderConfig(id, providersConfig.getConfig(id));\n });\n}\n\n/**\n * Reads the configuration for the PuppetDB Entity Provider.\n *\n * @param id - ID of the provider.\n * @param config - The application configuration.\n *\n * @returns The PuppetDB Entity Provider configuration.\n */\nfunction readProviderConfig(\n id: string,\n config: Config,\n): PuppetDbEntityProviderConfig {\n const baseUrl = config.getString('baseUrl').replace(/\\/+$/, '');\n const query = config.getOptionalString('query');\n\n const schedule = config.has('schedule')\n ? readSchedulerServiceTaskScheduleDefinitionFromConfig(\n config.getConfig('schedule'),\n )\n : undefined;\n\n return {\n id,\n baseUrl,\n query,\n schedule,\n };\n}\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\n/**\n * Annotation for specifying the certificate name of a node in PuppetDB.\n *\n * @public\n */\nexport const ANNOTATION_PUPPET_CERTNAME = 'puppet.com/certname';\n\n/**\n * Path of PuppetDB FactSets endpoint.\n */\nexport const ENDPOINT_FACTSETS = 'pdb/query/v4/factsets';\n\n/**\n * Path of PuppetDB Nodes endpoint.\n */\nexport const ENDPOINT_NODES = 'pdb/query/v4/nodes';\n\n/**\n * Default owner for entities created by the PuppetDB provider.\n *\n * @public\n */\nexport const DEFAULT_ENTITY_OWNER = 'unknown';\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { ResourceTransformer } from './types';\nimport { DEFAULT_NAMESPACE, ResourceEntity } from '@backstage/catalog-model';\nimport { ANNOTATION_PUPPET_CERTNAME, DEFAULT_ENTITY_OWNER } from './constants';\n\n/**\n * A default implementation of the {@link ResourceTransformer}.\n *\n * @param node - The found PuppetDB node entry in its source format. This is the entry that you want to transform.\n * @param _config - The configuration for the entity provider.\n *\n * @returns A `ResourceEntity`.\n *\n * @public\n */\nexport const defaultResourceTransformer: ResourceTransformer = async (\n node,\n _config,\n): Promise<ResourceEntity | undefined> => {\n const certName = node.certname.toLocaleLowerCase('en-US');\n const type = node.facts?.data?.find(e => e.name === 'is_virtual')?.value\n ? 'virtual-machine'\n : 'physical-server';\n const kernel = node.facts?.data?.find(e => e.name === 'kernel')?.value;\n const latest_report_status = node.latest_report_status;\n\n return {\n apiVersion: 'backstage.io/v1beta1',\n kind: 'Resource',\n metadata: {\n name: certName,\n annotations: {\n [ANNOTATION_PUPPET_CERTNAME]: certName,\n },\n namespace: DEFAULT_NAMESPACE,\n description: node.facts?.data\n ?.find(e => e.name === 'ipaddress')\n ?.value?.toString(),\n tags: kernel\n ? [\n kernel.toString().toLocaleLowerCase('en-US'),\n latest_report_status.toString().toLocaleLowerCase('en-US'),\n ]\n : [],\n },\n spec: {\n type: type,\n owner: DEFAULT_ENTITY_OWNER,\n dependsOn: [],\n dependencyOf: [],\n },\n };\n};\n","/*\n * Copyright 2020 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport { PuppetDbEntityProviderConfig } from '../providers';\nimport { PuppetNode, ResourceTransformer } from './types';\nimport { ResourceEntity } from '@backstage/catalog-model';\nimport { defaultResourceTransformer } from './transformers';\nimport fetch from 'node-fetch';\nimport { ResponseError } from '@backstage/errors';\nimport { ENDPOINT_FACTSETS } from './constants';\nimport { LoggerService } from '@backstage/backend-plugin-api';\n\n/**\n * Reads nodes and their facts from PuppetDB.\n *\n * @param config - The provider configuration.\n * @param opts - Additional options.\n */\nexport async function readPuppetNodes(\n config: PuppetDbEntityProviderConfig,\n opts?: {\n transformer?: ResourceTransformer;\n logger?: LoggerService;\n },\n): Promise<ResourceEntity[]> {\n const transformFn = opts?.transformer ?? defaultResourceTransformer;\n const url = new URL(ENDPOINT_FACTSETS, config.baseUrl);\n\n if (config.query) {\n url.searchParams.set('query', config.query);\n }\n\n if (opts?.logger) {\n opts.logger.debug('Reading nodes from PuppetDB', { url: url.toString() });\n }\n\n const response = await fetch(url.toString(), {\n method: 'GET',\n headers: {\n 'Content-Type': 'application/json',\n Accept: 'application/json',\n },\n });\n\n if (!response.ok) {\n throw await ResponseError.fromResponse(response);\n }\n\n const nodes = (await response.json()) as PuppetNode[];\n const entities: ResourceEntity[] = [];\n\n for (const node of nodes) {\n const entity = await transformFn(node, config);\n if (entity) {\n entities.push(entity);\n }\n }\n\n return entities;\n}\n","/*\n * Copyright 2021 The Backstage Authors\n *\n * Licensed under the Apache License, Version 2.0 (the \"License\");\n * you may not use this file except in compliance with the License.\n * You may obtain a copy of the License at\n *\n * http://www.apache.org/licenses/LICENSE-2.0\n *\n * Unless required by applicable law or agreed to in writing, software\n * distributed under the License is distributed on an \"AS IS\" BASIS,\n * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n * See the License for the specific language governing permissions and\n * limitations under the License.\n */\n\nimport {\n EntityProvider,\n EntityProviderConnection,\n} from '@backstage/plugin-catalog-node';\nimport {\n PuppetDbEntityProviderConfig,\n readProviderConfigs,\n} from './PuppetDbEntityProviderConfig';\nimport { Config } from '@backstage/config';\nimport * as uuid from 'uuid';\nimport { defaultResourceTransformer, ResourceTransformer } from '../puppet';\nimport {\n ANNOTATION_LOCATION,\n ANNOTATION_ORIGIN_LOCATION,\n Entity,\n} from '@backstage/catalog-model';\nimport { merge } from 'lodash';\nimport { readPuppetNodes } from '../puppet/read';\nimport { ENDPOINT_NODES } from '../puppet/constants';\nimport {\n SchedulerService,\n SchedulerServiceTaskRunner,\n LoggerService,\n} from '@backstage/backend-plugin-api';\n\n/**\n * Reads nodes from [PuppetDB](https://www.puppet.com/docs/puppet/6/puppetdb_overview.html)\n * based on the provided query and registers them as Resource entities in the catalog.\n *\n * @public\n */\nexport class PuppetDbEntityProvider implements EntityProvider {\n private readonly config: PuppetDbEntityProviderConfig;\n private readonly logger: LoggerService;\n private readonly scheduleFn: () => Promise<void>;\n private readonly transformer: ResourceTransformer;\n private connection?: EntityProviderConnection;\n\n /**\n * Creates instances of {@link PuppetDbEntityProvider} from a configuration.\n *\n * @param config - The configuration to read provider information from.\n * @param deps - The dependencies for {@link PuppetDbEntityProvider}.\n *\n * @returns A list of {@link PuppetDbEntityProvider} instances.\n */\n static fromConfig(\n config: Config,\n deps: {\n logger: LoggerService;\n schedule?: SchedulerServiceTaskRunner;\n scheduler?: SchedulerService;\n transformer?: ResourceTransformer;\n },\n ): PuppetDbEntityProvider[] {\n if (!deps.schedule && !deps.scheduler) {\n throw new Error('Either schedule or scheduler must be provided.');\n }\n\n return readProviderConfigs(config).map(providerConfig => {\n if (!deps.schedule && !providerConfig.schedule) {\n throw new Error(\n `No schedule provided neither via code nor config for puppet-provider:${providerConfig.id}.`,\n );\n }\n\n const taskRunner =\n deps.schedule ??\n deps.scheduler!.createScheduledTaskRunner(providerConfig.schedule!);\n\n const transformer = deps.transformer ?? defaultResourceTransformer;\n\n return new PuppetDbEntityProvider(\n providerConfig,\n deps.logger,\n taskRunner,\n transformer,\n );\n });\n }\n\n /**\n * Creates an instance of {@link PuppetDbEntityProvider}.\n *\n * @param config - Configuration of the provider.\n * @param logger - The instance of a {@link LoggerService}.\n * @param taskRunner - The instance of {@link SchedulerServiceTaskRunner}.\n * @param transformer - A {@link ResourceTransformer} function.\n *\n * @private\n */\n private constructor(\n config: PuppetDbEntityProviderConfig,\n logger: LoggerService,\n taskRunner: SchedulerServiceTaskRunner,\n transformer: ResourceTransformer,\n ) {\n this.config = config;\n this.logger = logger.child({\n target: this.getProviderName(),\n });\n this.scheduleFn = this.createScheduleFn(taskRunner);\n this.transformer = transformer;\n }\n\n /** {@inheritdoc @backstage/plugin-catalog-node#EntityProvider.connect} */\n async connect(connection: EntityProviderConnection): Promise<void> {\n this.connection = connection;\n await this.scheduleFn();\n }\n\n /** {@inheritdoc @backstage/plugin-catalog-node#EntityProvider.getProviderName} */\n getProviderName(): string {\n return `puppetdb-provider:${this.config.id}`;\n }\n\n /**\n * Creates a function that can be used to schedule a refresh of the catalog.\n *\n * @param taskRunner - The instance of {@link SchedulerServiceTaskRunner}.\n *\n * @private\n */\n private createScheduleFn(\n taskRunner: SchedulerServiceTaskRunner,\n ): () => Promise<void> {\n return async () => {\n const taskId = `${this.getProviderName()}:refresh`;\n return taskRunner.run({\n id: taskId,\n fn: async () => {\n const logger = this.logger.child({\n class: PuppetDbEntityProvider.prototype.constructor.name,\n taskId,\n taskInstanceId: uuid.v4(),\n });\n try {\n await this.refresh(logger);\n } catch (error) {\n logger.error(\n `${this.getProviderName()} refresh failed, ${error}`,\n error,\n );\n }\n },\n });\n };\n }\n\n /**\n * Refreshes the catalog by reading nodes from PuppetDB and registering them as Resource Entities.\n *\n * @param logger - The instance of a Logger.\n */\n async refresh(logger: LoggerService) {\n if (!this.connection) {\n throw new Error('Not initialized');\n }\n\n const { markReadComplete } = trackProgress(logger);\n const entities = await readPuppetNodes(this.config, {\n logger,\n transformer: this.transformer,\n });\n const { markCommitComplete } = markReadComplete(entities);\n\n await this.connection.applyMutation({\n type: 'full',\n entities: [...entities].map(entity => ({\n locationKey: this.getProviderName(),\n entity: withLocations(this.config.baseUrl, entity),\n })),\n });\n markCommitComplete(entities);\n }\n}\n\n/**\n * Ensures the entities have required annotation data.\n *\n * @param baseUrl - The base URL of the PuppetDB instance.\n * @param entity - The entity to add the annotations to.\n *\n * @returns Entity with @{@link ANNOTATION_LOCATION} and @{@link ANNOTATION_ORIGIN_LOCATION} annotations.\n */\nfunction withLocations(baseUrl: string, entity: Entity): Entity {\n const location = `${baseUrl}/${ENDPOINT_NODES}/${entity.metadata?.name}`;\n\n return merge(\n {\n metadata: {\n annotations: {\n [ANNOTATION_LOCATION]: `url:${location}`,\n [ANNOTATION_ORIGIN_LOCATION]: `url:${location}`,\n },\n },\n },\n entity,\n ) as Entity;\n}\n\n/**\n * Tracks the progress of the PuppetDB read and commit operations.\n *\n * @param logger - The instance of a {@link LoggerService}.\n */\nfunction trackProgress(logger: LoggerService) {\n let timestamp = Date.now();\n\n function markReadComplete(entities: Entity[]) {\n const readDuration = ((Date.now() - timestamp) / 1000).toFixed(1);\n timestamp = Date.now();\n logger.info(\n `Read ${entities?.length ?? 0} in ${readDuration} seconds. Committing...`,\n );\n return { markCommitComplete };\n }\n\n function markCommitComplete(entities: Entity[]) {\n const commitDuration = ((Date.now() - timestamp) / 1000).toFixed(1);\n logger.info(\n `Committed ${entities?.length ?? 0} in ${commitDuration} seconds.`,\n );\n }\n\n return { markReadComplete };\n}\n"],"names":["readSchedulerServiceTaskScheduleDefinitionFromConfig","DEFAULT_NAMESPACE","fetch","ResponseError","uuid","merge","ANNOTATION_LOCATION","ANNOTATION_ORIGIN_LOCATION"],"mappings":"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"}