1 package services
2
3 import (
4 "context"
5 "database/sql"
6 "errors"
7
8 "github.com/google/uuid"
9
10 sqlerr "edge-infra.dev/pkg/edge/api/apierror/sql"
11 "edge-infra.dev/pkg/edge/api/graph/mapper"
12 "edge-infra.dev/pkg/edge/api/graph/model"
13 sqlquery "edge-infra.dev/pkg/edge/api/sql"
14 "edge-infra.dev/pkg/edge/api/utils"
15 )
16
17 type NamespaceService interface {
18 CreateNamespaceEntry(ctx context.Context, createNamespace *model.NamespaceCreateInput) (*model.Namespace, error)
19 DeleteNamespaceEntry(ctx context.Context, bannerEdgeID string, name string) error
20 GetBannerNamespaces(ctx context.Context, bannerEdgeID string, name *string) ([]*model.Namespace, error)
21 GetClusterNamespaces(ctx context.Context, clusterEdgeID string, name *string) ([]*model.Namespace, error)
22 CreateDSDSKubeNamespaceCR(namespace *model.Namespace) (string, error)
23 CreateClusterNamespaceEntry(ctx context.Context, transaction *sql.Tx, namespaceEdgeID string, clusterEdgeID string) error
24 GetNumClustersUsingNamespace(ctx context.Context, namespaceEdgeID string) (int, error)
25 GetClusterNamespaceEdgeID(ctx context.Context, transaction *sql.Tx, namespaceEdgeID string, clusterEdgeID string) (string, error)
26 GetNamespaceName(ctx context.Context, namespaceEdgeID string) (string, error)
27 }
28
29 type namespaceService struct {
30 SQLDB *sql.DB
31 }
32
33 func (n *namespaceService) CreateNamespaceEntry(ctx context.Context, createNamespace *model.NamespaceCreateInput) (namespace *model.Namespace, err error) {
34 transaction, err := n.SQLDB.BeginTx(ctx, nil)
35 if err != nil {
36 return nil, err
37 }
38
39 defer func() {
40 if err != nil {
41 err = errors.Join(err, transaction.Rollback())
42 }
43 }()
44
45 modelNamespace := utils.CreateNamespaceModel(uuid.NewString(), createNamespace.BannerEdgeID, createNamespace.Name, createNamespace.Workload)
46 namespace = &modelNamespace
47
48 if err = utils.ValidateNamespace(namespace); err != nil {
49 return nil, err
50 }
51
52 args := []interface{}{
53 namespace.NamespaceEdgeID,
54 namespace.BannerEdgeID,
55 namespace.Name,
56 namespace.Workload,
57 }
58
59 if _, err = transaction.ExecContext(ctx, sqlquery.NamespaceCreateQuery, args...); err != nil {
60 return nil, err
61 }
62
63 if err = transaction.Commit(); err != nil {
64 return nil, err
65 }
66
67 return namespace, nil
68 }
69
70 func (n *namespaceService) DeleteNamespaceEntry(ctx context.Context, bannerEdgeID string, name string) error {
71 args := []interface{}{
72 bannerEdgeID,
73 name,
74 }
75 _, err := n.SQLDB.ExecContext(ctx, sqlquery.NamespaceDeleteQuery, args...)
76 return err
77 }
78
79 func (n *namespaceService) GetBannerNamespaces(ctx context.Context, bannerEdgeID string, name *string) ([]*model.Namespace, error) {
80 if name == nil {
81 return n.getAllBannerNamespaces(ctx, bannerEdgeID)
82 }
83 return n.getBannerNamespaces(ctx, bannerEdgeID, *name)
84 }
85
86 func (n *namespaceService) GetClusterNamespaces(ctx context.Context, clusterEdgeID string, name *string) ([]*model.Namespace, error) {
87 if name == nil {
88 return n.getClusterNamespacesByClusterEdgeID(ctx, clusterEdgeID)
89 }
90 return n.getClusterNamespaces(ctx, clusterEdgeID, *name)
91 }
92
93 func (n *namespaceService) CreateDSDSKubeNamespaceCR(namespace *model.Namespace) (string, error) {
94 kubeNamespace, err := mapper.NamespaceToKubeNamespace(namespace)
95 if err != nil {
96 return "", err
97 }
98 encodedNamespace, err := utils.ConvertStructToBase64(kubeNamespace)
99 if err != nil {
100 return "", err
101 }
102 return encodedNamespace, nil
103 }
104
105 func (n *namespaceService) CreateClusterNamespaceEntry(ctx context.Context, transaction *sql.Tx, namespaceEdgeID string, clusterEdgeID string) error {
106 args := []interface{}{
107 namespaceEdgeID,
108 clusterEdgeID,
109 }
110 _, err := transaction.ExecContext(ctx, sqlquery.ClusterNamespaceCreateQuery, args...)
111 return err
112 }
113
114 func (n *namespaceService) GetNumClustersUsingNamespace(ctx context.Context, namespaceEdgeID string) (int, error) {
115 row := n.SQLDB.QueryRowContext(ctx, sqlquery.GetNumClustersUsingNamespaceQuery, namespaceEdgeID)
116 var count int
117 if err := row.Scan(&count); err != nil {
118 return 0, err
119 }
120 return count, nil
121 }
122
123 func (n *namespaceService) GetClusterNamespaceEdgeID(ctx context.Context, transaction *sql.Tx, namespaceEdgeID string, clusterEdgeID string) (string, error) {
124 args := []interface{}{
125 namespaceEdgeID,
126 clusterEdgeID,
127 }
128 row := transaction.QueryRowContext(ctx, sqlquery.GetClusterNamespaceEdgeIDQuery, args...)
129
130 var clusterNamespaceEdgeID string
131 if err := row.Scan(&clusterNamespaceEdgeID); err != nil {
132 return "", err
133 }
134
135 return clusterNamespaceEdgeID, nil
136 }
137
138 func (n *namespaceService) GetNamespaceName(ctx context.Context, namespaceEdgeID string) (string, error) {
139 var namespace string
140 row := n.SQLDB.QueryRowContext(ctx, sqlquery.GetNamespaceNameByNamespaceEdgeIDQuery, namespaceEdgeID)
141 if err := row.Scan(&namespace); err != nil {
142 return "", err
143 }
144 return namespace, nil
145 }
146
147 func (n *namespaceService) getAllBannerNamespaces(ctx context.Context, bannerEdgeID string) ([]*model.Namespace, error) {
148 rows, err := n.SQLDB.QueryContext(ctx, sqlquery.GetAllBannerNamespacesQuery, bannerEdgeID)
149 if err != nil {
150 return nil, err
151 }
152 namespaces, err := n.scanNamespaceRows(rows)
153 if err != nil {
154 return nil, err
155 }
156 return namespaces, nil
157 }
158
159 func (n *namespaceService) getBannerNamespaces(ctx context.Context, bannerEdgeID string, name string) ([]*model.Namespace, error) {
160 args := []interface{}{
161 bannerEdgeID,
162 name,
163 }
164
165 rows, err := n.SQLDB.QueryContext(ctx, sqlquery.GetBannerNamespacesQuery, args...)
166 if err != nil {
167 return nil, err
168 }
169 namespaces, err := n.scanNamespaceRows(rows)
170 if err != nil {
171 return nil, err
172 }
173 return namespaces, nil
174 }
175
176 func (n *namespaceService) getClusterNamespacesByClusterEdgeID(ctx context.Context, clusterEdgeID string) ([]*model.Namespace, error) {
177 rows, err := n.SQLDB.QueryContext(ctx, sqlquery.GetAllClusterNamespacesQuery, clusterEdgeID)
178 if err != nil {
179 return nil, err
180 }
181 namespaces, err := n.scanNamespaceRows(rows)
182 if err != nil {
183 return nil, err
184 }
185 return namespaces, nil
186 }
187
188 func (n *namespaceService) getClusterNamespaces(ctx context.Context, clusterEdgeID string, name string) ([]*model.Namespace, error) {
189 args := []interface{}{
190 clusterEdgeID,
191 name,
192 }
193
194 rows, err := n.SQLDB.QueryContext(ctx, sqlquery.GetClusterNamespacesQuery, args...)
195 if err != nil {
196 return nil, err
197 }
198 namespaces, err := n.scanNamespaceRows(rows)
199 if err != nil {
200 return nil, err
201 }
202 return namespaces, nil
203 }
204
205 func (n *namespaceService) scanNamespaceRows(rows *sql.Rows) ([]*model.Namespace, error) {
206 namespaces := []*model.Namespace{}
207 for rows.Next() {
208 namespace := &model.Namespace{}
209 err := rows.Scan(&namespace.NamespaceEdgeID, &namespace.BannerEdgeID, &namespace.Name, &namespace.Workload)
210 if err != nil {
211 return nil, err
212 }
213 namespaces = append(namespaces, namespace)
214 }
215 if err := rows.Err(); err != nil {
216 return nil, sqlerr.Wrap(err)
217 }
218 return namespaces, nil
219 }
220
221 func NewNamespaceService(sqlDB *sql.DB) *namespaceService {
222 return &namespaceService{
223 SQLDB: sqlDB,
224 }
225 }
226
View as plain text