Add suport for query api on root level
[multicloud/k8s.git] / src / k8splugin / internal / app / query.go
1 /*
2  * Copyright 2018 Intel Corporation, Inc
3  * Copyright © 2021 Samsung Electronics
4  * Copyright © 2021 Orange
5  *
6  * Licensed under the Apache License, Version 2.0 (the "License");
7  * you may not use this file except in compliance with the License.
8  * You may obtain a copy of the License at
9  *
10  *     http://www.apache.org/licenses/LICENSE-2.0
11  *
12  * Unless required by applicable law or agreed to in writing, software
13  * distributed under the License is distributed on an "AS IS" BASIS,
14  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15  * See the License for the specific language governing permissions and
16  * limitations under the License.
17  */
18
19 package app
20
21 import (
22         "github.com/onap/multicloud-k8s/src/k8splugin/internal/helm"
23         "k8s.io/apimachinery/pkg/runtime/schema"
24
25         pkgerrors "github.com/pkg/errors"
26 )
27
28 // QueryStatus is what is returned when status is queried for an instance
29 type QueryStatus struct {
30         ResourceCount   int32            `json:"resourceCount"`
31         ResourcesStatus []ResourceStatus `json:"resourcesStatus"`
32 }
33
34 // QueryManager is an interface exposes the instantiation functionality
35 type QueryManager interface {
36         Query(namespace, cloudRegion, apiVersion, kind, name, labels, id string) (QueryStatus, error)
37 }
38
39 // QueryClient implements the InstanceManager interface
40 // It will also be used to maintain some localized state
41 type QueryClient struct {
42         storeName string
43         tagInst   string
44 }
45
46 // NewQueryClient returns an instance of the QueryClient
47 // which implements the InstanceManager
48 func NewQueryClient() *QueryClient {
49         return &QueryClient{
50                 storeName: "rbdef",
51                 tagInst:   "instance",
52         }
53 }
54
55 // Query returns state of instance's filtered resources
56 func (v *QueryClient) Query(namespace, cloudRegion, apiVersion, kind, name, labels, id string) (QueryStatus, error) {
57
58         //Read the status from the DD
59
60         k8sClient := KubernetesClient{}
61         err := k8sClient.Init(cloudRegion, id)
62         if err != nil {
63                 return QueryStatus{}, pkgerrors.Wrap(err, "Getting CloudRegion Information")
64         }
65
66         var resourcesStatus []ResourceStatus
67         if labels != "" {
68                 resList, err := k8sClient.queryResources(apiVersion, kind, labels, namespace)
69                 if err != nil {
70                         return QueryStatus{}, pkgerrors.Wrap(err, "Querying Resources")
71                 }
72                 // If user specifies both label and name, we want to pick up only single resource from these matching label
73                 if name != "" {
74                         //Assigning 0-length, because we may actually not find matching name
75                         resourcesStatus = make([]ResourceStatus, 0)
76                         for _, res := range resList {
77                                 if res.Name == name {
78                                         resourcesStatus = append(resourcesStatus, res)
79                                         break
80                                 }
81                         }
82                 } else {
83                         resourcesStatus = resList
84                 }
85         } else if name != "" {
86                 resIdentifier := helm.KubernetesResource{
87                         Name: name,
88                         GVK:  schema.FromAPIVersionAndKind(apiVersion, kind),
89                 }
90                 res, err := k8sClient.GetResourceStatus(resIdentifier, namespace)
91                 if err != nil {
92                         return QueryStatus{}, pkgerrors.Wrap(err, "Querying Resource")
93                 }
94                 resourcesStatus = []ResourceStatus{res}
95         } else {
96                 resList, err := k8sClient.queryResources(apiVersion, kind, labels, namespace)
97                 if err != nil {
98                         return QueryStatus{}, pkgerrors.Wrap(err, "Querying Resources")
99                 }
100                 resourcesStatus = resList
101         }
102
103         resp := QueryStatus{
104                 ResourceCount:   int32(len(resourcesStatus)),
105                 ResourcesStatus: resourcesStatus,
106         }
107         return resp, nil
108 }