-
Notifications
You must be signed in to change notification settings - Fork 42
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Signed-off-by: warjiang <[email protected]>
- Loading branch information
Showing
4 changed files
with
226 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,42 @@ | ||
package service | ||
|
||
import ( | ||
"github.com/karmada-io/dashboard/pkg/dataselect" | ||
v1 "k8s.io/api/core/v1" | ||
) | ||
|
||
// The code below allows to perform complex data section on []api.Service | ||
|
||
type ServiceCell v1.Service | ||
|
||
func (self ServiceCell) GetProperty(name dataselect.PropertyName) dataselect.ComparableValue { | ||
switch name { | ||
case dataselect.NameProperty: | ||
return dataselect.StdComparableString(self.ObjectMeta.Name) | ||
case dataselect.CreationTimestampProperty: | ||
return dataselect.StdComparableTime(self.ObjectMeta.CreationTimestamp.Time) | ||
case dataselect.NamespaceProperty: | ||
return dataselect.StdComparableString(self.ObjectMeta.Namespace) | ||
case dataselect.TypeProperty: | ||
return dataselect.StdComparableString(self.Spec.Type) | ||
default: | ||
// if name is not supported then just return a constant dummy value, sort will have no effect. | ||
return nil | ||
} | ||
} | ||
|
||
func toCells(std []v1.Service) []dataselect.DataCell { | ||
cells := make([]dataselect.DataCell, len(std)) | ||
for i := range std { | ||
cells[i] = ServiceCell(std[i]) | ||
} | ||
return cells | ||
} | ||
|
||
func fromCells(cells []dataselect.DataCell) []v1.Service { | ||
std := make([]v1.Service, len(cells)) | ||
for i := range std { | ||
std[i] = v1.Service(cells[i].(ServiceCell)) | ||
} | ||
return std | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,53 @@ | ||
package service | ||
|
||
import ( | ||
"context" | ||
"github.com/karmada-io/dashboard/pkg/common/errors" | ||
"github.com/karmada-io/dashboard/pkg/resource/endpoint" | ||
v1 "k8s.io/api/core/v1" | ||
metaV1 "k8s.io/apimachinery/pkg/apis/meta/v1" | ||
k8sClient "k8s.io/client-go/kubernetes" | ||
"log" | ||
) | ||
|
||
// Service is a representation of a service. | ||
type ServiceDetail struct { | ||
// Extends list item structure. | ||
Service `json:",inline"` | ||
|
||
// List of Endpoint obj. that are endpoints of this Service. | ||
EndpointList endpoint.EndpointList `json:"endpointList"` | ||
|
||
// Show the value of the SessionAffinity of the Service. | ||
SessionAffinity v1.ServiceAffinity `json:"sessionAffinity"` | ||
|
||
// List of non-critical errors, that occurred during resource retrieval. | ||
Errors []error `json:"errors"` | ||
} | ||
|
||
// GetServiceDetail gets service details. | ||
func GetServiceDetail(client k8sClient.Interface, namespace, name string) (*ServiceDetail, error) { | ||
log.Printf("Getting details of %s service in %s namespace", name, namespace) | ||
serviceData, err := client.CoreV1().Services(namespace).Get(context.TODO(), name, metaV1.GetOptions{}) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
endpointList, err := endpoint.GetServiceEndpoints(client, namespace, name) | ||
nonCriticalErrors, criticalError := errors.ExtractErrors(err) | ||
if criticalError != nil { | ||
return nil, criticalError | ||
} | ||
|
||
service := toServiceDetail(serviceData, *endpointList, nonCriticalErrors) | ||
return &service, nil | ||
} | ||
|
||
func toServiceDetail(service *v1.Service, endpointList endpoint.EndpointList, nonCriticalErrors []error) ServiceDetail { | ||
return ServiceDetail{ | ||
Service: toService(service), | ||
EndpointList: endpointList, | ||
SessionAffinity: service.Spec.SessionAffinity, | ||
Errors: nonCriticalErrors, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
package service | ||
|
||
import ( | ||
"github.com/karmada-io/dashboard/pkg/common/types" | ||
"github.com/karmada-io/dashboard/pkg/dataselect" | ||
"github.com/karmada-io/dashboard/pkg/resource/common" | ||
"github.com/karmada-io/dashboard/pkg/resource/event" | ||
"log" | ||
|
||
client "k8s.io/client-go/kubernetes" | ||
) | ||
|
||
// GetServiceEvents returns model events for a service with the given name in the given namespace. | ||
func GetServiceEvents(client client.Interface, dsQuery *dataselect.DataSelectQuery, namespace, name string) ( | ||
*common.EventList, error) { | ||
eventList := common.EventList{ | ||
Events: make([]common.Event, 0), | ||
ListMeta: types.ListMeta{TotalItems: 0}, | ||
} | ||
|
||
serviceEvents, err := event.GetEvents(client, namespace, name) | ||
if err != nil { | ||
return &eventList, err | ||
} | ||
|
||
eventList = event.CreateEventList(event.FillEventsType(serviceEvents), dsQuery) | ||
log.Printf("Found %d events related to %s service in %s namespace", len(eventList.Events), name, namespace) | ||
return &eventList, nil | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,102 @@ | ||
package service | ||
|
||
import ( | ||
"github.com/karmada-io/dashboard/pkg/common/errors" | ||
"github.com/karmada-io/dashboard/pkg/common/types" | ||
"github.com/karmada-io/dashboard/pkg/dataselect" | ||
"github.com/karmada-io/dashboard/pkg/resource/common" | ||
v1 "k8s.io/api/core/v1" | ||
client "k8s.io/client-go/kubernetes" | ||
"log" | ||
) | ||
|
||
// Service is a representation of a service. | ||
type Service struct { | ||
ObjectMeta types.ObjectMeta `json:"objectMeta"` | ||
TypeMeta types.TypeMeta `json:"typeMeta"` | ||
|
||
// InternalEndpoint of all Kubernetes services that have the same label selector as connected Replication | ||
// Controller. Endpoint is DNS name merged with ports. | ||
InternalEndpoint common.Endpoint `json:"internalEndpoint"` | ||
|
||
// ExternalEndpoints of all Kubernetes services that have the same label selector as connected Replication | ||
// Controller. Endpoint is external IP address name merged with ports. | ||
ExternalEndpoints []common.Endpoint `json:"externalEndpoints"` | ||
|
||
// Label selector of the service. | ||
Selector map[string]string `json:"selector"` | ||
|
||
// Type determines how the service will be exposed. Valid options: ClusterIP, NodePort, LoadBalancer, ExternalName | ||
Type v1.ServiceType `json:"type"` | ||
|
||
// ClusterIP is usually assigned by the control plane. Valid values are None, empty string (""), or | ||
// a valid IP address. None can be specified for headless services when proxying is not required | ||
ClusterIP string `json:"clusterIP"` | ||
} | ||
|
||
// ServiceList contains a list of services in the cluster. | ||
type ServiceList struct { | ||
ListMeta types.ListMeta `json:"listMeta"` | ||
|
||
// Unordered list of services. | ||
Services []Service `json:"services"` | ||
|
||
// List of non-critical errors, that occurred during resource retrieval. | ||
Errors []error `json:"errors"` | ||
} | ||
|
||
// GetServiceList returns a list of all services in the cluster. | ||
func GetServiceList(client client.Interface, nsQuery *common.NamespaceQuery, | ||
dsQuery *dataselect.DataSelectQuery) (*ServiceList, error) { | ||
log.Print("Getting list of all services in the cluster") | ||
|
||
channels := &common.ResourceChannels{ | ||
ServiceList: common.GetServiceListChannel(client, nsQuery, 1), | ||
} | ||
|
||
return GetServiceListFromChannels(channels, dsQuery) | ||
} | ||
|
||
// GetServiceListFromChannels returns a list of all services in the cluster. | ||
func GetServiceListFromChannels(channels *common.ResourceChannels, | ||
dsQuery *dataselect.DataSelectQuery) (*ServiceList, error) { | ||
services := <-channels.ServiceList.List | ||
err := <-channels.ServiceList.Error | ||
nonCriticalErrors, criticalError := errors.ExtractErrors(err) | ||
if criticalError != nil { | ||
return nil, criticalError | ||
} | ||
|
||
return CreateServiceList(services.Items, nonCriticalErrors, dsQuery), nil | ||
} | ||
|
||
func toService(service *v1.Service) Service { | ||
return Service{ | ||
ObjectMeta: types.NewObjectMeta(service.ObjectMeta), | ||
TypeMeta: types.NewTypeMeta(types.ResourceKindService), | ||
InternalEndpoint: common.GetInternalEndpoint(service.Name, service.Namespace, service.Spec.Ports), | ||
ExternalEndpoints: common.GetExternalEndpoints(service), | ||
Selector: service.Spec.Selector, | ||
ClusterIP: service.Spec.ClusterIP, | ||
Type: service.Spec.Type, | ||
} | ||
} | ||
|
||
// CreateServiceList returns paginated service list based on given service array and pagination query. | ||
func CreateServiceList(services []v1.Service, nonCriticalErrors []error, dsQuery *dataselect.DataSelectQuery) *ServiceList { | ||
serviceList := &ServiceList{ | ||
Services: make([]Service, 0), | ||
ListMeta: types.ListMeta{TotalItems: len(services)}, | ||
Errors: nonCriticalErrors, | ||
} | ||
|
||
serviceCells, filteredTotal := dataselect.GenericDataSelectWithFilter(toCells(services), dsQuery) | ||
services = fromCells(serviceCells) | ||
serviceList.ListMeta = types.ListMeta{TotalItems: filteredTotal} | ||
|
||
for _, service := range services { | ||
serviceList.Services = append(serviceList.Services, toService(&service)) | ||
} | ||
|
||
return serviceList | ||
} |