100 lines
2.5 KiB
Go

package pod
import (
"fmt"
"os"
apiv1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
"k8s.io/client-go/kubernetes"
"k8s.io/klog"
"k8s.io/kubernetes/pkg/kubelet/util/sliceutils"
)
// Info contains runtime information about the pod running the Ingres controller
type Info struct {
Name string
Namespace string
// Labels selectors of the running pod
// This is used to search for other Ingress controller pods
Labels map[string]string
}
func GetAddresses(p *Info, kubeClient *kubernetes.Clientset) ([]string, error) {
addrs := []string{}
// get information about all the pods running the ingress controller
pods, err := kubeClient.CoreV1().Pods(p.Namespace).List(metav1.ListOptions{
LabelSelector: labels.SelectorFromSet(p.Labels).String(),
})
if err != nil {
return nil, err
}
for _, pod := range pods.Items {
// only Running pods are valid
if pod.Status.Phase != apiv1.PodRunning {
continue
}
name := GetNodeIPOrName(kubeClient, pod.Spec.NodeName, true)
if !sliceutils.StringInSlice(name, addrs) {
addrs = append(addrs, name)
}
}
return addrs, nil
}
// GetNodeIPOrName returns the IP address or the name of a node in the cluster
func GetNodeIPOrName(kubeClient *kubernetes.Clientset, name string, useInternalIP bool) string {
node, err := kubeClient.CoreV1().Nodes().Get(name, metav1.GetOptions{})
if err != nil {
klog.Errorf("Error getting node %v: %v", name, err)
return ""
}
if useInternalIP {
for _, address := range node.Status.Addresses {
if address.Type == apiv1.NodeInternalIP {
if address.Address != "" {
return address.Address
}
}
}
}
for _, address := range node.Status.Addresses {
if address.Type == apiv1.NodeExternalIP {
if address.Address != "" {
return address.Address
}
}
}
return ""
}
// GetPodDetails returns runtime information about the pod:
// name, namespace and IP of the node where it is running
func GetPodDetails(kubeClient *kubernetes.Clientset) (*Info, error) {
podName := os.Getenv("POD_NAME")
podNs := os.Getenv("POD_NAMESPACE")
if podName == "" || podNs == "" {
return nil, fmt.Errorf("unable to get POD information (missing POD_NAME or POD_NAMESPACE environment variable")
}
pod, _ := kubeClient.CoreV1().Pods(podNs).Get(podName, metav1.GetOptions{})
if pod == nil {
return nil, fmt.Errorf("unable to get POD information")
}
return &Info{
Name: podName,
Namespace: podNs,
Labels: pod.GetLabels(),
}, nil
}