Skip to content

Commit

Permalink
Merge branch 'develop' into feature/tech-1647
Browse files Browse the repository at this point in the history
  • Loading branch information
mlabouardy authored Sep 20, 2023
2 parents 6c2461e + 530b6ff commit 3fdd3e0
Show file tree
Hide file tree
Showing 7 changed files with 204 additions and 25 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
</a>
</p>

[![Build and Test komiser](https://github.com/tailwarden/komiser/actions/workflows/build_test.yml/badge.svg)](https://github.com/tailwarden/komiser/actions/workflows/build_test.yml)
[![Price](https://img.shields.io/badge/price-FREE-0098f7.svg)](https://github.com/tailwarden/komiser/blob/master/LICENSE) [![Docker Stars](https://img.shields.io/docker/pulls/mlabouardy/komiser.svg)](https://hub.docker.com/r/mlabouardy/komiser)
[![ELv2 License](https://img.shields.io/badge/license-ELv2-green)](LICENSE) [![Docker Stars](https://img.shields.io/github/issues/tailwarden/komiser.svg)](https://github.com/tailwarden/komiser/issues) [![Discord](https://badgen.net/badge/icon/discord?icon=discord&label)](https://discord.tailwarden.com/)

Expand Down
35 changes: 35 additions & 0 deletions dashboard/components/icons/AlertCircleIcon.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import { SVGProps } from 'react';

const AlertCircleIcon = (props: SVGProps<SVGSVGElement>) => (
<svg
xmlns="http://www.w3.org/2000/svg"
viewBox="0 0 49 49"
fill="none"
{...props}
>
<circle cx="24.5" cy="24.5" r="24" fill="#FFE8E8" />
<path
d="M24.5 34.5C30.0228 34.5 34.5 30.0228 34.5 24.5C34.5 18.9772 30.0228 14.5 24.5 14.5C18.9772 14.5 14.5 18.9772 14.5 24.5C14.5 30.0228 18.9772 34.5 24.5 34.5Z"
stroke="#DE5E5E"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M24.5 20.5V24.5"
stroke="#DE5E5E"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
<path
d="M24.5 28.5H24.51"
stroke="#DE5E5E"
stroke-width="2"
stroke-linecap="round"
stroke-linejoin="round"
/>
</svg>
);

export default AlertCircleIcon;
134 changes: 133 additions & 1 deletion dashboard/pages/cloud-accounts.tsx
Original file line number Diff line number Diff line change
@@ -1,21 +1,77 @@
import Head from 'next/head';
import Image from 'next/image';
import { useEffect, useRef, useState } from 'react';

import classNames from 'classnames';

import providers from '../utils/providerHelper';

import Toast from '../components/toast/Toast';
import Modal from '../components/modal/Modal';
import Button from '../components/button/Button';
import EditIcon from '../components/icons/EditIcon';
import More2Icon from '../components/icons/More2Icon';
import DeleteIcon from '../components/icons/DeleteIcon';
import AlertCircleIcon from '../components/icons/AlertCircleIcon';
import CloudAccountsHeader from '../components/cloud-account/components/CloudAccountsHeader';
import CloudAccountsLayout from '../components/cloud-account/components/CloudAccountsLayout';

import useCloudAccount from '../components/cloud-account/hooks/useCloudAccounts/useCloudAccount';

function CloudAccounts() {
const optionsRef = useRef<HTMLDivElement | null>(null);
const [clickedItemId, setClickedItemId] = useState<string | null>(null);
const [editCloudAccount, setEditCloudAccount] = useState<boolean>(false);
const [removeCloudAccount, setRemoveCloudAccount] = useState<{
state: boolean;
accountName: string;
}>({
state: false,
accountName: ''
});

const { router, cloudAccounts, toast, dismissToast, isNotCustomView } =
useCloudAccount();

useEffect(() => {
const handleOutsideClick = (event: MouseEvent) => {
if (
optionsRef.current &&
!optionsRef.current.contains(event.target as Node)
) {
setClickedItemId(null); // Close the options if clicked outside
}
};

document.addEventListener('mousedown', handleOutsideClick);

return () => {
document.removeEventListener('mousedown', handleOutsideClick);
};
}, []);

const toggleOptions = (itemId: string) => {
setClickedItemId(prevClickedItemId => {
if (prevClickedItemId === itemId) {
return null; // Close on Clicking the same item's icon
}
return itemId;
});
};

const closeRemoveModal = () => {
setRemoveCloudAccount({
state: false,
accountName: ''
});
};

const deleteCloudAccount = () => {
const removalName = removeCloudAccount.accountName;
console.log('deleting', removalName);
// TODO: (onboarding-wizard) handle account removal API call here
};

return (
<>
<Head>
Expand All @@ -30,6 +86,7 @@ function CloudAccounts() {

{cloudAccounts.map(account => {
const { provider, name, status } = account;
const isOpen = clickedItemId === name;

return (
<div
Expand All @@ -43,12 +100,14 @@ function CloudAccounts() {
height={150}
className="h-12 w-12 rounded-full"
/>

<div className="mr-auto">
<p className="font-bold">{name}</p>
<p className="text-black-300">
{providers.providerLabel(provider)}
</p>
</div>

<div
className={classNames(
'group relative rounded-3xl px-2 py-1 text-sm',
Expand All @@ -66,12 +125,85 @@ function CloudAccounts() {
{status.message}
</div>
</div>
<More2Icon className="h-6 w-6" />

<More2Icon
className="h-6 w-6 cursor-pointer"
onClick={() => toggleOptions(name)}
/>

{isOpen && (
<div
ref={optionsRef}
className="absolute right-0 top-0 mr-5 mt-[70px] items-center rounded-md border border-black-130 bg-white p-4 shadow-xl"
style={{ zIndex: 1000 }}
>
<button
className="flex w-full rounded-md py-3 pl-3 pr-5 text-left text-sm text-black-400 hover:bg-black-150"
onClick={() => {
setEditCloudAccount(true);
setClickedItemId(null);
}}
>
<EditIcon className="mr-2 h-6 w-6" />
Edit cloud account
</button>
<button
className="flex w-full rounded-md py-3 pl-3 pr-5 text-left text-sm text-error-600 hover:bg-black-150"
onClick={() => {
setRemoveCloudAccount({
state: true,
accountName: name
});
setClickedItemId(null);
}}
>
<DeleteIcon className="mr-2 h-6 w-6" />
Remove account
</button>
</div>
)}
</div>
);
})}
</CloudAccountsLayout>

{/* Delete Modal */}
<Modal
isOpen={removeCloudAccount.state}
closeModal={() => closeRemoveModal()}
>
<div className="flex max-w-xl flex-col gap-y-6 p-8 text-black-400">
<div className="flex flex-col items-center gap-y-6">
<AlertCircleIcon className="h-16 w-16" />
<h1 className="text-center text-xl font-semibold text-black-800">
Are you sure you want to remove this cloud account?
</h1>
<h3 className="text-center">
All related data (like custom views and tags) will be deleted and
the {removeCloudAccount.accountName} account will be disconnected
from Komiser.
</h3>
</div>
<div className="flex flex-row place-content-end gap-x-8">
<Button style="text" onClick={() => closeRemoveModal()}>
Cancel
</Button>
<Button style="delete" onClick={() => deleteCloudAccount()}>
Delete account
</Button>
</div>
</div>
</Modal>

{/* Edit Drawer */}
<Modal
isOpen={editCloudAccount}
closeModal={() => setEditCloudAccount(false)}
>
<div>Editing</div>
<div>Replace this with the drawer</div>
</Modal>

{/* Toast component */}
{toast && <Toast {...toast} dismissToast={dismissToast} />}
</>
Expand Down
32 changes: 16 additions & 16 deletions docs/getting-started/introduction.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -10,48 +10,48 @@ Welcome to the Komiser Documentation, your comprehensive guide to harnessing the

## What is Komiser?

Komiser is an open-source project that empowers users to optimize and manage their cloud resources efficiently. This documentation serves as a comprehensive guide to understanding and using [Komiser](/docs/Introduction/what-is-komiser.md) effectively.
Komiser is an open-source project that empowers users to optimize and manage their cloud resources efficiently. This documentation serves as a comprehensive guide to understanding and using [Komiser](/welcome/overview) effectively.

## Community

At Komiser, we believe that the strength of any open-source project lies in its community. Whether you're a developer, user, or enthusiast, you can contribute to the project's success. Learn how to get involved and join our thriving community in the [Community](https://docs.komiser.io/community-support/contributing) section.
At Komiser, we believe that the strength of any open-source project lies in its community. Whether you're a developer, user, or enthusiast, you can contribute to the project's success. Learn how to get involved and join our thriving community in the [Contributing](/community-support/contributing) section.

## Installation

To start using Komiser, you'll need to install the Komiser Command-Line Interface (CLI) tailored for your specific operating system and architecture. Visit the [Installation](https://docs.komiser.io/getting-started/installation) page for detailed instructions on how to download and set up Komiser on your system.
To start using Komiser, you'll need to install the Komiser Command-Line Interface (CLI) tailored for your specific operating system and architecture. Visit the [Installation](/getting-started/installation) page for detailed instructions on how to download and set up Komiser on your system.

## Cloud Providers

Komiser is compatible with various cloud providers and deployment methods. Explore the installation steps for your preferred cloud provider from the list below:

[AWS](/docs/cloud-providers/aws)
[AWS](/cloud-providers/aws)

[Azure](/docs/cloud-providers/azure)
[Azure](/cloud-providers/azure)

[Civo](/docs/cloud-providers/civo)
[Civo](/cloud-providers/civo)

[DigitalOcean](/docs/cloud-providers/digital-ocean)
[DigitalOcean](/cloud-providers/digital-ocean)

[Kubernetes](/docs/cloud-providers/kubernetes)
[Kubernetes](/cloud-providers/kubernetes)

[Linode](/docs/cloud-providers/linode)
[Linode](/cloud-providers/linode)

[MongoDB Atlas](/docs/cloud-providers/mongodb-atlas)
[MongoDB Atlas](/cloud-providers/mongodb-atlas)

[OCI](/docs/cloud-providers/oci)
[OCI](/cloud-providers/oci)

[Scaleway](/docs/cloud-providers/scaleway)
[Scaleway](/cloud-providers/scaleway)

[Tencent](/docs/cloud-providers/tencent)
[Tencent](/cloud-providers/tencent)

## Contributing

Komiser is written in `Golang` and is `Elv2 licensed` - contributions are always welcome whether that means providing feedback, be it through GitHub, through the `#feedback` channel on our [Discord server](https://discord.tailwarden.com) or testing existing and new features. Find all the details on how to contribute in the [Contribute](https://docs.komiser.io/community-support/contributing) section.
Komiser is written in `Golang` and is `Elv2 licensed` - contributions are always welcome whether that means providing feedback, be it through GitHub, through the `#feedback` channel on our [Discord server](https://discord.tailwarden.com) or testing existing and new features. Find all the details on how to contribute in the [Contribute](/community-support/contributing) section.

## Guides

To help you make the most of Komiser, we provide a collection of informative guides and series. These guides offer valuable insights and actionable advice for optimizing your cloud resources with Komiser. Dive into the world of Komiser with our [How to Komiser](/docs/guides/overview) guide.
To help you make the most of Komiser, we provide a collection of informative guides and series. These guides offer valuable insights and actionable advice for optimizing your cloud resources with Komiser. Dive into the world of Komiser with our [Alerts](/guides/alerts) guide.

## FAQs

Got questions about Komiser? Find answers to commonly asked questions in the [FAQs](/docs/FAQ/faq.md) section. If you have additional questions or suggestions, feel free to reach out through the `#feedback` channel on our [Discord](https://discord.tailwarden.com) server.
Got questions about Komiser? Find answers to commonly asked questions in the [FAQs](/FAQ/faq.md) section. If you have additional questions or suggestions, feel free to reach out through the `#feedback` channel on our [Discord](https://discord.tailwarden.com) server.
27 changes: 19 additions & 8 deletions docs/guides/alerts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,12 @@ Note: The above actions are just a few examples of the endless possibilities tha
6. Save the alert.
7. Congratulations! You should now see the alert when you click on the alerts tab again.

<Info> This is the expected output of a triggered alerts on Slack </Info>

<Frame className="tailwind styles absolute top-0 left-0 w-full h-full rounded-2xl">
<img src="/images/alert-example.png" />
</Frame>

## Slack integration
To integrate Komiser with Slack you will have to generate a webhook and add it to the `config.toml` file.
Find the steps to generate the slack webhook in the official slack documentation [here](https://api.slack.com/messaging/webhooks).
Expand All @@ -45,8 +51,8 @@ webhook="https://hooks.slack.com/services/T00000000/B00000000/XXXXXXXXXXXXXXXXXX
To integrate a custom webhook, you need a URL that listens to the data posted to it when it is triggered. You don't need to edit the `config.toml` file for this integration.

### Request Details
- Komiser makes a **POST** request to the endpoint.
- The data is sent in the following format in the request body:
Komiser makes a **POST** request to the endpoint.
The data is sent in the following format in the request body:
```json
{
"komiser": "<komiser-version>", // [string]
Expand All @@ -56,8 +62,8 @@ To integrate a custom webhook, you need a URL that listens to the data posted to
"timestamp": 1685793973 // [int64] number of seconds since January 1, 1970 UTC
}
```
- You can add an optional **Secret** field. It is a secret value that is added as a request header: `authorization: <secret>`.
- It is recommended to **test the endpoint** before submitting the alert and verify the data you receive is the same as:
You can add an optional **Secret** field. It is a secret value that is added as a request header: `authorization: <secret>`.
It is recommended to **test the endpoint** before submitting the alert and verify the data you receive is the same as:
```json
{
"komiser": "komiser version that will send the webhook",
Expand All @@ -68,6 +74,11 @@ To integrate a custom webhook, you need a URL that listens to the data posted to
}
```

<Info>Webhook alert configuration screen</Info>
<Frame className="tailwind styles absolute top-0 left-0 w-full h-full rounded-2xl">
<img src="/images/untagged-resources-alert.png" />
</Frame>

## Komiser Alerts Webhook Integration Use Cases
In this guide, we'll explore five practical use cases for the Komiser alerts webhook integration. This integration allows you to trigger actions based on alerts generated by Komiser, helping you proactively manage your cloud resources. We'll also reference the Komiser Alerts documentation to demonstrate how to set up these use cases.

Expand All @@ -76,7 +87,7 @@ In this guide, we'll explore five practical use cases for the Komiser alerts web
**Scenario:** When Komiser alerts trigger, you want to notify your admin team via email and create a ticket in a task management system.

**Solution:**
1. *Komiser Alert Configuration:* Follow the steps outlined in the [Komiser Alerts](#Steps-to-add-an-Alert) to set up alerts for cost or usage thresholds.
1. *Komiser Alert Configuration:* Follow the steps outlined in the [Komiser Alerts](#steps-to-add-an-alert) to set up alerts for cost or usage thresholds.
2. *Webhook Integration:* Configure a webhook integration in Komiser to send alerts.
3. *Zapier Integration:* Use Zapier to connect the Komiser webhook to your email service and task management system. Create a Zap that triggers an email to the admin and generates a ticket on Linear.

Expand All @@ -85,7 +96,7 @@ In this guide, we'll explore five practical use cases for the Komiser alerts web
**Scenario:** When Komiser alerts are triggered, you want to automatically execute actions in AWS Lambda.

**Solution:**
1. *Komiser Alert Configuration:* Set up alerts as per the [Komiser Alerts](#Steps-to-add-an-Alert).
1. *Komiser Alert Configuration:* Set up alerts as per the [Komiser Alerts](#steps-to-add-an-alert).
2. *Webhook Integration:* Configure a webhook in Komiser to send alerts.
3. *AWS Lambda Integration:* Create an AWS Lambda function that is triggered by the Komiser webhook. Define the actions you want Lambda to take when an alert is received.

Expand All @@ -94,7 +105,7 @@ In this guide, we'll explore five practical use cases for the Komiser alerts web
**Scenario:** Komiser alerts should trigger PagerDuty incidents, and you want to create post-mortem documentation.

**Solution:**
1. *Komiser Alert Configuration:* Set up alerts as described in the [Komiser Alerts](#Steps-to-add-an-Alert).
1. *Komiser Alert Configuration:* Set up alerts as described in the [Komiser Alerts](#steps-to-add-an-alert).
2. *Webhook Integration:* Configure a webhook integration in Komiser to send alerts.
3. *PagerDuty Integration:* In PagerDuty, set up a service that listens for alerts from Komiser via the webhook. Configure PagerDuty to trigger incidents.
4. *Notion Documentation:* Use Zapier or another integration to automatically create post-mortem documentation in Notion when an incident is triggered in PagerDuty.
Expand All @@ -104,7 +115,7 @@ In this guide, we'll explore five practical use cases for the Komiser alerts web
**Scenario:** Receive Komiser alerts in a Slack channel for real-time monitoring.

**Solution:**
1. *Komiser Alert Configuration:* Follow the [Komiser Alerts](#Steps-to-add-an-Alert) to set up alerts.
1. *Komiser Alert Configuration:* Follow the [Komiser Alerts](#steps-to-add-an-alert) to set up alerts.
2. *Slack Integration:* Configure the Komiser webhook integration to send alerts to a Slack channel. Reference the [Slack Integration section](#slack-integration) for guidance.

### Use Case 5: Custom Script Execution
Expand Down
Binary file added docs/images/alert-example.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/images/untagged-resources-alert.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.

0 comments on commit 3fdd3e0

Please sign in to comment.