mirror of https://github.com/portainer/portainer
				
				
				
			
		
			
				
	
	
		
			154 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Go
		
	
	
			
		
		
	
	
			154 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			Go
		
	
	
package cli
 | 
						|
 | 
						|
import (
 | 
						|
	"context"
 | 
						|
 | 
						|
	models "github.com/portainer/portainer/api/http/models/kubernetes"
 | 
						|
	v1 "k8s.io/api/core/v1"
 | 
						|
	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
 | 
						|
	"k8s.io/apimachinery/pkg/util/intstr"
 | 
						|
)
 | 
						|
 | 
						|
// GetServices gets all the services for a given namespace in a k8s endpoint.
 | 
						|
func (kcl *KubeClient) GetServices(namespace string) ([]models.K8sServiceInfo, error) {
 | 
						|
	client := kcl.cli.CoreV1().Services(namespace)
 | 
						|
 | 
						|
	services, err := client.List(context.Background(), metav1.ListOptions{})
 | 
						|
	if err != nil {
 | 
						|
		return nil, err
 | 
						|
	}
 | 
						|
 | 
						|
	var result []models.K8sServiceInfo
 | 
						|
 | 
						|
	for _, service := range services.Items {
 | 
						|
		servicePorts := make([]models.K8sServicePort, 0)
 | 
						|
		for _, port := range service.Spec.Ports {
 | 
						|
			servicePorts = append(servicePorts, models.K8sServicePort{
 | 
						|
				Name:       port.Name,
 | 
						|
				NodePort:   int(port.NodePort),
 | 
						|
				Port:       int(port.Port),
 | 
						|
				Protocol:   string(port.Protocol),
 | 
						|
				TargetPort: port.TargetPort.IntValue(),
 | 
						|
			})
 | 
						|
		}
 | 
						|
 | 
						|
		ingressStatus := make([]models.K8sServiceIngress, 0)
 | 
						|
		for _, status := range service.Status.LoadBalancer.Ingress {
 | 
						|
			ingressStatus = append(ingressStatus, models.K8sServiceIngress{
 | 
						|
				IP:   status.IP,
 | 
						|
				Host: status.Hostname,
 | 
						|
			})
 | 
						|
		}
 | 
						|
 | 
						|
		result = append(result, models.K8sServiceInfo{
 | 
						|
			Name:                          service.Name,
 | 
						|
			UID:                           string(service.GetUID()),
 | 
						|
			Type:                          string(service.Spec.Type),
 | 
						|
			Namespace:                     service.Namespace,
 | 
						|
			CreationTimestamp:             service.GetCreationTimestamp().String(),
 | 
						|
			AllocateLoadBalancerNodePorts: service.Spec.AllocateLoadBalancerNodePorts,
 | 
						|
			Ports:                         servicePorts,
 | 
						|
			IngressStatus:                 ingressStatus,
 | 
						|
			Labels:                        service.GetLabels(),
 | 
						|
			Annotations:                   service.GetAnnotations(),
 | 
						|
		})
 | 
						|
	}
 | 
						|
 | 
						|
	return result, nil
 | 
						|
}
 | 
						|
 | 
						|
// CreateService creates a new service in a given namespace in a k8s endpoint.
 | 
						|
