Skip to content

Commit

Permalink
Merge pull request #979 from tailwarden/feature/tech-1647
Browse files Browse the repository at this point in the history
Expose cloud accounts management endpoints
  • Loading branch information
mlabouardy authored Sep 20, 2023
2 parents 530b6ff + 3fdd3e0 commit f945f4e
Show file tree
Hide file tree
Showing 10 changed files with 271 additions and 19 deletions.
2 changes: 1 addition & 1 deletion dashboard/components/onboarding-wizard/DatabasePurplin.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ interface DatabasePurplinProps {
function DatabasePurplin({ database }: DatabasePurplinProps) {
return (
<div className="relative">
<div className="-ml-12 -mb-14 flex w-24 items-center justify-center rounded-3xl bg-komiser-200 p-4">
<div className="-mb-14 -ml-12 flex w-24 items-center justify-center rounded-3xl bg-komiser-200 p-4">
<Image
src={`/assets/img/database/${
database === 'postgres' ? 'postgresql' : 'sqlite'
Expand Down
2 changes: 1 addition & 1 deletion dashboard/components/onboarding-wizard/PurplinCloud.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ function PurplinCloud({ provider }: { provider: Provider }) {
width={500}
height={120}
/>
<div className="absolute top-[53%] left-[48%] -translate-x-1/2 -translate-y-1/2 transform rounded-full">
<div className="absolute left-[48%] top-[53%] -translate-x-1/2 -translate-y-1/2 transform rounded-full">
<Image
src={ProviderCls.providerImg(provider) as string}
alt={`${provider} Logo`}
Expand Down
10 changes: 5 additions & 5 deletions dashboard/components/onboarding-wizard/SelectInput.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ function SelectInput({
return (
<div className="relative">
<div
className="pointer-events-none absolute right-4
bottom-[1.15rem] text-komiser-600 transition-all"
className="pointer-events-none absolute bottom-[1.15rem]
right-4 text-komiser-600 transition-all"
>
{icon}
</div>
Expand All @@ -49,7 +49,7 @@ function SelectInput({
{ 'outline-2 outline-primary': isOpen }
)}
>
<div className="pointer-events-none flex w-full appearance-none items-center gap-2 rounded bg-white pt-[0.75rem] pb-[0.75rem] pl-4 pr-16 text-sm text-black-900">
<div className="pointer-events-none flex w-full appearance-none items-center gap-2 rounded bg-white pb-[0.75rem] pl-4 pr-16 pt-[0.75rem] text-sm text-black-900">
{displayValues[index].icon && displayValues[index].icon}
{displayValues[index].label}
</div>
Expand All @@ -61,15 +61,15 @@ function SelectInput({
onClick={toggle}
className="fixed inset-0 z-20 hidden animate-fade-in bg-transparent opacity-0 sm:block"
></div>
<div className="absolute top-[96px] z-[21] max-h-52 w-full overflow-hidden overflow-y-auto rounded-lg border border-black-130 bg-white py-2 px-3 shadow-lg">
<div className="absolute top-[96px] z-[21] max-h-52 w-full overflow-hidden overflow-y-auto rounded-lg border border-black-130 bg-white px-3 py-2 shadow-lg">
<div className="flex w-full flex-col gap-1">
{values.map((item, idx) => {
const isActive = value === item;
return (
<button
key={idx}
className={classNames(
'flex items-center rounded py-2 px-3 text-left text-sm text-black-400 hover:bg-black-150',
'flex items-center rounded px-3 py-2 text-left text-sm text-black-400 hover:bg-black-150',
{ 'bg-komiser-150': isActive }
)}
onClick={() => handleClick(item)}
Expand Down
2 changes: 1 addition & 1 deletion dashboard/components/select/Select.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ function Select({
onClick={toggle}
className="fixed inset-0 z-20 hidden animate-fade-in bg-transparent opacity-0 sm:block"
></div>
<div className="absolute top-[66px] z-[21] max-h-52 w-full overflow-hidden overflow-y-auto rounded-lg border border-black-130 bg-white py-2 px-3 shadow-lg">
<div className="absolute top-[66px] z-[21] max-h-52 w-full overflow-hidden overflow-y-auto rounded-lg border border-black-130 bg-white px-3 py-2 shadow-lg">
<div className="flex w-full flex-col gap-1">
{values.map((item, idx) => {
const isActive = value === item;
Expand Down
2 changes: 1 addition & 1 deletion dashboard/pages/onboarding/choose-cloud.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -92,7 +92,7 @@ export default function ChooseCloud() {
width={500}
height={120}
/>
<div className="absolute top-[53%] left-[48%] -translate-x-1/2 -translate-y-1/2 transform rounded-full">
<div className="absolute left-[48%] top-[53%] -translate-x-1/2 -translate-y-1/2 transform rounded-full">
<Image
src={ProviderCls.providerImg(provider) as string}
alt={`${provider} Logo`}
Expand Down
105 changes: 105 additions & 0 deletions handlers/accounts_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,105 @@
package handlers

import (
"context"
"encoding/json"
"net/http"

"github.com/gin-gonic/gin"
"github.com/sirupsen/logrus"
"github.com/tailwarden/komiser/models"
)

func (handler *ApiHandler) IsOnboardedHandler(c *gin.Context) {
output := struct {
Onboarded bool `json:"onboarded"`
}{
Onboarded: false,
}

accounts := make([]models.Account, 0)
err := handler.db.NewRaw("SELECT * FROM accounts").Scan(handler.ctx, &accounts)
if err != nil {
logrus.WithError(err).Error("scan failed")
c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"})
return
}

if len(accounts) > 0 {
output.Onboarded = true
}

c.JSON(http.StatusOK, output)
}

func (handler *ApiHandler) ListCloudAccountsHandler(c *gin.Context) {
accounts := make([]models.Account, 0)
err := handler.db.NewRaw("SELECT * FROM accounts").Scan(handler.ctx, &accounts)
if err != nil {
logrus.WithError(err).Error("scan failed")
c.JSON(http.StatusInternalServerError, gin.H{"error": "scan failed"})
return
}

c.JSON(http.StatusOK, accounts)
}

func (handler *ApiHandler) NewCloudAccountHandler(c *gin.Context) {
var account models.Account

err := json.NewDecoder(c.Request.Body).Decode(&account)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}

result, err := handler.db.NewInsert().Model(&account).Exec(context.Background())
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}

accountId, _ := result.LastInsertId()
account.Id = accountId

if handler.telemetry {
handler.analytics.TrackEvent("creating_alert", map[string]interface{}{
"type": len(account.Credentials),
"provider": account.Provider,
})
}

c.JSON(http.StatusCreated, account)
}

func (handler *ApiHandler) DeleteCloudAccountHandler(c *gin.Context) {
accountId := c.Param("id")

account := new(models.Account)
_, err := handler.db.NewDelete().Model(account).Where("id = ?", accountId).Exec(handler.ctx)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}

c.JSON(http.StatusOK, gin.H{"message": "account has been deleted"})
}

func (handler *ApiHandler) UpdateCloudAccountHandler(c *gin.Context) {
accountId := c.Param("id")

var account models.Account
err := json.NewDecoder(c.Request.Body).Decode(&account)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}

_, err = handler.db.NewUpdate().Model(&account).Column("name", "provider", "credentials").Where("id = ?", accountId).Exec(handler.ctx)
if err != nil {
c.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
}

c.JSON(http.StatusOK, account)
}
6 changes: 6 additions & 0 deletions internal/api/v1/endpoints.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ func Endpoints(ctx context.Context, telemetry bool, analytics utils.Analytics, d
router.POST("/alerts/test", api.TestEndpointHandler)

router.GET("/telemetry", api.TelemetryHandler)
router.GET("/is_onboarded", api.IsOnboardedHandler)

router.GET("/cloud_accounts", api.ListCloudAccountsHandler)
router.POST("/cloud_accounts", api.NewCloudAccountHandler)
router.DELETE("/cloud_accounts/:id", api.DeleteCloudAccountHandler)
router.PUT("/cloud_accounts/:id", api.UpdateCloudAccountHandler)

router.NoRoute(gin.WrapH(http.FileServer(assetFS())))

Expand Down
Loading

0 comments on commit f945f4e

Please sign in to comment.