feat(kubernetes): update k8s-backend plugin to use label selectors

update plugin to use label selectors when querying backend
This commit is contained in:
Moustafa Baiou
2020-10-19 23:22:08 -04:00
committed by moustafab
parent da2f4cd41a
commit e2085293a6
11 changed files with 132 additions and 74 deletions
+23 -2
View File
@@ -14,7 +14,12 @@ It is only meant for local development, and the setup for it can be found inside
## Surfacing your Kubernetes components as part of an entity
### Adding the entity annotation
There are 2 ways to surface your kubernetes components as part of an entity.
The label selector takes precedence over the annotation/service id.
### Common `backstage.io/kubernetes-id` label
#### Adding the entity annotation
In order for Backstage to detect that an entity has Kubernetes components,
the following annotation should be added to the entity.
@@ -24,7 +29,7 @@ annotations:
'backstage.io/kubernetes-id': dice-roller
```
### Labeling Kubernetes components
#### Labeling Kubernetes components
In order for Kubernetes components to show up in the service catalog
as a part of an entity, Kubernetes components must be labeled with the following label:
@@ -32,3 +37,19 @@ as a part of an entity, Kubernetes components must be labeled with the following
```yaml
'backstage.io/kubernetes-id': <ENTITY_NAME>
```
### Full label selector
#### Adding the entity label selector to the spec
In order for Backstage to detect that an entity has kubernetes components the `kubernetes.selector` must have a valid selector. (Currently only matchLabels is supported)
```yaml
spec:
kubernetes:
selector:
matchLabels:
someKey: someValue
other-key: other-value
app.kubernetes.io/name: dice-roller
```
@@ -20,6 +20,7 @@ import {
AuthRequestBody,
ObjectsByServiceIdResponse,
} from '@backstage/plugin-kubernetes-backend';
import { V1LabelSelector } from '@kubernetes/client-node';
export class KubernetesBackendClient implements KubernetesApi {
private readonly discoveryApi: DiscoveryApi;
@@ -50,10 +51,23 @@ export class KubernetesBackendClient implements KubernetesApi {
return await response.json();
}
async getObjectsByServiceId(
private parseLabelSelector(params: V1LabelSelector): string {
// TODO: figure out how to convert the selector to the full query param from the yaml
// (as shown here https://github.com/kubernetes/apimachinery/blob/master/pkg/labels/selector.go)
return Object.keys(params.matchLabels)
.map(key => `${key}=${params[key]}`)
.join(',');
}
async getObjectsByLabelSelector(
serviceId: String,
labelSelector: V1LabelSelector,
requestBody: AuthRequestBody,
): Promise<ObjectsByServiceIdResponse> {
return await this.getRequired(`/services/${serviceId}`, requestBody);
const labelSelectorQueryParams = this.parseLabelSelector(labelSelector);
return await this.getRequired(
`/services/${serviceId}?labelSelector=${labelSelectorQueryParams}`,
requestBody,
);
}
}
+3 -1
View File
@@ -19,6 +19,7 @@ import {
AuthRequestBody,
ObjectsByServiceIdResponse,
} from '@backstage/plugin-kubernetes-backend';
import { V1LabelSelector } from '@kubernetes/client-node';
export const kubernetesApiRef = createApiRef<KubernetesApi>({
id: 'plugin.kubernetes.service',
@@ -27,8 +28,9 @@ export const kubernetesApiRef = createApiRef<KubernetesApi>({
});
export interface KubernetesApi {
getObjectsByServiceId(
getObjectsByLabelSelector(
serviceId: String,
labelSelector: V1LabelSelector,
requestBody: AuthRequestBody,
): Promise<ObjectsByServiceIdResponse>;
}
@@ -41,6 +41,7 @@ import {
ExtensionsV1beta1Ingress,
V1ConfigMap,
V1HorizontalPodAutoscaler,
V1LabelSelector,
V1Service,
} from '@kubernetes/client-node';
import { Services } from '../Services';
@@ -129,9 +130,27 @@ export const KubernetesContent = ({ entity }: KubernetesContentProps) => {
);
}
// decide label selector to search by defaulting to this label
let labelSelector: V1LabelSelector = {
matchLabels: {
'backstage.io/kubernetes-id': entity.metadata.name,
},
};
if (
entity.spec.kubernetes &&
(entity.spec.kubernetes.selector as V1LabelSelector)
) {
labelSelector = entity.spec.kubernetes.selector;
}
// TODO: Add validation on contents/format of requestBody
kubernetesApi
.getObjectsByServiceId(entity.metadata.name, requestBody)
.getObjectsByLabelSelector(
entity.metadata.name,
labelSelector,
requestBody,
)
.then(result => {
setKubernetesObjects(result);
})