Skip to content

Commit d8bb81e

Browse files
authored
Minor API docs improvement (#90)
* Minor change to api docs * Throw ConfigError instead of TypeError in Configs methods * Temp hack with --global-scope
1 parent e264264 commit d8bb81e

File tree

15 files changed

+155
-141
lines changed

15 files changed

+155
-141
lines changed

docs/api/classes/_types_.configs.md

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ Creates a Config.
4040

4141
Name | Type | Default | Description |
4242
------ | ------ | ------ | ------ |
43-
`input` | [KubernetesObject](../interfaces/_types_.kubernetesobject.md)[] | [] | Input Kubernetes objects. If supplied multiple objects with the same (Group, Kind, Namespace, Name) discards all but the last one. Does not preserve insertion order of the passed objects. |
43+
`input` | [KubernetesObject](../interfaces/_types_.kubernetesobject.md)[] | [] | Input Kubernetes objects. If supplied multiple objects with the same [kubernetesKey](../modules/_types_.md#kuberneteskey) discards all but the last one. Does not preserve insertion order of the given objects. |
4444
`functionConfig?` | [KubernetesObject](../interfaces/_types_.kubernetesobject.md) | - | Kubernetes object used to parameterize the function's behavior. |
4545

4646
**Returns:** *[Configs](_types_.configs.md)*
@@ -51,9 +51,9 @@ Name | Type | Default | Description |
5151

5252
**delete**(...`objects`: [KubernetesObject](../interfaces/_types_.kubernetesobject.md)[]): *void*
5353

54-
Deletes all objects with the same (Group, Kind, Namespace, Name) as any of the passed objects.
54+
Deletes all objects with the same [kubernetesKey](../modules/_types_.md#kuberneteskey) as any of the given objects.
5555

56-
Does not throw if passed duplicates or keys which are not present in the Configs.
56+
Does not throw if given duplicates or keys which are not present in the Configs.
5757

5858
**Parameters:**
5959

@@ -79,7 +79,7 @@ ___
7979

8080
**get**<**Kind**>(`isKind`: function): *Kind[]*
8181

82-
Returns an array of objects matching the passed Kind type predicate.
82+
Returns an array of objects matching the given Kind type predicate.
8383

8484
Casts to an array of Kind. May throw if isKind is incorrect.
8585

@@ -139,12 +139,12 @@ ___
139139

140140
Returns the value for the given key if functionConfig is of kind ConfigMap.
141141

142-
Throws a TypeError exception if functionConfig kind is not a ConfigMap.
142+
Throws a ConfigError if functionConfig kind is not a ConfigMap.
143143

144144
Returns undefined if functionConfig is undefined OR
145145
if the ConfigMap has no such key in the 'data' section.
146146

147-
**`key`** key The key in the 'data' field in the ConfigMap object passed as the functionConfig.
147+
**`key`** key The key in the 'data' field in the ConfigMap object given as the functionConfig.
148148

149149
**Parameters:**
150150

@@ -160,7 +160,7 @@ ___
160160

161161
**getFunctionConfigValueOrThrow**(`key`: string): *string*
162162

163-
Similar to [getFunctionConfigValue](_types_.configs.md#getfunctionconfigvalue) except it throws a TypeError exception if the given key is undefined.
163+
Similar to [getFunctionConfigValue](_types_.configs.md#getfunctionconfigvalue) except it throws a ConfigError if the given key is undefined.
164164

165165
**Parameters:**
166166

@@ -210,12 +210,12 @@ ___
210210

211211
Inserts objects into the Configs.
212212

213-
If another object already in Configs has the same (Group, Kind, Namespace, Name), replaces that one with the
214-
passed object.
213+
If another object already in Configs has the same [kubernetesKey](../modules/_types_.md#kuberneteskey), replaces that one with the
214+
given object.
215215

216-
If multiple objects have the same (Group, Kind, Namespace, Name), discards all but the last one.
216+
If inserting multiple objects with the same [kubernetesKey](../modules/_types_.md#kuberneteskey), discards all but the last one.
217217

218-
Does not preserve insertion order of the passed objects.
218+
Does not preserve insertion order of the given objects.
219219

220220
**Parameters:**
221221

docs/api/modules/_types_.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
### Functions
1717

1818
* [isKubernetesObject](_types_.md#iskubernetesobject)
19-
* [kubernetesKeyFn](_types_.md#kuberneteskeyfn)
19+
* [kubernetesKey](_types_.md#kuberneteskey)
2020

2121
## Functions
2222

@@ -36,11 +36,11 @@ Name | Type |
3636

3737
___
3838

39-
### kubernetesKeyFn
39+
### kubernetesKey
4040

41-
**kubernetesKeyFn**(`o`: [KubernetesObject](../interfaces/_types_.kubernetesobject.md)): *string*
41+
**kubernetesKey**(`o`: [KubernetesObject](../interfaces/_types_.kubernetesobject.md)): *string*
4242

43-
Generates the primary key for a Kubernetes objects in Configs.
43+
A unique key for a Kubernetes object defined as tuple of (apiVersion, kind, namespace, name).
4444

4545
**Parameters:**
4646

docs/run.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -75,7 +75,7 @@ EOF
7575
You should see the same results as in the previous examples:
7676

7777
```sh
78-
kpt fn run .
78+
kpt fn run --global-scope .
7979
git status
8080
```
8181

@@ -100,7 +100,7 @@ EOF
100100
`fn run` executes both functions:
101101

102102
```sh
103-
kpt fn run .
103+
kpt fn run --global-scope .
104104
```
105105

106106
In this case, `validate-rolebinding` will find policy violations and fail with a non-zero exit code.

ts/demo-functions/package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
"build": "tsc",
1010
"watch": "tsc --watch",
1111
"clean": "rm -Rf node_modules/ dist/",
12-
"lint": "tslint -p package.json; prettier \"src/**\" \"*.json\" --check",
12+
"lint": "tslint -p package.json && prettier \"src/**\" \"*.json\" --check",
1313
"lint-license": "license-checker --onlyAllow 'Apache-2.0;MIT;BSD;BSD-2-Clause;BSD-3-Clause;ISC;CC-BY-3.0;CC0-1.0;Unlicense'",
1414
"format": "prettier \"src/**\" \"*.json\" --write",
1515
"pretest": "npm run build",

ts/demo-functions/src/expand_team_test.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -20,17 +20,6 @@ import { Namespace } from './gen/io.k8s.api.core.v1';
2020
import { ClusterRole, RoleBinding, Subject } from './gen/io.k8s.api.rbac.v1';
2121
import { expandTeamCr } from './expand_team_cr';
2222

23-
function team(name: string, ...roles: Team.Spec.Item[]): Team {
24-
const team = new Team({
25-
metadata: { name },
26-
spec: {},
27-
});
28-
if (roles.length) {
29-
team.spec.roles = roles;
30-
}
31-
return team;
32-
}
33-
3423
const RUNNER = new TestRunner(expandTeamCr);
3524

3625
describe(expandTeamCr.name, () => {
@@ -225,3 +214,14 @@ describe(expandTeamCr.name, () => {
225214
),
226215
);
227216
});
217+
218+
function team(name: string, ...roles: Team.Spec.Item[]): Team {
219+
const team = new Team({
220+
metadata: { name },
221+
spec: {},
222+
});
223+
if (roles.length) {
224+
team.spec.roles = roles;
225+
}
226+
return team;
227+
}

ts/demo-functions/src/label_namespace.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@
1717
import { addLabel, Configs } from '@googlecontainertools/kpt-functions';
1818
import { isNamespace } from './gen/io.k8s.api.core.v1';
1919

20-
export const LABEL_NAME = 'label_name';
21-
export const LABEL_VALUE = 'label_value';
20+
const LABEL_NAME = 'label_name';
21+
const LABEL_VALUE = 'label_value';
2222

2323
export async function labelNamespace(configs: Configs) {
2424
const labelName = configs.getFunctionConfigValueOrThrow(LABEL_NAME);

ts/demo-functions/src/label_namespace_test.ts

Lines changed: 17 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -15,31 +15,29 @@
1515
*/
1616

1717
import { Configs, TestRunner } from '@googlecontainertools/kpt-functions';
18-
import { labelNamespace, LABEL_NAME, LABEL_VALUE } from './label_namespace';
18+
import { labelNamespace } from './label_namespace';
1919
import { Namespace, ConfigMap } from './gen/io.k8s.api.core.v1';
2020

21+
const RUNNER = new TestRunner(labelNamespace);
2122
const TEST_NAMESPACE = 'testNamespace';
2223
const TEST_LABEL_NAME = 'costCenter';
2324
const TEST_LABEL_VALUE = 'xyz';
25+
const FUNC_CONFIG: ConfigMap = new ConfigMap({
26+
metadata: { name: 'config' },
27+
data: { label_name: 'costCenter', label_value: 'xyz' },
28+
});
2429

2530
describe('labelNamespace', () => {
26-
let functionConfig = ConfigMap.named('foo');
27-
functionConfig.data = {};
28-
functionConfig.data[LABEL_NAME] = TEST_LABEL_NAME;
29-
functionConfig.data[LABEL_VALUE] = TEST_LABEL_VALUE;
30-
31-
const RUNNER = new TestRunner(labelNamespace);
32-
33-
it('empty input ok', RUNNER.assertCallback(new Configs(undefined, functionConfig)));
31+
it('empty input ok', RUNNER.assertCallback(new Configs(undefined, FUNC_CONFIG)));
3432

3533
it('requires functionConfig', RUNNER.assertCallback(undefined, undefined, TypeError));
3634

3735
it('adds label namespace when metadata.labels is undefined', async () => {
38-
const actual = new Configs(undefined, functionConfig);
39-
actual.insert(Namespace.named(TEST_NAMESPACE));
36+
const input = new Configs(undefined, FUNC_CONFIG);
37+
input.insert(Namespace.named(TEST_NAMESPACE));
4038

41-
const expected = new Configs();
42-
expected.insert(
39+
const output = new Configs();
40+
output.insert(
4341
new Namespace({
4442
metadata: {
4543
name: TEST_NAMESPACE,
@@ -48,12 +46,12 @@ describe('labelNamespace', () => {
4846
}),
4947
);
5048

51-
await RUNNER.assert(actual, expected);
49+
await RUNNER.assert(input, output);
5250
});
5351

5452
it('adds label to namespace when metadata.labels is defined', async () => {
55-
const actual = new Configs(undefined, functionConfig);
56-
actual.insert(
53+
const input = new Configs(undefined, FUNC_CONFIG);
54+
input.insert(
5755
new Namespace({
5856
metadata: {
5957
name: TEST_NAMESPACE,
@@ -62,8 +60,8 @@ describe('labelNamespace', () => {
6260
}),
6361
);
6462

65-
const expected = new Configs();
66-
expected.insert(
63+
const output = new Configs();
64+
output.insert(
6765
new Namespace({
6866
metadata: {
6967
name: TEST_NAMESPACE,
@@ -75,6 +73,6 @@ describe('labelNamespace', () => {
7573
}),
7674
);
7775

78-
await RUNNER.assert(actual, expected);
76+
await RUNNER.assert(input, output);
7977
});
8078
});

ts/demo-functions/src/mutate_psp_test.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -18,25 +18,10 @@ import { Configs, TestRunner } from '@googlecontainertools/kpt-functions';
1818
import { PodSecurityPolicy } from './gen/io.k8s.api.policy.v1beta1';
1919
import { mutatePsp } from './mutate_psp';
2020

21-
function psp(allowPrivilegeEscalation: boolean): PodSecurityPolicy {
22-
return new PodSecurityPolicy({
23-
metadata: {
24-
name: 'pod',
25-
},
26-
spec: {
27-
allowPrivilegeEscalation,
28-
fsGroup: { rule: 'RunAsAny' },
29-
runAsUser: { rule: 'RunAsAny' },
30-
seLinux: { rule: 'RunAsAny' },
31-
supplementalGroups: { rule: 'RunAsAny' },
32-
},
33-
});
34-
}
35-
3621
const RUNNER = new TestRunner(mutatePsp);
3722

3823
describe('mutatePsp', () => {
39-
it('passes empty repos', RUNNER.assertCallback());
24+
it('empty configs is noop', RUNNER.assertCallback());
4025

4126
it(
4227
'modifies PSP with allowPrivilegeEscalation = true to false',
@@ -48,3 +33,18 @@ describe('mutatePsp', () => {
4833
RUNNER.assertCallback(new Configs([psp(false)])),
4934
);
5035
});
36+
37+
function psp(allowPrivilegeEscalation: boolean): PodSecurityPolicy {
38+
return new PodSecurityPolicy({
39+
metadata: {
40+
name: 'pod',
41+
},
42+
spec: {
43+
allowPrivilegeEscalation,
44+
fsGroup: { rule: 'RunAsAny' },
45+
runAsUser: { rule: 'RunAsAny' },
46+
seLinux: { rule: 'RunAsAny' },
47+
supplementalGroups: { rule: 'RunAsAny' },
48+
},
49+
});
50+
}

ts/demo-functions/src/read_yaml.ts

Lines changed: 21 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -17,13 +17,22 @@
1717
import * as fs from 'fs';
1818
import * as glob from 'glob';
1919
import { safeLoadAll } from 'js-yaml';
20-
import * as kpt from '@googlecontainertools/kpt-functions';
2120
import * as path from 'path';
21+
import {
22+
Configs,
23+
ConfigError,
24+
MultiConfigError,
25+
isKubernetesObject,
26+
ConfigFileError,
27+
addAnnotation,
28+
SOURCE_PATH_ANNOTATION,
29+
SOURCE_INDEX_ANNOTATION,
30+
} from '@googlecontainertools/kpt-functions';
2231

2332
export const SOURCE_DIR = 'source_dir';
2433
export const FILTER_IVNALID = 'filter_invalid';
2534

26-
export async function readYaml(configs: kpt.Configs) {
35+
export async function readYaml(configs: Configs) {
2736
// Get the parameters.
2837
const sourceDir = configs.getFunctionConfigValueOrThrow(SOURCE_DIR);
2938
const ignoreInvalid = configs.getFunctionConfigValue(FILTER_IVNALID) === 'true';
@@ -35,13 +44,13 @@ export async function readYaml(configs: kpt.Configs) {
3544
const files = glob.sync(sourceDir + '/**/*.+(yaml|yml)');
3645

3746
// Parse each file and convert it to a KubernetesObject.
38-
const errors: kpt.ConfigError[] = files
47+
const errors: ConfigError[] = files
3948
.map((f) => parseFile(configs, sourceDir, f, ignoreInvalid))
4049
.filter((err) => err !== undefined)
41-
.map((err) => err as kpt.ConfigError);
50+
.map((err) => err as ConfigError);
4251

4352
if (errors.length) {
44-
throw new kpt.MultiConfigError(
53+
throw new MultiConfigError(
4554
`Found files containing invalid objects. To filter invalid objects set ${FILTER_IVNALID} to 'true'.`,
4655
errors,
4756
);
@@ -67,21 +76,21 @@ metadata:
6776
`;
6877

6978
function parseFile(
70-
configs: kpt.Configs,
79+
configs: Configs,
7180
sourceDir: string,
7281
file: string,
7382
ignoreInvalid: boolean,
74-
): kpt.ConfigError | undefined {
83+
): ConfigError | undefined {
7584
const contents = readFileOrThrow(file);
7685
let objects = safeLoadAll(contents);
7786

7887
// Filter for objects that are not KubernetesObject. This is conditional on 'ignoreValid' parameter.
79-
const invalidObjects: object[] = objects.filter((o) => !kpt.isKubernetesObject(o));
88+
const invalidObjects: object[] = objects.filter((o) => !isKubernetesObject(o));
8089
if (invalidObjects.length) {
8190
if (ignoreInvalid) {
82-
objects = objects.filter((o) => kpt.isKubernetesObject(o));
91+
objects = objects.filter((o) => isKubernetesObject(o));
8392
} else {
84-
return new kpt.ConfigFileError(
93+
return new ConfigFileError(
8594
`File contains invalid Kubernetes objects '${JSON.stringify(invalidObjects)}'`,
8695
file,
8796
);
@@ -91,8 +100,8 @@ function parseFile(
91100
// Add the standard path and index annotations to preserve the filesystem hierarchy
92101
// and ordering within a file.
93102
objects.forEach((o, i) => {
94-
kpt.addAnnotation(o, kpt.SOURCE_PATH_ANNOTATION, path.relative(sourceDir, file));
95-
kpt.addAnnotation(o, kpt.SOURCE_INDEX_ANNOTATION, i.toString());
103+
addAnnotation(o, SOURCE_PATH_ANNOTATION, path.relative(sourceDir, file));
104+
addAnnotation(o, SOURCE_INDEX_ANNOTATION, i.toString());
96105
});
97106

98107
configs.insert(...objects);

0 commit comments

Comments
 (0)