9cf5ee801db04c783a4b997c0503be9435a405f5
[ric-plt/sdlgo.git] / internal / cli / namespaces.go
1 /*
2    Copyright (c) 2021 AT&T Intellectual Property.
3    Copyright (c) 2018-2021 Nokia.
4
5    Licensed under the Apache License, Version 2.0 (the "License");
6    you may not use this file except in compliance with the License.
7    You may obtain a copy of the License at
8
9        http://www.apache.org/licenses/LICENSE-2.0
10
11    Unless required by applicable law or agreed to in writing, software
12    distributed under the License is distributed on an "AS IS" BASIS,
13    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14    See the License for the specific language governing permissions and
15    limitations under the License.
16 */
17
18 /*
19  * This source code is part of the near-RT RIC (RAN Intelligent Controller)
20  * platform project (RICP).
21  */
22
23 package cli
24
25 import (
26         "fmt"
27         "github.com/spf13/cobra"
28         "os"
29         "sort"
30         "strings"
31 )
32
33 func init() {
34         getCmd.AddCommand(newNamespacesCmd(newDatabase))
35 }
36
37 func newNamespacesCmd(dbCreateCb DbCreateCb) *cobra.Command {
38         cmd := &cobra.Command{
39                 Use:   "namespaces",
40                 Short: "List all the namespaces in database",
41                 Long:  "List all the namespaces in database",
42                 Args:  cobra.ExactArgs(0),
43                 RunE: func(cmd *cobra.Command, args []string) error {
44                         showPerDb, _ := cmd.Flags().GetBool("group")
45                         nsMap, err := runNamespaces(dbCreateCb)
46                         if err != nil {
47                                 cmd.PrintErrf("%s\n", buf.String())
48                                 return err
49                         }
50                         if showPerDb {
51                                 printNamespacesPerDb(cmd, nsMap)
52                         } else {
53                                 printNamespaces(cmd, nsMap)
54                         }
55                         return err
56                 },
57         }
58         cmd.SetOut(os.Stdout)
59         cmd.Flags().BoolP("group", "g", false, "Show namespaces per SDL DB cluster group")
60         return cmd
61 }
62
63 func runNamespaces(dbCreateCb DbCreateCb) (map[string][]string, error) {
64         nsMap := make(map[string][]string)
65         for _, dbInst := range dbCreateCb().Instances {
66                 keys, err := dbInst.Keys("*")
67                 if err != nil {
68                         return nil, err
69                 }
70                 id, err := getServiceAddress(dbInst)
71                 if err != nil {
72                         return nil, err
73                 }
74                 for _, key := range keys {
75                         namespace, err := parseKeyNamespace(key)
76                         if err != nil {
77                                 return nil, err
78                         }
79                         if isUniqueNamespace(nsMap[id], namespace) {
80                                 nsMap[id] = append(nsMap[id], namespace)
81                         }
82                 }
83         }
84         return nsMap, nil
85 }
86
87 func getServiceAddress(db iDatabase) (string, error) {
88         state, err := db.State()
89         if err != nil {
90                 return "", err
91         }
92         return state.MasterDbState.GetAddress(), nil
93 }
94
95 func parseKeyNamespace(key string) (string, error) {
96         sIndex := strings.Index(key, "{")
97         if sIndex == -1 {
98                 return "", fmt.Errorf("Namespace parsing error, no '{' in key string '%s'", key)
99         }
100         str := key[sIndex+len("{"):]
101         eIndex := strings.Index(str, "}")
102         if eIndex == -1 {
103                 return "", fmt.Errorf("Namespace parsing error, no '}' in key string '%s'", key)
104         }
105         return str[:eIndex], nil
106 }
107
108 func isUniqueNamespace(namespaces []string, newNs string) bool {
109         for _, n := range namespaces {
110                 if n == newNs {
111                         return false
112                 }
113         }
114         return true
115 }
116
117 func printNamespaces(cmd *cobra.Command, nsMap map[string][]string) {
118         var namespaces []string
119         for _, nsList := range nsMap {
120                 namespaces = append(namespaces, nsList...)
121         }
122
123         sort.Strings(namespaces)
124         for _, ns := range namespaces {
125                 cmd.Println(ns)
126         }
127 }
128
129 func printNamespacesPerDb(cmd *cobra.Command, nsMap map[string][]string) {
130         for addr, nsList := range nsMap {
131                 sort.Strings(nsList)
132                 for _, ns := range nsList {
133                         if addr == "" {
134                                 cmd.Printf("%s\n", ns)
135                         } else {
136                                 cmd.Printf("%s: %s\n", addr, ns)
137                         }
138                 }
139         }
140 }