Merge pull request #30144 from backstage/permissions/catalog-has-label-value

[Catalog] Add optional `value` to `HAS_LABEL` permission rule
This commit is contained in:
Eric Peterson
2025-06-04 13:53:38 +02:00
committed by GitHub
4 changed files with 76 additions and 5 deletions
+5
View File
@@ -0,0 +1,5 @@
---
'@backstage/plugin-catalog-backend': patch
---
You can now specify an optional value when applying the `HAS_LABEL` permission rule, similar to the `HAS_ANNOTATION` permission rule.
@@ -30,6 +30,7 @@ export const catalogConditions: Conditions<{
'catalog-entity',
{
label: string;
value?: string | undefined;
}
>;
hasMetadata: PermissionRule<
@@ -103,6 +104,7 @@ export const permissionRules: {
'catalog-entity',
{
label: string;
value?: string | undefined;
}
>;
hasMetadata: PermissionRule<
@@ -73,6 +73,50 @@ describe('hasLabel permission rule', () => {
),
).toEqual(true);
});
it('returns false when specified label has different than expected value', () => {
expect(
hasLabel.apply(
{
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
name: 'test-component',
labels: {
someLabel: 'foo',
'backstage.io/testLabel': 'bar',
},
},
},
{
label: 'backstage.io/testLabel',
value: 'baz',
},
),
).toEqual(false);
});
it('returns true when specified label has expected value', () => {
expect(
hasLabel.apply(
{
apiVersion: 'backstage.io/v1alpha1',
kind: 'Component',
metadata: {
name: 'test-component',
labels: {
someLabel: 'foo',
'backstage.io/testLabel': 'bar',
},
},
},
{
label: 'backstage.io/testLabel',
value: 'bar',
},
),
).toEqual(true);
});
});
describe('toQuery', () => {
@@ -85,5 +129,17 @@ describe('hasLabel permission rule', () => {
key: 'metadata.labels.backstage.io/testlabel',
});
});
it('returns an appropriate catalog-backend filter with values', () => {
expect(
hasLabel.toQuery({
label: 'backstage.io/testLabel',
value: 'foo',
}),
).toEqual({
key: 'metadata.labels.backstage.io/testLabel',
values: ['foo'],
});
});
});
});
@@ -29,10 +29,18 @@ export const hasLabel = createPermissionRule({
resourceRef: catalogEntityPermissionResourceRef,
paramsSchema: z.object({
label: z.string().describe('Name of the label to match on'),
value: z.string().optional().describe('Value of the label to match on'),
}),
apply: (resource, { label }) =>
!!resource.metadata.labels?.hasOwnProperty(label),
toQuery: ({ label }) => ({
key: `metadata.labels.${label}`,
}),
apply: (resource, { label, value }) =>
!!resource.metadata.labels?.hasOwnProperty(label) &&
(value === undefined ? true : resource.metadata.labels?.[label] === value),
toQuery: ({ label, value }) =>
value === undefined
? {
key: `metadata.labels.${label}`,
}
: {
key: `metadata.labels.${label}`,
values: [value],
},
});