Skip to content

Commit c2ab87d

Browse files
author
nishant
committed
Merge remote-tracking branch 'common-lib/appdetails-improv-sept24' into appdetails-improv-sept24-common-lib
2 parents e6ec309 + 2784806 commit c2ab87d

9 files changed

Lines changed: 1012 additions & 52 deletions

File tree

common-lib/go.mod

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@ require (
6161
github.com/cespare/xxhash/v2 v2.2.0 // indirect
6262
github.com/containerd/containerd v1.7.12 // indirect
6363
github.com/containerd/log v0.1.0 // indirect
64-
github.com/davecgh/go-spew v1.1.1 // indirect
64+
github.com/davecgh/go-spew v1.1.1
6565
github.com/docker/cli v24.0.6+incompatible
6666
github.com/docker/distribution v2.8.2+incompatible // indirect
6767
github.com/docker/docker-credential-helpers v0.7.0 // indirect

common-lib/utils/k8s/K8sUtil.go

Lines changed: 27 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -179,7 +179,7 @@ func (impl *K8sServiceImpl) GetRestConfigByClusterWithoutCustomTransport(cluster
179179
bearerToken := clusterConfig.BearerToken
180180
var restConfig *rest.Config
181181
var err error
182-
if clusterConfig.Host == DefaultClusterUrl && len(bearerToken) == 0 {
182+
if clusterConfig.Host == commonBean.DefaultClusterUrl && len(bearerToken) == 0 {
183183
restConfig, err = impl.GetK8sInClusterRestConfig()
184184
if err != nil {
185185
impl.logger.Errorw("error in getting rest config for default cluster", "err", err)
@@ -632,7 +632,7 @@ func (impl *K8sServiceImpl) DiscoveryClientGetLiveZCall(cluster *ClusterConfig)
632632
return nil, err
633633
}
634634
//using livez path as healthz path is deprecated
635-
response, err := impl.GetLiveZCall(LiveZ, k8sClientSet)
635+
response, err := impl.GetLiveZCall(commonBean.LiveZ, k8sClientSet)
636636
if err != nil {
637637
impl.logger.Errorw("error in getting livez call", "err", err, "clusterName", cluster.ClusterName)
638638
return nil, err
@@ -694,7 +694,7 @@ func (impl *K8sServiceImpl) DeletePodByLabel(namespace string, labels string, cl
694694
}
695695

696696
for _, pod := range (*podList).Items {
697-
if pod.Status.Phase != Running {
697+
if pod.Status.Phase != commonBean.Running {
698698
podName := pod.ObjectMeta.Name
699699
err := pods.Delete(context.Background(), podName, metav1.DeleteOptions{})
700700
if err != nil && !errors.IsNotFound(err) {
@@ -751,7 +751,7 @@ func (impl *K8sServiceImpl) ListNamespaces(client *v12.CoreV1Client) (*v1.Namesp
751751
}
752752

753753
func (impl *K8sServiceImpl) GetClientByToken(serverUrl string, token map[string]string) (*v12.CoreV1Client, error) {
754-
bearerToken := token[BearerToken]
754+
bearerToken := token[commonBean.BearerToken]
755755
clusterCfg := &ClusterConfig{Host: serverUrl, BearerToken: bearerToken}
756756
v12Client, err := impl.GetCoreV1Client(clusterCfg)
757757
if err != nil {
@@ -883,16 +883,30 @@ func (impl *K8sServiceImpl) BuildK8sObjectListTableData(manifest *unstructured.U
883883
var cellObj map[string]interface{}
884884
if cellObjUncast != nil {
885885
cellObj = cellObjUncast.(map[string]interface{})
886-
if cellObj != nil && cellObj[commonBean.K8sClusterResourceMetadataKey] != nil {
887-
metadata := cellObj[commonBean.K8sClusterResourceMetadataKey].(map[string]interface{})
888-
if metadata[commonBean.K8sClusterResourceNamespaceKey] != nil {
889-
namespace = metadata[commonBean.K8sClusterResourceNamespaceKey].(string)
890-
if namespaced {
891-
rowIndex[commonBean.K8sClusterResourceNamespaceKey] = namespace
886+
if cellObj != nil {
887+
rowIndex[commonBean.K8sClusterResourceKindKey] = cellObj[commonBean.K8sClusterResourceKindKey].(string)
888+
rowIndex[commonBean.K8sClusterResourceApiVersionKey] = cellObj[commonBean.K8sClusterResourceApiVersionKey].(string)
889+
890+
if cellObj[commonBean.K8sClusterResourceMetadataKey] != nil {
891+
metadata := cellObj[commonBean.K8sClusterResourceMetadataKey].(map[string]interface{})
892+
if metadata[commonBean.K8sClusterResourceNamespaceKey] != nil {
893+
namespace = metadata[commonBean.K8sClusterResourceNamespaceKey].(string)
894+
if namespaced {
895+
rowIndex[commonBean.K8sClusterResourceNamespaceKey] = namespace
896+
}
897+
}
898+
if includeMetadata {
899+
rowIndex[commonBean.K8sClusterResourceMetadataKey] = metadata
892900
}
893901
}
894-
if includeMetadata {
895-
rowIndex[commonBean.K8sClusterResourceMetadataKey] = metadata
902+
903+
if cellObj[commonBean.K8sClusterResourceSpecKey] != nil {
904+
spec, ok := cellObj[commonBean.K8sClusterResourceSpecKey].(map[string]interface{})
905+
if ok {
906+
rowIndex[commonBean.K8sClusterResourceSpecKey] = spec
907+
} else {
908+
impl.logger.Warnw("Not able to cast spec key of manifest to map")
909+
}
896910
}
897911
}
898912
}
@@ -1221,7 +1235,7 @@ func (impl *K8sServiceImpl) CreateK8sClientSet(restConfig *rest.Config) (*kubern
12211235

12221236
func (impl *K8sServiceImpl) FetchConnectionStatusForCluster(k8sClientSet *kubernetes.Clientset) error {
12231237
//using livez path as healthz path is deprecated
1224-
path := LiveZ
1238+
path := commonBean.LiveZ
12251239
response, err := k8sClientSet.Discovery().RESTClient().Get().AbsPath(path).DoRaw(context.Background())
12261240
log.Println("received response for cluster livez status", "response", string(response), "err", err)
12271241
if err != nil {
@@ -1758,24 +1772,6 @@ func (impl *K8sServiceImpl) GetPodListByLabel(namespace, label string, clientSet
17581772
return podList.Items, nil
17591773
}
17601774

1761-
func IsService(gvk schema.GroupVersionKind) bool {
1762-
return gvk.Group == "" && gvk.Kind == commonBean.ServiceKind
1763-
}
1764-
1765-
func IsPod(gvk schema.GroupVersionKind) bool {
1766-
return gvk.Group == "" && gvk.Kind == commonBean.PodKind && gvk.Version == "v1"
1767-
}
1768-
1769-
func IsDevtronApp(labels map[string]string) bool {
1770-
isDevtronApp := false
1771-
if val, ok := labels[DEVTRON_APP_LABEL_KEY]; ok {
1772-
if val == DEVTRON_APP_LABEL_VALUE1 || val == DEVTRON_APP_LABEL_VALUE2 {
1773-
isDevtronApp = true
1774-
}
1775-
}
1776-
return isDevtronApp
1777-
}
1778-
17791775
//func GetHealthCheckFunc(gvk schema.GroupVersionKind) func(obj *unstructured.Unstructured) (*health.HealthStatus, error) {
17801776
// return health.GetHealthCheckFunc(gvk)
17811777
//}

common-lib/utils/k8s/adapter.go

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,3 +40,14 @@ func (req *ResourceIdentifier) WithKind(kind string) *ResourceIdentifier {
4040
req.GroupVersionKind.Kind = kind
4141
return req
4242
}
43+
44+
//
45+
//func GetEmptyResourceForResourceKey(resourceKey *ResourceKey) *Resource {
46+
// return &cache.Resource{
47+
// Ref: v1.ObjectReference{
48+
// Kind: resourceKey.Kind,
49+
// Namespace: resourceKey.Namespace,
50+
// Name: resourceKey.Name,
51+
// },
52+
// }
53+
//}

common-lib/utils/k8s/bean.go

Lines changed: 0 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -35,22 +35,6 @@ import (
3535
"time"
3636
)
3737

38-
const (
39-
DEFAULT_CLUSTER = "default_cluster"
40-
DEVTRON_SERVICE_NAME = "devtron-service"
41-
DefaultClusterUrl = "https://kubernetes.default.svc"
42-
BearerToken = "bearer_token"
43-
CertificateAuthorityData = "cert_auth_data"
44-
CertData = "cert_data"
45-
TlsKey = "tls_key"
46-
LiveZ = "/livez"
47-
Running = "Running"
48-
RestartingNotSupported = "restarting not supported"
49-
DEVTRON_APP_LABEL_KEY = "app"
50-
DEVTRON_APP_LABEL_VALUE1 = "devtron"
51-
DEVTRON_APP_LABEL_VALUE2 = "orchestrator"
52-
)
53-
5438
type ClusterConfig struct {
5539
ClusterName string
5640
Host string

common-lib/utils/k8s/commonBean/bean.go

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,9 @@
1717
package commonBean
1818

1919
import (
20+
v1 "k8s.io/api/core/v1"
2021
"k8s.io/apimachinery/pkg/api/meta"
22+
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
2123
"k8s.io/apimachinery/pkg/runtime/schema"
2224
)
2325

@@ -73,6 +75,17 @@ const (
7375
StatefulSetsResourceType = "statefulsets"
7476
)
7577

78+
const (
79+
ContainersType = "Containers"
80+
ContainersNamesType = "ContainerNames"
81+
InitContainersNamesType = "InitContainerNames"
82+
EphemeralContainersInfoType = "EphemeralContainerInfo"
83+
EphemeralContainersStatusType = "EphemeralContainerStatuses"
84+
StatusReason = "Status Reason"
85+
Node = "Node"
86+
RestartCount = "Restart Count"
87+
)
88+
7689
const (
7790
Group = "group"
7891
Version = "version"
@@ -103,6 +116,7 @@ const K8sClusterResourceNameKey = "name"
103116
const K8sClusterResourcePriorityKey = "priority"
104117
const K8sClusterResourceNamespaceKey = "namespace"
105118
const K8sClusterResourceMetadataKey = "metadata"
119+
const K8sClusterResourceSpecKey = "spec"
106120
const K8sClusterResourceMetadataNameKey = "name"
107121
const K8sClusterResourceOwnerReferenceKey = "ownerReferences"
108122
const K8sClusterResourceCreationTimestampKey = "creationTimestamp"
@@ -126,6 +140,9 @@ const V1VERSION = "v1"
126140
const BatchGroup = "batch"
127141
const AppsGroup = "apps"
128142

143+
const HelmHookAnnotation = "helm.sh/hook"
144+
const HibernateReplicaAnnotation = "hibernator.devtron.ai/replicas"
145+
129146
const (
130147
K8sResourceColumnDefinitionName = "Name"
131148
K8sResourceColumnDefinitionSyncStatus = "Sync Status"
@@ -200,3 +217,131 @@ type GvrAndScope struct {
200217
func GetGvkVsChildGvrAndScope() map[schema.GroupVersionKind][]*GvrAndScope {
201218
return gvkVsChildGvrAndScope
202219
}
220+
221+
// ResourceNode contains information about live resource and its children
222+
type ResourceNode struct {
223+
*ResourceRef `json:",inline" protobuf:"bytes,1,opt,name=resourceRef"`
224+
ParentRefs []*ResourceRef `json:"parentRefs,omitempty" protobuf:"bytes,2,opt,name=parentRefs"`
225+
NetworkingInfo *ResourceNetworkingInfo `json:"networkingInfo,omitempty" protobuf:"bytes,4,opt,name=networkingInfo"`
226+
ResourceVersion string `json:"resourceVersion,omitempty" protobuf:"bytes,5,opt,name=resourceVersion"`
227+
Health *HealthStatus `json:"health,omitempty" protobuf:"bytes,7,opt,name=health"`
228+
IsHibernated bool `json:"isHibernated"`
229+
CanBeHibernated bool `json:"canBeHibernated"`
230+
Info []InfoItem `json:"info,omitempty"`
231+
Port []int64 `json:"port,omitempty"`
232+
CreatedAt string `json:"createdAt,omitempty"`
233+
IsHook bool `json:"isHook,omitempty"`
234+
HookType string `json:"hookType,omitempty"`
235+
// UpdateRevision is used when a pod's owner is a StatefulSet for identifying if the pod is new or old
236+
UpdateRevision string `json:"updateRevision,omitempty"`
237+
// DeploymentPodHash is the podHash in deployment manifest and is used to compare replicaSet's podHash for identifying new vs old pod
238+
DeploymentPodHash string `json:"deploymentPodHash,omitempty"`
239+
DeploymentCollisionCount *int32 `json:"deploymentCollisionCount,omitempty"`
240+
// RolloutCurrentPodHash is the podHash in rollout manifest and is used to compare replicaSet's podHash for identifying new vs old pod
241+
RolloutCurrentPodHash string `json:"rolloutCurrentPodHash,omitempty"`
242+
}
243+
244+
// ResourceRef includes fields which unique identify resource
245+
type ResourceRef struct {
246+
Group string `json:"group,omitempty" protobuf:"bytes,1,opt,name=group"`
247+
Version string `json:"version,omitempty" protobuf:"bytes,2,opt,name=version"`
248+
Kind string `json:"kind,omitempty" protobuf:"bytes,3,opt,name=kind"`
249+
Namespace string `json:"namespace,omitempty" protobuf:"bytes,4,opt,name=namespace"`
250+
Name string `json:"name,omitempty" protobuf:"bytes,5,opt,name=name"`
251+
UID string `json:"uid,omitempty" protobuf:"bytes,6,opt,name=uid"`
252+
Manifest unstructured.Unstructured `json:"-"`
253+
}
254+
255+
func (r *ResourceRef) GetGvk() schema.GroupVersionKind {
256+
if r == nil {
257+
return schema.GroupVersionKind{}
258+
}
259+
return schema.GroupVersionKind{
260+
Group: r.Group,
261+
Version: r.Version,
262+
Kind: r.Kind,
263+
}
264+
}
265+
266+
// ResourceNetworkingInfo holds networking resource related information
267+
type ResourceNetworkingInfo struct {
268+
Labels map[string]string `json:"labels,omitempty" protobuf:"bytes,3,opt,name=labels"`
269+
}
270+
271+
type HealthStatus struct {
272+
Status HealthStatusCode `json:"status,omitempty" protobuf:"bytes,1,opt,name=status"`
273+
Message string `json:"message,omitempty" protobuf:"bytes,2,opt,name=message"`
274+
}
275+
276+
type HealthStatusCode = string
277+
278+
const (
279+
HealthStatusUnknown HealthStatusCode = "Unknown"
280+
HealthStatusProgressing HealthStatusCode = "Progressing"
281+
HealthStatusHealthy HealthStatusCode = "Healthy"
282+
HealthStatusSuspended HealthStatusCode = "Suspended"
283+
HealthStatusDegraded HealthStatusCode = "Degraded"
284+
HealthStatusMissing HealthStatusCode = "Missing"
285+
HealthStatusHibernated HealthStatusCode = "Hibernated"
286+
HealthStatusPartiallyHibernated HealthStatusCode = "Partially Hibernated"
287+
)
288+
289+
type ResourceTreeResponse struct {
290+
Nodes []*ResourceNode `json:"nodes,omitempty"`
291+
PodMetadata []*PodMetadata `json:"podMetadata,omitempty"`
292+
}
293+
294+
type PodMetadata struct {
295+
Name string `json:"name"`
296+
UID string `json:"uid"`
297+
Containers []string `json:"containers"`
298+
InitContainers []string `json:"initContainers"`
299+
IsNew bool `json:"isNew"`
300+
EphemeralContainers []*EphemeralContainerData `json:"ephemeralContainers"`
301+
}
302+
303+
// use value field as generic type
304+
// InfoItem contains arbitrary, human readable information about an application
305+
type InfoItem struct {
306+
// Name is a human readable title for this piece of information.
307+
Name string `json:"name,omitempty"`
308+
// Value is human readable content.
309+
Value interface{} `json:"value,omitempty"`
310+
}
311+
312+
type EphemeralContainerData struct {
313+
Name string `json:"name"`
314+
IsExternal bool `json:"isExternal"`
315+
}
316+
317+
type EphemeralContainerStatusesInfo struct {
318+
Name string
319+
State v1.ContainerState
320+
}
321+
322+
type EphemeralContainerInfo struct {
323+
Name string
324+
Command []string
325+
}
326+
type ExtraNodeInfo struct {
327+
// UpdateRevision is only used for StatefulSets, if not empty, indicates the version of the StatefulSet used to generate Pods in the sequence
328+
UpdateRevision string
329+
ResourceNetworkingInfo *ResourceNetworkingInfo
330+
RolloutCurrentPodHash string
331+
}
332+
333+
const (
334+
DEFAULT_CLUSTER = "default_cluster"
335+
DEVTRON_SERVICE_NAME = "devtron-service"
336+
DefaultClusterUrl = "https://kubernetes.default.svc"
337+
BearerToken = "bearer_token"
338+
CertificateAuthorityData = "cert_auth_data"
339+
CertData = "cert_data"
340+
TlsKey = "tls_key"
341+
LiveZ = "/livez"
342+
Running = "Running"
343+
RestartingNotSupported = "restarting not supported"
344+
DEVTRON_APP_LABEL_KEY = "app"
345+
DEVTRON_APP_LABEL_VALUE1 = "devtron"
346+
DEVTRON_APP_LABEL_VALUE2 = "orchestrator"
347+
)

common-lib/utils/k8sObjectsUtil/EphemeralContainersUtil.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,3 @@ func IsExternalEphemeralContainer(cmds []string, name string) bool {
7474
}
7575
return isExternal
7676
}
77-
78-
func IsPod(kind string, group string) bool {
79-
return kind == "Pod" && group == ""
80-
}

0 commit comments

Comments
 (0)