aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--application_router.go21
-rw-r--r--frontend/src/components/panels/ServicesPane.js15
-rw-r--r--services_controller.go15
-rw-r--r--storage.go80
4 files changed, 126 insertions, 5 deletions
diff --git a/application_router.go b/application_router.go
index 6d65960..1288eb1 100644
--- a/application_router.go
+++ b/application_router.go
@@ -20,14 +20,15 @@ package main
import (
"errors"
"fmt"
- "github.com/gin-gonic/contrib/static"
- "github.com/gin-gonic/gin"
- log "github.com/sirupsen/logrus"
"net/http"
"os"
"path/filepath"
"strings"
"time"
+
+ "github.com/gin-gonic/contrib/static"
+ "github.com/gin-gonic/gin"
+ log "github.com/sirupsen/logrus"
)
func CreateApplicationRouter(applicationContext *ApplicationContext,
@@ -389,6 +390,20 @@ func CreateApplicationRouter(applicationContext *ApplicationContext,
}
})
+ api.DELETE("/services", func(c *gin.Context) {
+ var service Service
+ if err := c.ShouldBindJSON(&service); err != nil {
+ badRequest(c, err)
+ return
+ }
+ if err := applicationContext.ServicesController.DeleteService(c, service); err == nil {
+ success(c, service)
+ notificationController.Notify("services.edit", service)
+ } else {
+ unprocessableEntity(c, err)
+ }
+ })
+
api.GET("/statistics", func(c *gin.Context) {
var filter StatisticsFilter
if err := c.ShouldBindQuery(&filter); err != nil {
diff --git a/frontend/src/components/panels/ServicesPane.js b/frontend/src/components/panels/ServicesPane.js
index 5986804..9f89485 100644
--- a/frontend/src/components/panels/ServicesPane.js
+++ b/frontend/src/components/panels/ServicesPane.js
@@ -85,6 +85,19 @@ class ServicesPane extends Component {
}
};
+ deleteService = () => {
+ const service = this.state.currentService;
+ if (this.validateService(service)) {
+ backend.delete("/api/services", service).then((res) => {
+ this.reset();
+ this.setState({serviceStatusCode: res.status});
+ this.loadServices();
+ }).catch((res) => {
+ this.setState({serviceStatusCode: res.status, serviceResponse: JSON.stringify(res.json)});
+ });
+ }
+ };
+
validateService = (service) => {
let valid = true;
if (!validation.isValidPort(service.port, true)) {
@@ -207,6 +220,8 @@ class ServicesPane extends Component {
<ButtonField variant={isUpdate ? "blue" : "green"}
name={isUpdate ? "update_service" : "add_service"}
bordered onClick={this.updateService}/>
+ {isUpdate ? <ButtonField variant="blue" name= "delete_service"
+ bordered onClick={this.deleteService}/> : ""}
</div>
</div>
</div>
diff --git a/services_controller.go b/services_controller.go
index e5fa200..aea4693 100644
--- a/services_controller.go
+++ b/services_controller.go
@@ -20,8 +20,9 @@ package main
import (
"context"
"errors"
- log "github.com/sirupsen/logrus"
"sync"
+
+ log "github.com/sirupsen/logrus"
)
type Service struct {
@@ -79,3 +80,15 @@ func (sc *ServicesController) GetServices() map[uint16]Service {
sc.mutex.Unlock()
return services
}
+
+func (sc *ServicesController) DeleteService(c context.Context, service Service) error {
+ sc.mutex.Lock()
+ defer sc.mutex.Unlock()
+
+ if err := sc.storage.Delete(Services).Context(c).Filter(OrderedDocument{{"_id", service.Port}}).One(); err != nil {
+ return errors.New(err.Error())
+ } else {
+ delete(sc.services, service.Port)
+ return nil
+ }
+}
diff --git a/storage.go b/storage.go
index 8505bfe..29694a3 100644
--- a/storage.go
+++ b/storage.go
@@ -21,11 +21,12 @@ import (
"context"
"errors"
"fmt"
+ "time"
+
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/bson/primitive"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
- "time"
)
// Collections names
@@ -46,6 +47,7 @@ type Storage interface {
Insert(collectionName string) InsertOperation
Update(collectionName string) UpdateOperation
Find(collectionName string) FindOperation
+ Delete(collectionName string) DeleteOperation
}
type MongoStorage struct {
@@ -399,3 +401,79 @@ func (storage *MongoStorage) Find(collectionName string) FindOperation {
}
return op
}
+
+// Delete one/many
+
+type DeleteOperation interface {
+ Context(ctx context.Context) DeleteOperation
+ Filter(filter OrderedDocument) DeleteOperation
+ One() error
+ Many() error
+}
+
+func (storage *MongoStorage) Delete(collectionName string) DeleteOperation {
+ collection, ok := storage.collections[collectionName]
+ op := MongoDeleteOperation{
+ collection: collection,
+ opts: options.Delete(),
+ }
+ if !ok {
+ op.err = errors.New("invalid collection: " + collectionName)
+ }
+ return op
+}
+
+type MongoDeleteOperation struct {
+ collection *mongo.Collection
+ ctx context.Context
+ opts *options.DeleteOptions
+ filter OrderedDocument
+ err error
+}
+
+func (do MongoDeleteOperation) Context(ctx context.Context) DeleteOperation {
+ do.ctx = ctx
+ return do
+}
+
+func (do MongoDeleteOperation) Filter(filter OrderedDocument) DeleteOperation {
+ for _, elem := range filter {
+ do.filter = append(do.filter, primitive.E{Key: elem.Key, Value: elem.Value})
+ }
+
+ return do
+}
+
+func (do MongoDeleteOperation) One() error {
+ if do.err != nil {
+ return do.err
+ }
+
+ result, err := do.collection.DeleteOne(do.ctx, do.filter, do.opts)
+ if err != nil {
+ return err
+ }
+
+ if result.DeletedCount == 0 {
+ return errors.New("nothing to delete")
+ }
+
+ return nil
+}
+
+func (do MongoDeleteOperation) Many() error {
+ if do.err != nil {
+ return do.err
+ }
+
+ result, err := do.collection.DeleteMany(do.ctx, do.filter, do.opts)
+ if err != nil {
+ return err
+ }
+
+ if result.DeletedCount == 0 {
+ return errors.New("nothing to delete")
+ }
+
+ return nil
+}