pepr 0.52.3-nightly.0 → 0.52.3-nightly.2

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.
@@ -113,15 +113,9 @@ export function checkIronBankImage(registry: string, image: string, peprVersion:
113
113
  * @param imagePullSecret
114
114
  * @returns boolean
115
115
  */
116
- export function validImagePullSecret(imagePullSecretName: string): void {
117
- if (imagePullSecretName) {
118
- const error = "Invalid imagePullSecret. Please provide a valid name as defined in RFC 1123.";
119
- if (sanitizeResourceName(imagePullSecretName) !== imagePullSecretName) {
120
- // https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names
121
- console.error(error);
122
- process.exit(1);
123
- }
124
- }
116
+ export function validImagePullSecret(imagePullSecretName: string): boolean {
117
+ // https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names
118
+ return sanitizeResourceName(imagePullSecretName) === imagePullSecretName;
125
119
  }
126
120
 
127
121
  /**
@@ -11,7 +11,7 @@ import { PeprConfig, Reloader } from "../types";
11
11
  import { BuildContext } from "esbuild";
12
12
  import { loadModule } from "./loadModule";
13
13
 
14
- type BuildModuleReturn = {
14
+ export type BuildModuleReturn = {
15
15
  ctx: BuildContext<BuildOptions>;
16
16
  path: string;
17
17
  cfg: PeprConfig;
@@ -15,6 +15,7 @@ import {
15
15
  generateYamlAndWriteToDisk,
16
16
  } from "./build.helpers";
17
17
  import { buildModule } from "./buildModule";
18
+ import Log from "../../lib/telemetry/logger";
18
19
 
19
20
  export default function (program: Command): void {
20
21
  program
@@ -53,7 +54,7 @@ export default function (program: Command): void {
53
54
  .option("-o, --output <directory>", "Set output directory.", "dist")
54
55
  .addOption(
55
56
  new Option(
56
- "-r, --registry <GitHub|Iron Bank>",
57
+ "-r, --registry <registry>",
57
58
  "Container registry: Choose container registry for deployment manifests. Conflicts with --custom-image and --registry-info.",
58
59
  )
59
60
  .conflicts(["customImage", "registryInfo"])
@@ -99,7 +100,7 @@ export default function (program: Command): void {
99
100
  }
100
101
 
101
102
  if (opts.registryInfo !== undefined) {
102
- console.info(`Including ${cfg.pepr.includedFiles.length} files in controller image.`);
103
+ Log.info(`Including ${cfg.pepr.includedFiles.length} files in controller image.`);
103
104
  // for journey test to make sure the image is built
104
105
 
105
106
  // only actually build/push if there are files to include
@@ -113,7 +114,7 @@ export default function (program: Command): void {
113
114
 
114
115
  // If building without embedding, exit after building
115
116
  if (!opts.embed) {
116
- console.info(`Module built successfully at ${path}`);
117
+ Log.info(`Module built successfully at ${path}`);
117
118
  return;
118
119
  }
119
120
 
@@ -136,7 +137,11 @@ export default function (program: Command): void {
136
137
  if (image !== "") assets.image = image;
137
138
 
138
139
  // Ensure imagePullSecret is valid
139
- validImagePullSecret(opts.withPullSecret);
140
+ if (!validImagePullSecret(opts.withPullSecret)) {
141
+ throw new Error(
142
+ "Invalid imagePullSecret. Please provide a valid name as defined in RFC 1123.",
143
+ );
144
+ }
140
145
 
141
146
  handleValidCapabilityNames(assets.capabilities);
142
147
  await generateYamlAndWriteToDisk({
@@ -0,0 +1,48 @@
1
+ import { Assets } from "../../lib/assets/assets";
2
+ import { deployWebhook } from "../../lib/assets/deploy";
3
+ import { loadCapabilities } from "../../lib/assets/loader";
4
+ import { namespaceDeploymentsReady } from "../../lib/deploymentChecks";
5
+ import { namespaceComplianceValidator, validateCapabilityNames } from "../../lib/helpers";
6
+ import { CapabilityExport } from "../../lib/types";
7
+ import { buildModule } from "../build/buildModule";
8
+
9
+ export async function buildAndDeployModule(image: string, force: boolean): Promise<void> {
10
+ const builtModule = await buildModule("dist");
11
+ if (!builtModule) {
12
+ return;
13
+ }
14
+
15
+ // Generate a secret for the module
16
+ const webhook = new Assets(
17
+ { ...builtModule.cfg.pepr, description: builtModule.cfg.description },
18
+ builtModule.path,
19
+ [],
20
+ );
21
+ webhook.image = image ?? webhook.image;
22
+ const capabilities = await loadCapabilities(webhook.path);
23
+ for (const capability of capabilities) {
24
+ validateNamespaces(capability, webhook);
25
+ }
26
+ try {
27
+ await webhook.deploy(deployWebhook, force, builtModule.cfg.pepr.webhookTimeout ?? 10);
28
+
29
+ // wait for capabilities to be loaded and test names
30
+ validateCapabilityNames(webhook.capabilities);
31
+
32
+ // Wait for the pepr-system resources to be fully up
33
+ await namespaceDeploymentsReady();
34
+ console.info(`Module deployed successfully`);
35
+ } catch (e) {
36
+ console.error(`Error deploying module:`, e);
37
+ process.exit(1);
38
+ }
39
+ }
40
+ export function validateNamespaces(capability: CapabilityExport, webhook: Assets): void {
41
+ namespaceComplianceValidator(capability, webhook.alwaysIgnore?.namespaces);
42
+ namespaceComplianceValidator(
43
+ capability,
44
+ webhook.config.admission?.alwaysIgnore?.namespaces,
45
+ false,
46
+ );
47
+ namespaceComplianceValidator(capability, webhook.config.watch?.alwaysIgnore?.namespaces, true);
48
+ }
@@ -0,0 +1,68 @@
1
+ import { ImagePullSecret } from "../../lib/types";
2
+ import { sanitizeName } from "../init/utils";
3
+
4
+ export interface ImagePullSecretDetails {
5
+ pullSecret?: string;
6
+ dockerServer?: string;
7
+ dockerUsername?: string;
8
+ dockerEmail?: string;
9
+ dockerPassword?: string;
10
+ }
11
+
12
+ export function validateImagePullSecretDetails(details: ImagePullSecretDetails): {
13
+ valid: boolean;
14
+ error?: string;
15
+ } {
16
+ if (!details.pullSecret) {
17
+ return { valid: true };
18
+ }
19
+
20
+ // https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names
21
+ if (details.pullSecret !== sanitizeName(details.pullSecret)) {
22
+ return {
23
+ valid: false,
24
+ error: `Invalid --pullSecret. Must be valid name as defined in RFC 1123.`,
25
+ };
26
+ }
27
+
28
+ const missing: string[] = [];
29
+ if (!details.dockerEmail) {
30
+ missing.push("--docker-email");
31
+ }
32
+ if (!details.dockerServer) {
33
+ missing.push("--docker-server");
34
+ }
35
+ if (!details.dockerUsername) {
36
+ missing.push("--docker-username");
37
+ }
38
+ if (!details.dockerPassword) {
39
+ missing.push("--docker-password");
40
+ }
41
+
42
+ if (missing.length > 0) {
43
+ return {
44
+ valid: false,
45
+ error: `Error: Must provide ${missing.join(", ")} when providing --pull-secret`,
46
+ };
47
+ }
48
+
49
+ return { valid: true };
50
+ }
51
+
52
+ type ValidatedImagePullSecretDetails = Required<ImagePullSecretDetails>;
53
+
54
+ export function generateImagePullSecret(details: ValidatedImagePullSecretDetails): ImagePullSecret {
55
+ const auth = Buffer.from(`${details.dockerUsername}:${details.dockerPassword}`).toString(
56
+ "base64",
57
+ );
58
+ return {
59
+ auths: {
60
+ [details.dockerServer]: {
61
+ username: details.dockerUsername,
62
+ password: details.dockerPassword,
63
+ email: details.dockerEmail,
64
+ auth,
65
+ },
66
+ },
67
+ };
68
+ }
@@ -0,0 +1,40 @@
1
+ // SPDX-License-Identifier: Apache-2.0
2
+ // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
+
4
+ import { Command } from "commander";
5
+ import { deployImagePullSecret } from "../../lib/assets/deploy";
6
+ import { validateImagePullSecretDetails, generateImagePullSecret } from "./imagePullSecret";
7
+ import { getUserConfirmation } from "./userConfirmation";
8
+ import { buildAndDeployModule } from "./buildAndDeploy";
9
+
10
+ export default function (program: Command): void {
11
+ program
12
+ .command("deploy")
13
+ .description("Deploy a Pepr Module")
14
+ .option("-E, --docker-email <email>", "Email for Docker registry.")
15
+ .option("-P, --docker-password <password>", "Password for Docker registry.")
16
+ .option("-S, --docker-server <server>", "Docker server address.")
17
+ .option("-U, --docker-username <username>", "Docker registry username.")
18
+ .option("-f, --force", "Force deploy the module, override manager field.")
19
+ .option("-i, --image <image>", "Override the image tag.")
20
+ .option("-p, --pull-secret <name>", "Deploy imagePullSecret for Controller private registry.")
21
+ .option("-y, --yes", "Skip confirmation prompts.")
22
+ .action(async opts => {
23
+ const valResp = validateImagePullSecretDetails(opts);
24
+ if (!valResp.valid) {
25
+ console.error(valResp.error);
26
+ process.exit(1);
27
+ }
28
+
29
+ if (opts.pullSecret) {
30
+ await deployImagePullSecret(generateImagePullSecret(opts), opts.pullSecret);
31
+ return;
32
+ }
33
+
34
+ if (!(await getUserConfirmation(opts))) {
35
+ process.exit(0);
36
+ }
37
+
38
+ await buildAndDeployModule(opts.image, opts.force);
39
+ });
40
+ }
@@ -0,0 +1,16 @@
1
+ import prompt from "prompts";
2
+
3
+ export async function getUserConfirmation(opts: { yes: boolean }): Promise<boolean> {
4
+ if (opts.yes) {
5
+ return true;
6
+ }
7
+
8
+ // Prompt the user to confirm
9
+ const confirmation = await prompt({
10
+ type: "confirm",
11
+ name: "yes",
12
+ message: "This will remove and redeploy the module. Continue?",
13
+ });
14
+
15
+ return confirmation.yes ? true : false;
16
+ }
@@ -1,21 +0,0 @@
1
- import { CapabilityExport } from "../lib/types";
2
- import { Assets } from "../lib/assets/assets";
3
- import { Command } from "commander";
4
- interface ImagePullSecretDetails {
5
- pullSecret?: string;
6
- dockerServer?: string;
7
- dockerUsername?: string;
8
- dockerEmail?: string;
9
- dockerPassword?: string;
10
- }
11
- export declare function validateImagePullSecretDetails(details: ImagePullSecretDetails): {
12
- valid: boolean;
13
- error?: string;
14
- };
15
- export declare function getUserConfirmation(opts: {
16
- yes: boolean;
17
- }): Promise<boolean>;
18
- export default function (program: Command): void;
19
- export declare function validateNamespaces(capability: CapabilityExport, webhook: Assets): void;
20
- export {};
21
- //# sourceMappingURL=deploy.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/cli/deploy.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,gBAAgB,EAAE,MAAM,cAAc,CAAC;AAChD,OAAO,EAAE,MAAM,EAAE,MAAM,sBAAsB,CAAC;AAE9C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,UAAU,sBAAsB;IAC9B,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,wBAAgB,8BAA8B,CAAC,OAAO,EAAE,sBAAsB,GAAG;IAC/E,KAAK,EAAE,OAAO,CAAC;IACf,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,CAmCA;AAoBD,wBAAsB,mBAAmB,CAAC,IAAI,EAAE;IAAE,GAAG,EAAE,OAAO,CAAA;CAAE,GAAG,OAAO,CAAC,OAAO,CAAC,CAalF;AAkCD,MAAM,CAAC,OAAO,WAAW,OAAO,EAAE,OAAO,GAAG,IAAI,CA8B/C;AAED,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,gBAAgB,EAAE,OAAO,EAAE,MAAM,GAAG,IAAI,CAQtF"}
package/src/cli/deploy.ts DELETED
@@ -1,170 +0,0 @@
1
- // SPDX-License-Identifier: Apache-2.0
2
- // SPDX-FileCopyrightText: 2023-Present The Pepr Authors
3
-
4
- import prompt from "prompts";
5
- import { CapabilityExport } from "../lib/types";
6
- import { Assets } from "../lib/assets/assets";
7
- import { ImagePullSecret } from "../lib/types";
8
- import { Command } from "commander";
9
- import { buildModule } from "./build/buildModule";
10
- import { deployImagePullSecret, deployWebhook } from "../lib/assets/deploy";
11
- import { namespaceDeploymentsReady } from "../lib/deploymentChecks";
12
- import { sanitizeName } from "./init/utils";
13
- import { validateCapabilityNames } from "../lib/helpers";
14
- import { namespaceComplianceValidator } from "../lib/helpers";
15
- import { loadCapabilities } from "../lib/assets/loader";
16
-
17
- interface ImagePullSecretDetails {
18
- pullSecret?: string;
19
- dockerServer?: string;
20
- dockerUsername?: string;
21
- dockerEmail?: string;
22
- dockerPassword?: string;
23
- }
24
-
25
- export function validateImagePullSecretDetails(details: ImagePullSecretDetails): {
26
- valid: boolean;
27
- error?: string;
28
- } {
29
- if (!details.pullSecret) {
30
- return { valid: true };
31
- }
32
-
33
- // https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#dns-subdomain-names
34
- if (details.pullSecret !== sanitizeName(details.pullSecret)) {
35
- return {
36
- valid: false,
37
- error: `Invalid --pullSecret. Must be valid name as defined in RFC 1123.`,
38
- };
39
- }
40
-
41
- const missing: string[] = [];
42
- if (!details.dockerEmail) {
43
- missing.push("--docker-email");
44
- }
45
- if (!details.dockerServer) {
46
- missing.push("--docker-server");
47
- }
48
- if (!details.dockerUsername) {
49
- missing.push("--docker-username");
50
- }
51
- if (!details.dockerPassword) {
52
- missing.push("--docker-password");
53
- }
54
-
55
- if (missing.length > 0) {
56
- return {
57
- valid: false,
58
- error: `Error: Must provide ${missing.join(", ")} when providing --pull-secret`,
59
- };
60
- }
61
-
62
- return { valid: true };
63
- }
64
-
65
- type ValidatedImagePullSecretDetails = Required<ImagePullSecretDetails>;
66
-
67
- function generateImagePullSecret(details: ValidatedImagePullSecretDetails): ImagePullSecret {
68
- const auth = Buffer.from(`${details.dockerUsername}:${details.dockerPassword}`).toString(
69
- "base64",
70
- );
71
- return {
72
- auths: {
73
- [details.dockerServer]: {
74
- username: details.dockerUsername,
75
- password: details.dockerPassword,
76
- email: details.dockerEmail,
77
- auth,
78
- },
79
- },
80
- };
81
- }
82
-
83
- export async function getUserConfirmation(opts: { yes: boolean }): Promise<boolean> {
84
- if (opts.yes) {
85
- return true;
86
- }
87
-
88
- // Prompt the user to confirm
89
- const confirmation = await prompt({
90
- type: "confirm",
91
- name: "yes",
92
- message: "This will remove and redeploy the module. Continue?",
93
- });
94
-
95
- return confirmation.yes ? true : false;
96
- }
97
-
98
- async function buildAndDeployModule(image: string, force: boolean): Promise<void> {
99
- const builtModule = await buildModule("dist");
100
- if (!builtModule) {
101
- return;
102
- }
103
-
104
- // Generate a secret for the module
105
- const webhook = new Assets(
106
- { ...builtModule.cfg.pepr, description: builtModule.cfg.description },
107
- builtModule.path,
108
- [],
109
- );
110
- webhook.image = image ?? webhook.image;
111
- const capabilities = await loadCapabilities(webhook.path);
112
- for (const capability of capabilities) {
113
- validateNamespaces(capability, webhook);
114
- }
115
- try {
116
- await webhook.deploy(deployWebhook, force, builtModule.cfg.pepr.webhookTimeout ?? 10);
117
-
118
- // wait for capabilities to be loaded and test names
119
- validateCapabilityNames(webhook.capabilities);
120
-
121
- // Wait for the pepr-system resources to be fully up
122
- await namespaceDeploymentsReady();
123
- console.info(`✅ Module deployed successfully`);
124
- } catch (e) {
125
- console.error(`Error deploying module:`, e);
126
- process.exit(1);
127
- }
128
- }
129
-
130
- export default function (program: Command): void {
131
- program
132
- .command("deploy")
133
- .description("Deploy a Pepr Module")
134
- .option("-E, --docker-email <email>", "Email for Docker registry.")
135
- .option("-P, --docker-password <password>", "Password for Docker registry.")
136
- .option("-S, --docker-server <server>", "Docker server address.")
137
- .option("-U, --docker-username <username>", "Docker registry username.")
138
- .option("-f, --force", "Force deploy the module, override manager field.")
139
- .option("-i, --image <image>", "Override the image tag.")
140
- .option("-p, --pull-secret <name>", "Deploy imagePullSecret for Controller private registry.")
141
- .option("-y, --yes", "Skip confirmation prompts.")
142
- .action(async opts => {
143
- const valResp = validateImagePullSecretDetails(opts);
144
- if (!valResp.valid) {
145
- console.error(valResp.error);
146
- process.exit(1);
147
- }
148
-
149
- if (opts.pullSecret) {
150
- await deployImagePullSecret(generateImagePullSecret(opts), opts.pullSecret);
151
- return;
152
- }
153
-
154
- if (!(await getUserConfirmation(opts))) {
155
- process.exit(0);
156
- }
157
-
158
- await buildAndDeployModule(opts.image, opts.force);
159
- });
160
- }
161
-
162
- export function validateNamespaces(capability: CapabilityExport, webhook: Assets): void {
163
- namespaceComplianceValidator(capability, webhook.alwaysIgnore?.namespaces);
164
- namespaceComplianceValidator(
165
- capability,
166
- webhook.config.admission?.alwaysIgnore?.namespaces,
167
- false,
168
- );
169
- namespaceComplianceValidator(capability, webhook.config.watch?.alwaysIgnore?.namespaces, true);
170
- }