From 2c986a364be66e0d1e72d1ba1adc733a5561ba2e Mon Sep 17 00:00:00 2001 From: Louis Royer Date: Tue, 16 Jul 2024 18:13:16 +0200 Subject: [PATCH] Add get rules --- internal/ctrl/rules-registry.go | 20 ++++--- internal/database/database.go | 95 +++++++++++++++++++++++++++++++-- internal/database/database.sql | 20 ++++++- 3 files changed, 123 insertions(+), 12 deletions(-) diff --git a/internal/ctrl/rules-registry.go b/internal/ctrl/rules-registry.go index 77ec231..c40007c 100644 --- a/internal/ctrl/rules-registry.go +++ b/internal/ctrl/rules-registry.go @@ -34,15 +34,23 @@ func (rr *RulesRegistry) GetRule(c *gin.Context) { return } c.Header("Cache-Control", "no-cache") - _ = iduuid - c.Status(http.StatusNotImplemented) + rule, err := rr.db.GetRule(iduuid) + if err != nil { + log.Printf("Could not get rule from database: %s\n", err) + c.JSON(http.StatusInternalServerError, gin.H{"message": "could not get rule from database"}) + return + } + c.JSON(http.StatusOK, rule) } func (rr *RulesRegistry) GetRules(c *gin.Context) { - //FIXME - - c.Status(http.StatusNotImplemented) - //c.JSON(http.StatusOK, rr.rules) + rules, err := rr.db.GetRules() + if err != nil { + log.Printf("Could not get all rules from database: %s\n", err) + c.JSON(http.StatusInternalServerError, gin.H{"message": "could not get all rules from database"}) + return + } + c.JSON(http.StatusOK, rules) } func (rr *RulesRegistry) DeleteRule(c *gin.Context) { diff --git a/internal/database/database.go b/internal/database/database.go index 5e3d2a5..8dc4f0a 100644 --- a/internal/database/database.go +++ b/internal/database/database.go @@ -8,7 +8,6 @@ import ( "database/sql" _ "embed" "fmt" - "net" "net/netip" "strings" @@ -109,8 +108,8 @@ func (db *Database) GetRule(uuid uuid.UUID) (jsonapi.Rule, error) { var type_uplink bool var action_next_hop string var action_srh []string - var match_ue_ip_prefix net.Addr - var match_gnb_ip_prefix net.Addr + var match_ue_ip_prefix string + var match_gnb_ip_prefix string if stmt, ok := db.stmt["get_rule"]; ok { err := stmt.QueryRow(uuid.String()).Scan(&enabled, &type_uplink, &action_next_hop, pq.Array(&action_srh), &match_ue_ip_prefix, &match_gnb_ip_prefix) if err != nil { @@ -126,19 +125,105 @@ func (db *Database) GetRule(uuid uuid.UUID) (jsonapi.Rule, error) { Enabled: enabled, Type: t, } - //FIXME - if match_ue_ip_prefix != nil { + rule.Match = jsonapi.Match{} + if match_ue_ip_prefix != "" { + p, err := netip.ParsePrefix(match_ue_ip_prefix) + if err == nil { + rule.Match.UEIpPrefix = p + } + } + if match_gnb_ip_prefix != "" { + p, err := netip.ParsePrefix(match_gnb_ip_prefix) + if err == nil { + rule.Match.GNBIpPrefix = p + } } + srh, err := jsonapi.NewSRH(action_srh) + if err != nil { + return jsonapi.Rule{}, err + } + nh, err := jsonapi.NewNextHop(action_next_hop) if err != nil { return jsonapi.Rule{}, err } + + rule.Action = jsonapi.Action{ + NextHop: *nh, + SRH: *srh, + } + return rule, err } else { return jsonapi.Rule{}, fmt.Errorf("Procedure not registered") } } +func (db *Database) GetRules() (jsonapi.RuleMap, error) { + var uuid uuid.UUID + var enabled bool + var type_uplink bool + var action_next_hop string + var action_srh []string + var match_ue_ip_prefix string + var match_gnb_ip_prefix string + m := jsonapi.RuleMap{} + if stmt, ok := db.stmt["get_all_rules"]; ok { + rows, err := stmt.Query() + if err != nil { + return m, nil + } + for rows.Next() { + err := rows.Scan(&uuid, &enabled, &type_uplink, &action_next_hop, pq.Array(&action_srh), &match_ue_ip_prefix, &match_gnb_ip_prefix) + if err != nil { + return m, err + } + var t string + if type_uplink { + t = "uplink" + } else { + t = "downlink" + } + rule := jsonapi.Rule{ + Enabled: enabled, + Type: t, + } + rule.Match = jsonapi.Match{} + if match_ue_ip_prefix != "" { + p, err := netip.ParsePrefix(match_ue_ip_prefix) + if err == nil { + rule.Match.UEIpPrefix = p + } + } + if match_gnb_ip_prefix != "" { + p, err := netip.ParsePrefix(match_gnb_ip_prefix) + if err == nil { + rule.Match.GNBIpPrefix = p + } + } + + srh, err := jsonapi.NewSRH(action_srh) + if err != nil { + return jsonapi.RuleMap{}, err + } + nh, err := jsonapi.NewNextHop(action_next_hop) + if err != nil { + return jsonapi.RuleMap{}, err + } + + rule.Action = jsonapi.Action{ + NextHop: *nh, + SRH: *srh, + } + m[uuid] = rule + } + return m, nil + + } else { + return jsonapi.RuleMap{}, fmt.Errorf("Procedure not registered") + } +} + func (db *Database) EnableRule(uuid uuid.UUID) error { if stmt, ok := db.stmt["enable_rule"]; ok { _, err := stmt.Exec(uuid.String()) diff --git a/internal/database/database.sql b/internal/database/database.sql index 9fadf32..b8fc393 100644 --- a/internal/database/database.sql +++ b/internal/database/database.sql @@ -125,5 +125,23 @@ BEGIN action_srh, match_ue_ip_prefix, match_gnb_ip_prefix FROM rule WHERE (rule.uuid = uuid) - INTO (action_next_hop, action_srh); + INTO (type_uplink, enabled, action_next_hop, action_srh, + match_ue_ip_prefix, match_gnb_ip_prefix); +END;$$; +CREATE OR REPLACE PROCEDURE get_all_rules( + OUT uuid UUID, + OUT type_uplink BOOL, + OUT enabled BOOL, + OUT action_next_hop INET, + OUT action_srh INET ARRAY, + OUT match_ue_ip_prefix CIDR, + OUT match_gnb_ip_prefix CIDR +) +LANGUAGE plpgsql AS $$ +BEGIN + SELECT uuid, type_uplink, enabled, action_next_hop, + action_srh, match_ue_ip_prefix, match_gnb_ip_prefix + FROM rule + INTO (uuid, type_uplink, enabled, action_next_hop, action_srh, + match_ue_ip_prefix, match_gnb_ip_prefix); END;$$;