github.com/kiali/kiali@v1.84.0/models/service.go (about) 1 package models 2 3 import ( 4 networking_v1beta1 "istio.io/client-go/pkg/apis/networking/v1beta1" 5 core_v1 "k8s.io/api/core/v1" 6 "k8s.io/apimachinery/pkg/labels" 7 k8s_networking_v1 "sigs.k8s.io/gateway-api/apis/v1" 8 k8s_networking_v1beta1 "sigs.k8s.io/gateway-api/apis/v1beta1" 9 10 "github.com/kiali/kiali/config" 11 "github.com/kiali/kiali/kubernetes" 12 ) 13 14 type ServiceOverview struct { 15 // Name of the Service 16 // required: true 17 // example: reviews-v1 18 Name string `json:"name"` 19 // Namespace of the Service 20 Namespace string `json:"namespace"` 21 // Define if Pods related to this Service has an IstioSidecar deployed 22 // required: true 23 // example: true 24 IstioSidecar bool `json:"istioSidecar"` 25 // The kube cluster where this service is located. 26 Cluster string `json:"cluster"` 27 // Check if it has Ambient enabled 28 // required: true 29 // example: true 30 IstioAmbient bool `json:"istioAmbient"` 31 // Has label app 32 // required: true 33 // example: true 34 AppLabel bool `json:"appLabel"` 35 // Additional detail sample, such as type of api being served (graphql, grpc, rest) 36 // example: rest 37 // required: false 38 AdditionalDetailSample *AdditionalItem `json:"additionalDetailSample"` 39 // Annotations of Deployment 40 // required: false 41 Annotations map[string]string `json:"annotations"` 42 // Annotations of the service 43 HealthAnnotations map[string]string `json:"healthAnnotations"` 44 // Names and Ports of Service 45 Ports map[string]int `json:"ports"` 46 // Labels for Service 47 Labels map[string]string `json:"labels"` 48 // Selector for Service 49 Selector map[string]string `json:"selector"` 50 // Istio References 51 IstioReferences []*IstioValidationKey `json:"istioReferences"` 52 // Kiali Wizard scenario, if any 53 KialiWizard string `json:"kialiWizard"` 54 // ServiceRegistry values: 55 // Kubernetes: is a service registry backed by k8s API server 56 // External: is a service registry for externally provided ServiceEntries 57 // Federation: special case when registry is provided from a federated environment 58 ServiceRegistry string `json:"serviceRegistry"` 59 60 // Health 61 Health ServiceHealth `json:"health,omitempty"` 62 } 63 64 type ClusterServices struct { 65 // Cluster where the services live in 66 // required: true 67 // example: east 68 Cluster string `json:"cluster"` 69 // Services list for namespaces of a single cluster 70 // required: true 71 Services []ServiceOverview `json:"services"` 72 Validations IstioValidations `json:"validations"` 73 } 74 75 type ServiceList struct { 76 Namespace string `json:"namespace"` 77 Services []ServiceOverview `json:"services"` 78 Validations IstioValidations `json:"validations"` 79 } 80 81 type ServiceDefinitionList struct { 82 Namespace Namespace `json:"namespace"` 83 ServiceDefinitions []ServiceDetails `json:"serviceDefinitions"` 84 } 85 86 type ServiceDetails struct { 87 DestinationRules []*networking_v1beta1.DestinationRule `json:"destinationRules"` 88 Endpoints Endpoints `json:"endpoints"` 89 IstioPermissions ResourcePermissions `json:"istioPermissions"` 90 IstioSidecar bool `json:"istioSidecar"` 91 K8sHTTPRoutes []*k8s_networking_v1.HTTPRoute `json:"k8sHTTPRoutes"` 92 K8sReferenceGrants []*k8s_networking_v1beta1.ReferenceGrant `json:"k8sReferenceGrants"` 93 Service Service `json:"service"` 94 ServiceEntries []*networking_v1beta1.ServiceEntry `json:"serviceEntries"` 95 VirtualServices []*networking_v1beta1.VirtualService `json:"virtualServices"` 96 Workloads WorkloadOverviews `json:"workloads"` 97 // Services with same app labels (different versions or a single version) 98 Health ServiceHealth `json:"health"` 99 NamespaceMTLS MTLSStatus `json:"namespaceMTLS"` 100 SubServices []*ServiceOverview `json:"subServices"` 101 Validations IstioValidations `json:"validations"` 102 } 103 104 type ( 105 Services []*Service 106 Service struct { 107 AdditionalDetails []AdditionalItem `json:"additionalDetails"` 108 Annotations map[string]string `json:"annotations"` 109 Cluster string `json:"cluster"` 110 CreatedAt string `json:"createdAt"` 111 ExternalName string `json:"externalName"` 112 HealthAnnotations map[string]string `json:"healthAnnotations"` 113 Ip string `json:"ip"` 114 Labels map[string]string `json:"labels"` 115 Name string `json:"name"` 116 Namespace string `json:"namespace"` 117 Ports Ports `json:"ports"` 118 ResourceVersion string `json:"resourceVersion"` 119 Selectors map[string]string `json:"selectors"` 120 Type string `json:"type"` 121 } 122 ) 123 124 func (so *ServiceOverview) ParseToService() *Service { 125 svc := Service{ 126 Name: so.Name, 127 Type: so.ServiceRegistry, 128 HealthAnnotations: so.HealthAnnotations, 129 } 130 return &svc 131 } 132 133 func (ss *Services) Parse(cluster string, services []core_v1.Service) { 134 if ss == nil { 135 return 136 } 137 138 for _, item := range services { 139 service := &Service{} 140 service.Parse(cluster, &item) 141 *ss = append(*ss, service) 142 } 143 } 144 145 func (s *Service) Parse(cluster string, service *core_v1.Service) { 146 if service != nil { 147 s.AdditionalDetails = GetAdditionalDetails(config.Get(), service.ObjectMeta.Annotations) 148 if len(service.Annotations) > 0 { 149 s.Annotations = service.Annotations 150 } else { 151 s.Annotations = map[string]string{} 152 } 153 s.Cluster = cluster 154 s.CreatedAt = formatTime(service.CreationTimestamp.Time) 155 s.ExternalName = service.Spec.ExternalName 156 s.HealthAnnotations = GetHealthAnnotation(service.Annotations, GetHealthConfigAnnotation()) 157 s.Ip = service.Spec.ClusterIP 158 s.Labels = service.Labels 159 s.Name = service.Name 160 s.Namespace = service.Namespace 161 (&s.Ports).Parse(service.Spec.Ports) 162 s.ResourceVersion = service.ResourceVersion 163 s.Selectors = service.Spec.Selector 164 s.Type = string(service.Spec.Type) 165 } 166 } 167 168 func (s *Service) ParseRegistryService(cluster string, service *kubernetes.RegistryService) { 169 if service != nil { 170 s.Cluster = cluster 171 s.HealthAnnotations = map[string]string{} 172 s.Labels = service.Attributes.Labels 173 s.Name = service.Attributes.Name 174 s.Namespace = service.Attributes.Namespace 175 s.Ports.ParseServiceRegistryPorts(service) 176 s.Selectors = service.Attributes.LabelSelectors 177 // It will expect "External" or "Federation" 178 s.Type = service.Attributes.ServiceRegistry 179 } 180 } 181 182 func (s *ServiceDetails) SetService(cluster string, svc *core_v1.Service) { 183 s.Service.Parse(cluster, svc) 184 } 185 186 func (s *ServiceDetails) SetEndpoints(eps *core_v1.Endpoints) { 187 (&s.Endpoints).Parse(eps) 188 } 189 190 func (s *ServiceDetails) SetPods(pods []core_v1.Pod) { 191 mPods := Pods{} 192 mPods.Parse(pods) 193 } 194 195 func (s *ServiceDetails) SetIstioSidecar(workloads WorkloadOverviews) { 196 s.IstioSidecar = workloads.HasIstioSidecar() 197 } 198 199 func (s *ServiceList) HasMatchingServices(service string) bool { 200 for _, s := range s.Services { 201 if service == s.Name { 202 return true 203 } 204 } 205 return false 206 } 207 208 func (s *ServiceList) FilterServicesForSelector(selector labels.Selector) []ServiceOverview { 209 services := []ServiceOverview{} 210 for _, svc := range s.Services { 211 if selector.Matches(labels.Set(svc.Selector)) { 212 services = append(services, svc) 213 } 214 } 215 return services 216 } 217 218 func (s *ServiceList) GetServiceNames() []string { 219 serviceNames := make([]string, 0) 220 for _, item := range s.Services { 221 serviceNames = append(serviceNames, item.Name) 222 } 223 return serviceNames 224 }