mirror of
https://github.com/GlueOps/autoglue.git
synced 2026-02-13 12:50:05 +01:00
Initial Labels Page & API
This commit is contained in:
@@ -118,6 +118,8 @@ func RegisterRoutes(r chi.Router) {
|
||||
l.Get("/", labels.ListLabels)
|
||||
l.Post("/", labels.CreateLabel)
|
||||
l.Get("/{id}", labels.GetLabel)
|
||||
l.Patch("/{id}", labels.UpdateLabel)
|
||||
l.Delete("/{id}", labels.DeleteLabel)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
||||
@@ -19,3 +19,8 @@ type createLabelRequest struct {
|
||||
Value string `json:"value"`
|
||||
NodePoolIDs []string `json:"node_pool_ids,omitempty"`
|
||||
}
|
||||
|
||||
type updateLabelRequest struct {
|
||||
Key *string `json:"key"`
|
||||
Value *string `json:"value"`
|
||||
}
|
||||
|
||||
@@ -79,7 +79,6 @@ func ListLabels(w http.ResponseWriter, r *http.Request) {
|
||||
// @Failure 404 {string} string "not found"
|
||||
// @Failure 500 {string} string "fetch failed"
|
||||
// @Router /api/v1/labels/{id} [get]
|
||||
|
||||
func GetLabel(w http.ResponseWriter, r *http.Request) {
|
||||
ac := middleware.GetAuthContext(r)
|
||||
if ac == nil || ac.OrganizationID == uuid.Nil {
|
||||
@@ -176,5 +175,99 @@ func CreateLabel(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
_ = response.JSON(w, http.StatusCreated, toResp(t, false))
|
||||
|
||||
}
|
||||
|
||||
// UpdateLabel godoc
|
||||
// @Summary Update label (org scoped)
|
||||
// @Description Partially update label fields.
|
||||
// @Tags labels
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param X-Org-ID header string true "Organization UUID"
|
||||
// @Param id path string true "Label ID (UUID)"
|
||||
// @Param body body updateLabelRequest true "Fields to update"
|
||||
// @Security BearerAuth
|
||||
// @Success 200 {object} labelResponse
|
||||
// @Failure 400 {string} string "invalid id / invalid json"
|
||||
// @Failure 401 {string} string "Unauthorized"
|
||||
// @Failure 403 {string} string "organization required"
|
||||
// @Failure 404 {string} string "not found"
|
||||
// @Failure 500 {string} string "update failed"
|
||||
// @Router /api/v1/labels/{id} [patch]
|
||||
func UpdateLabel(w http.ResponseWriter, r *http.Request) {
|
||||
ac := middleware.GetAuthContext(r)
|
||||
if ac == nil || ac.OrganizationID == uuid.Nil {
|
||||
http.Error(w, "organization required", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
id, err := uuid.Parse(chi.URLParam(r, "id"))
|
||||
if err != nil {
|
||||
http.Error(w, "invalid id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
var t models.Label
|
||||
if err := db.DB.Where("id = ? AND organization_id = ?", id, ac.OrganizationID).First(&t).Error; err != nil {
|
||||
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||
http.Error(w, "not found", http.StatusNotFound)
|
||||
return
|
||||
}
|
||||
http.Error(w, "fetch failed", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
var req updateLabelRequest
|
||||
if err := json.NewDecoder(r.Body).Decode(&req); err != nil {
|
||||
http.Error(w, "invalid json or missing key/value", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
if req.Key != nil {
|
||||
t.Key = strings.TrimSpace(*req.Key)
|
||||
}
|
||||
if req.Value != nil {
|
||||
t.Value = strings.TrimSpace(*req.Value)
|
||||
}
|
||||
|
||||
if err := db.DB.Save(&t).Error; err != nil {
|
||||
http.Error(w, "update failed", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
_ = response.JSON(w, http.StatusOK, toResp(t, false))
|
||||
}
|
||||
|
||||
// DeleteLabel godoc
|
||||
// @Summary Delete label (org scoped)
|
||||
// @Description Permanently deletes the label.
|
||||
// @Tags labels
|
||||
// @Accept json
|
||||
// @Produce json
|
||||
// @Param X-Org-ID header string true "Organization UUID"
|
||||
// @Param id path string true "Label ID (UUID)"
|
||||
// @Security BearerAuth
|
||||
// @Success 204 {string} string "No Content"
|
||||
// @Failure 400 {string} string "invalid id"
|
||||
// @Failure 401 {string} string "Unauthorized"
|
||||
// @Failure 403 {string} string "organization required"
|
||||
// @Failure 500 {string} string "delete failed"
|
||||
// @Router /api/v1/labels/{id} [delete]
|
||||
func DeleteLabel(w http.ResponseWriter, r *http.Request) {
|
||||
ac := middleware.GetAuthContext(r)
|
||||
if ac == nil || ac.OrganizationID == uuid.Nil {
|
||||
http.Error(w, "organization required", http.StatusForbidden)
|
||||
return
|
||||
}
|
||||
|
||||
id, err := uuid.Parse(chi.URLParam(r, "id"))
|
||||
if err != nil {
|
||||
http.Error(w, "invalid id", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
|
||||
if err := db.DB.Where("id = ? AND organization_id = ?", id, ac.OrganizationID).Delete(&models.Taint{}).Error; err != nil {
|
||||
http.Error(w, "delete failed", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
|
||||
response.NoContent(w)
|
||||
}
|
||||
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
1
internal/ui/dist/assets/index-CmZFDWt2.js
vendored
Normal file
1
internal/ui/dist/assets/index-CmZFDWt2.js
vendored
Normal file
File diff suppressed because one or more lines are too long
1
internal/ui/dist/assets/index-eleTxiqf.js
vendored
1
internal/ui/dist/assets/index-eleTxiqf.js
vendored
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -1,4 +1,4 @@
|
||||
import{r as i}from"./vendor-DBKlM1wc.js";function Zt(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}/**
|
||||
import{r as i}from"./vendor-DvippHRz.js";function Zt(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}/**
|
||||
* react-router v7.8.2
|
||||
*
|
||||
* Copyright (c) Remix Software Inc.
|
||||
File diff suppressed because one or more lines are too long
12
internal/ui/dist/index.html
vendored
12
internal/ui/dist/index.html
vendored
@@ -5,12 +5,12 @@
|
||||
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
|
||||
<title>AutoGlue</title>
|
||||
<script type="module" crossorigin src="/assets/index-eleTxiqf.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/router-CQ4G2GmP.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vendor-DBKlM1wc.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/radix-BnAuhYuH.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/icons-CNkJtX2d.js">
|
||||
<link rel="stylesheet" crossorigin href="/assets/index-D2Vr0ZQJ.css">
|
||||
<script type="module" crossorigin src="/assets/index-CmZFDWt2.js"></script>
|
||||
<link rel="modulepreload" crossorigin href="/assets/router-CANfZtzM.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/vendor-DvippHRz.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/radix-DRmH1vcw.js">
|
||||
<link rel="modulepreload" crossorigin href="/assets/icons-DQ1I1M7X.js">
|
||||
<link rel="stylesheet" crossorigin href="/assets/index--a4aJrTK.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="root"></div>
|
||||
|
||||
1
internal/ui/dist/vite.svg
vendored
1
internal/ui/dist/vite.svg
vendored
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" aria-hidden="true" role="img" class="iconify iconify--logos" width="31.88" height="32" preserveAspectRatio="xMidYMid meet" viewBox="0 0 256 257"><defs><linearGradient id="IconifyId1813088fe1fbc01fb466" x1="-.828%" x2="57.636%" y1="7.652%" y2="78.411%"><stop offset="0%" stop-color="#41D1FF"></stop><stop offset="100%" stop-color="#BD34FE"></stop></linearGradient><linearGradient id="IconifyId1813088fe1fbc01fb467" x1="43.376%" x2="50.316%" y1="2.242%" y2="89.03%"><stop offset="0%" stop-color="#FFEA83"></stop><stop offset="8.333%" stop-color="#FFDD35"></stop><stop offset="100%" stop-color="#FFA800"></stop></linearGradient></defs><path fill="url(#IconifyId1813088fe1fbc01fb466)" d="M255.153 37.938L134.897 252.976c-2.483 4.44-8.862 4.466-11.382.048L.875 37.958c-2.746-4.814 1.371-10.646 6.827-9.67l120.385 21.517a6.537 6.537 0 0 0 2.322-.004l117.867-21.483c5.438-.991 9.574 4.796 6.877 9.62Z"></path><path fill="url(#IconifyId1813088fe1fbc01fb467)" d="M185.432.063L96.44 17.501a3.268 3.268 0 0 0-2.634 3.014l-5.474 92.456a3.268 3.268 0 0 0 3.997 3.378l24.777-5.718c2.318-.535 4.413 1.507 3.936 3.838l-7.361 36.047c-.495 2.426 1.782 4.5 4.151 3.78l15.304-4.649c2.372-.72 4.652 1.36 4.15 3.788l-11.698 56.621c-.732 3.542 3.979 5.473 5.943 2.437l1.313-2.028l72.516-144.72c1.215-2.423-.88-5.186-3.54-4.672l-25.505 4.922c-2.396.462-4.435-1.77-3.759-4.114l16.646-57.705c.677-2.35-1.37-4.583-3.769-4.113Z"></path></svg>
|
||||
|
Before Width: | Height: | Size: 1.5 KiB |
Reference in New Issue
Block a user