Feature: Add ArgoCD widget (#4305)
Co-authored-by: shamoon <4887959+shamoon@users.noreply.github.com>pull/4315/head
parent
adde687331
commit
4a3a4c846e
@ -0,0 +1,33 @@
|
||||
---
|
||||
title: ArgoCD
|
||||
description: ArgoCD Widget Configuration
|
||||
---
|
||||
|
||||
Learn more about [ArgoCD](https://argo-cd.readthedocs.io/en/stable/).
|
||||
|
||||
Allowed fields (limited to a max of 4): `["apps", "synced", "outOfSync", "healthy", "progressing", "degraded", "suspended", "missing"]`
|
||||
|
||||
```yaml
|
||||
widget:
|
||||
type: argocd
|
||||
url: http://argocd.host.or.ip:port
|
||||
key: argocdapikey
|
||||
```
|
||||
|
||||
You can generate an API key either by creating a bearer token for an existing account, see [Authorization](https://argo-cd.readthedocs.io/en/latest/developer-guide/api-docs/#authorization) (not recommended) or create a new local user account with limited privileges and generate an authentication token for this account. To do this the steps are:
|
||||
|
||||
- [Create a new local user](https://argo-cd.readthedocs.io/en/stable/operator-manual/user-management/#create-new-user) and give it the `apiKey` capability
|
||||
- Setup [RBAC configuration](https://argo-cd.readthedocs.io/en/stable/operator-manual/rbac/#rbac-configuration) for your the user and give it readonly access to your ArgoCD resources, e.g. by giving it the `role:readonly` role.
|
||||
- In your ArgoCD project under _Settings / Accounts_ open the newly created account and in the _Tokens_ section click on _Generate New_ to generate an access token, optionally specifying an expiry date.
|
||||
|
||||
If you installed ArgoCD via the official Helm chart, the account creation and rbac config can be achived by overriding these helm values:
|
||||
|
||||
```yaml
|
||||
configs:
|
||||
cm:
|
||||
accounts.readonly: apiKey
|
||||
rbac:
|
||||
policy.csv: "g, readonly, role:readonly"
|
||||
```
|
||||
|
||||
This creates a new account called `readonly` and attaches the `role:readonly` role to it.
|
@ -0,0 +1,52 @@
|
||||
import Container from "components/services/widget/container";
|
||||
import Block from "components/services/widget/block";
|
||||
import useWidgetAPI from "utils/proxy/use-widget-api";
|
||||
|
||||
export default function Component({ service }) {
|
||||
const { widget } = service;
|
||||
|
||||
if (!widget.fields) {
|
||||
widget.fields = ["apps", "synced", "outOfSync", "healthy"];
|
||||
}
|
||||
|
||||
const MAX_ALLOWED_FIELDS = 4;
|
||||
if (widget.fields.length > MAX_ALLOWED_FIELDS) {
|
||||
widget.fields = widget.fields.slice(0, MAX_ALLOWED_FIELDS);
|
||||
}
|
||||
|
||||
const { data: appsData, error: appsError } = useWidgetAPI(widget, "applications");
|
||||
|
||||
const appCounts = widget.fields.map((status) => {
|
||||
if (status === "apps") {
|
||||
return { status, count: appsData?.items?.length };
|
||||
}
|
||||
const count = appsData?.items?.filter(
|
||||
(item) =>
|
||||
item.status?.sync?.status.toLowerCase() === status.toLowerCase() ||
|
||||
item.status?.health?.status.toLowerCase() === status.toLowerCase(),
|
||||
).length;
|
||||
return { status, count };
|
||||
});
|
||||
|
||||
if (appsError) {
|
||||
return <Container service={service} error={appsError} />;
|
||||
}
|
||||
|
||||
if (!appsData) {
|
||||
return (
|
||||
<Container service={service}>
|
||||
{appCounts.map((a) => (
|
||||
<Block label={`argocd.${a.status}`} key={a.status} />
|
||||
))}
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
return (
|
||||
<Container service={service}>
|
||||
{appCounts.map((a) => (
|
||||
<Block label={`argocd.${a.status}`} key={a.status} value={a.count} />
|
||||
))}
|
||||
</Container>
|
||||
);
|
||||
}
|
@ -0,0 +1,14 @@
|
||||
import credentialedProxyHandler from "utils/proxy/handlers/credentialed";
|
||||
|
||||
const widget = {
|
||||
api: "{url}/api/v1/{endpoint}",
|
||||
proxyHandler: credentialedProxyHandler,
|
||||
|
||||
mappings: {
|
||||
applications: {
|
||||
endpoint: "applications",
|
||||
},
|
||||
},
|
||||
};
|
||||
|
||||
export default widget;
|
Loading…
Reference in new issue