diff --git a/internal/ctrl/api/rules-registry-http.go b/internal/ctrl/api/rules-registry-http.go index 461e48c..87da1b1 100644 --- a/internal/ctrl/api/rules-registry-http.go +++ b/internal/ctrl/api/rules-registry-http.go @@ -17,4 +17,5 @@ type RulesRegistryHTTP interface { DisableRule(c *gin.Context) SwitchRule(c *gin.Context) PostRule(c *gin.Context) + UpdateAction(c *gin.Context) } diff --git a/internal/ctrl/rules-registry.go b/internal/ctrl/rules-registry.go index 640e969..5ab843b 100644 --- a/internal/ctrl/rules-registry.go +++ b/internal/ctrl/rules-registry.go @@ -158,3 +158,28 @@ func (rr *RulesRegistry) PostRule(c *gin.Context) { c.Header("Location", fmt.Sprintf("/rules/%s", id)) c.JSON(http.StatusCreated, rule) } + +// Update action of a rule +func (rr *RulesRegistry) UpdateAction(c *gin.Context) { + id_rule := c.Param("uuid") + iduuid_rule, err := uuid.FromString(id_rule) + if err != nil { + logrus.WithError(err).Error("Bad UUID") + c.JSON(http.StatusBadRequest, jsonapi.MessageWithError{Message: "bad uuid", Error: err}) + return + } + var action n4tosrv6.Action + if err := c.BindJSON(&action); err != nil { + logrus.WithError(err).Error("could not deserialize") + c.JSON(http.StatusBadRequest, jsonapi.MessageWithError{Message: "could not deserialize", Error: err}) + return + } + c.Header("Cache-Control", "no-cache") + err = rr.db.UpdateAction(c, iduuid_rule, action) + if err != nil { + logrus.WithError(err).Error("Could not update Action for this rule in the database") + c.JSON(http.StatusInternalServerError, jsonapi.MessageWithError{Message: "could not update Action for this rule in the database", Error: err}) + return + } + c.Status(http.StatusNoContent) +} diff --git a/internal/database/database.go b/internal/database/database.go index 2180f3f..5c7c3e2 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -373,3 +373,16 @@ func (db *Database) GetDownlinkAction(ctx context.Context, ueIp netip.Addr) (n4t return n4tosrv6.Action{}, fmt.Errorf("Procedure not registered") } } + +func (db *Database) UpdateAction(ctx context.Context, uuidRule uuid.UUID, action n4tosrv6.Action) error { + srh := []string{} + for _, ip := range action.SRH { + srh = append(srh, ip.String()) + } + if stmt, ok := db.stmt["update_action"]; ok { + _, err := stmt.ExecContext(ctx, uuidRule.String(), pq.Array(srh)) + return err + } else { + return fmt.Errorf("Procedure not registered") + } +} diff --git a/internal/database/database.sql b/internal/database/database.sql index 18f04d6..29efab3 100644 --- a/internal/database/database.sql +++ b/internal/database/database.sql @@ -76,6 +76,15 @@ BEGIN DELETE FROM rule WHERE uuid = in_uuid; END;$$; +CREATE OR REPLACE PROCEDURE update_action( + IN in_uuid UUID, + IN in_srh INET ARRAY +) +LANGUAGE plpgsql AS $$ +BEGIN + UPDATE rule SET action_srh = in_srh WHERE rule.uuid = in_uuid; +END;$$; + CREATE OR REPLACE FUNCTION get_uplink_action( IN in_uplink_teid BIGINT, IN in_uplink_upf INET, IN in_gnb_ip INET, diff --git a/internal/database/database_gen.go b/internal/database/database_gen.go index 421b7f4..4bf7ebe 100644 --- a/internal/database/database_gen.go +++ b/internal/database/database_gen.go @@ -19,6 +19,7 @@ var procedures = map[string]procedureOrFunction{ "disable_rule": {is_procedure: true, num_in: 1, num_out: 0}, "switch_rule": {is_procedure: true, num_in: 2, num_out: 0}, "delete_rule": {is_procedure: true, num_in: 1, num_out: 0}, + "update_action": {is_procedure: true, num_in: 2, num_out: 0}, "get_uplink_action": {is_procedure: false, num_in: 5, num_out: 0}, "get_downlink_action": {is_procedure: false, num_in: 1, num_out: 0}, "get_rule": {is_procedure: false, num_in: 1, num_out: 0}, diff --git a/internal/tasks/http-server.go b/internal/tasks/http-server.go index e52f06b..a4776e8 100644 --- a/internal/tasks/http-server.go +++ b/internal/tasks/http-server.go @@ -68,6 +68,7 @@ func (t *HttpServerTask) RunInit(ctx context.Context) error { r.PATCH("/rules/:uuid/disable", t.rulesRegistryHTTP.DisableRule) r.PATCH("/rules/switch/:enable_uuid/:disable_uuid", t.rulesRegistryHTTP.SwitchRule) r.DELETE("/rules/:uuid", t.rulesRegistryHTTP.DeleteRule) + r.PATCH("/rules/:uuid/update-action", t.rulesRegistryHTTP.UpdateAction) t.srv = &http.Server{ Addr: t.httpAddr.String(), Handler: r,