func (kcl *KubeClient) CreateService(namespace string, info models.K8sServiceInfo) error {
 | 
						|
	ServiceClient := kcl.cli.CoreV1().Services(namespace)
 | 
						|
	var service v1.Service
 | 
						|
 | 
						|
	service.Name = info.Name
 | 
						|
	service.Spec.Type = v1.ServiceType(info.Type)
 | 
						|
	service.Namespace = info.Namespace
 | 
						|
	service.Annotations = info.Annotations
 | 
						|
	service.Labels = info.Labels
 | 
						|
	service.Spec.AllocateLoadBalancerNodePorts = info.AllocateLoadBalancerNodePorts
 | 
						|
	service.Spec.Selector = info.Selector
 | 
						|
 | 
						|
	// Set ports.
 | 
						|
	for _, p := range info.Ports {
 | 
						|
		var port v1.ServicePort
 | 
						|
		port.Name = p.Name
 | 
						|
		port.NodePort = int32(p.NodePort)
 | 
						|
		port.Port = int32(p.Port)
 | 
						|
		port.Protocol = v1.Protocol(p.Protocol)
 | 
						|
		port.TargetPort = intstr.FromInt(p.TargetPort)
 | 
						|
		service.Spec.Ports = append(service.Spec.Ports, port)
 | 
						|
	}
 | 
						|
 | 
						|
	// Set ingresses.
 | 
						|
	for _, i := range info.IngressStatus {
 | 
						|
		var ing v1.LoadBalancerIngress
 | 
						|
		ing.IP = i.IP
 | 
						|
		ing.Hostname = i.Host
 | 
						|
		service.Status.LoadBalancer.Ingress = append(
 | 
						|
			service.Status.LoadBalancer.Ingress,
 | 
						|
			ing,
 | 
						|
		)
 | 
						|
	}
 | 
						|
 | 
						|
	_, err := ServiceClient.Create(context.Background(), &service, metav1.CreateOptions{})
 | 
						|
	return err
 | 
						|
}
 | 
						|
 | 
						|
// DeleteServices processes a K8sServiceDeleteRequest by deleting each service
 | 
						|
// in its given namespace.
 | 
						|
func (kcl *KubeClient) DeleteServices(reqs models.K8sServiceDeleteRequests) error {
 | 
						|
	var err error
 | 
						|
	for namespace := range reqs {
 | 
						|
		for _, service := range reqs[namespace] {
 | 
						|
			serviceClient := kcl.cli.CoreV1().Services(namespace)
 | 
						|
			err = serviceClient.Delete(
 | 
						|
				context.Background(),
 | 
						|
				service,
 | 
						|
				metav1.DeleteOptions{},
 | 
						|
			)
 | 
						|
		}
 | 
						|
	}
 | 
						|
	return err
 | 
						|
}
 | 
						|
 | 
						|
// UpdateService updates service in a given namespace in a k8s endpoint.
 | 
						|
func (kcl *KubeClient) UpdateService(namespace string, info models.K8sServiceInfo) error {
 | 
						|
	ServiceClient := kcl.cli.CoreV1().Services(namespace)
 | 
						|
	var service v1.Service
 | 
						|
 | 
						|
	service.Name = info.Name
 | 
						|
	service.Spec.Type = v1.ServiceType(info.Type)
 | 
						|
	service.Namespace = info.Namespace
 | 
						|
	service.Annotations = info.Annotations
 | 
						|
	service.Labels = info.Labels
 | 
						|
	service.Spec.AllocateLoadBalancerNodePorts = info.AllocateLoadBalancerNodePorts
 | 
						|
	service.Spec.Selector = info.Selector
 | 
						|
 | 
						|
	// Set ports.
 | 
						|
	for _, p := range info.Ports {
 | 
						|
		var port v1.ServicePort
 | 
						|
		port.Name = p.Name
 | 
						|
		port.NodePort = int32(p.NodePort)
 | 
						|
		port.Port = int32(p.Port)
 | 
						|
		port.Protocol = v1.Protocol(p.Protocol)
 | 
						|
		port.TargetPort = intstr.FromInt(p.TargetPort)
 | 
						|
		service.Spec.Ports = append(service.Spec.Ports, port)
 | 
						|
	}
 | 
						|
 | 
						|
	// Set ingresses.
 | 
						|
	for _, i := range info.IngressStatus {
 | 
						|
		var ing v1.LoadBalancerIngress
 | 
						|
		ing.IP = i.IP
 | 
						|
		ing.Hostname = i.Host
 | 
						|
		service.Status.LoadBalancer.Ingress = append(
 | 
						|
			service.Status.LoadBalancer.Ingress,
 | 
						|
			ing,
 | 
						|
		)
 | 
						|
	}
 | 
						|
 | 
						|
	_, err := ServiceClient.Update(context.Background(), &service, metav1.UpdateOptions{})
 | 
						|
	return err
 | 
						|
}
 |