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  }