func PortsForRole(
	cr *kdv1.KubeDirectorCluster,
	role string,
) ([]ServicePortInfo, error) {
	appCR, err := GetApp(cr)
	if err != nil {
		return nil, err
	}
	var result []ServicePortInfo
	for _, roleService := range appCR.Spec.Config.RoleServices {
		if roleService.RoleID == role {
			for _, service := range appCR.Spec.Services {
				if shared.StringInList(service.ID, roleService.ServiceIDs) {
					if service.Endpoint.Port != nil {
						servicePortInfo := ServicePortInfo{
							ID:        service.ID,
							Port:      *(service.Endpoint.Port),
							URLScheme: service.Endpoint.URLScheme,
						}
						result = append(result, servicePortInfo)
					}
				}
			}
			break
		}
	}
	return result, nil
}
PortsForRole returns list of service port info (id and port num) for a given role.
This will be used to export those ports as NodePort/LoadBalancer
package catalog
import (
	"fmt"
	"strconv"
	"strings"
	kdv1 "github.com/bluek8s/kubedirector/pkg/apis/kubedirector/v1beta1"
	"github.com/bluek8s/kubedirector/pkg/observer"
	"github.com/bluek8s/kubedirector/pkg/shared"
	v1 "k8s.io/api/core/v1"
)
func GetServiceFromID(
	appCR *kdv1.KubeDirectorApp,
	serviceID string,
) *kdv1.Service {
	for _, serviceDef := range appCR.Spec.Services {
		if serviceDef.ID == serviceID {
			return &serviceDef
		}
	}
	return nil
}
func GetAllServiceIDs(
	appCR *kdv1.KubeDirectorApp,
) []string {
	var services []string
	for _, serviceDef := range appCR.Spec.Services {
		services = append(services, serviceDef.ID)
	}
	return services
}
func GetRoleFromID(
	appCR *kdv1.KubeDirectorApp,
	roleID string,
) *kdv1.NodeRole {
	for _, nodeRole := range appCR.Spec.NodeRoles {
		if nodeRole.ID == roleID {
			return &nodeRole
		}
	}
	return nil
}
func GetAllRoleIDs(
	appCR *kdv1.KubeDirectorApp,
) []string {
	var nodeRoles []string
	for _, nodeRole := range appCR.Spec.NodeRoles {
		nodeRoles = append(nodeRoles, nodeRole.ID)
	}
	return nodeRoles
}
func GetSelectedRoleIDs(
	appCR *kdv1.KubeDirectorApp,
) []string {
	return appCR.Spec.Config.SelectedRoles
}
func GetRoleCardinality(
	appRole *kdv1.NodeRole,
) (int32, bool) {
	var count int
	var isScaleOut = false
	if strings.HasSuffix(appRole.Cardinality, "+") {
		count, _ = strconv.Atoi(strings.Trim(appRole.Cardinality, "+"))
		isScaleOut = true
	} else {
		count, _ = strconv.Atoi(appRole.Cardinality)
	}
	return int32(count), isScaleOut
}
func GetRoleMinResources(
	appRole *kdv1.NodeRole,
) *v1.ResourceList {
	return appRole.MinResources
}