Skip to content

Commit

Permalink
Merge pull request #207 from grycap/dev-slangarita
Browse files Browse the repository at this point in the history
Added functionality to expose OSCAR services on a specific port
  • Loading branch information
catttam authored Jul 26, 2023
2 parents edc9611 + f3b3c13 commit d26f8e0
Show file tree
Hide file tree
Showing 7 changed files with 575 additions and 7 deletions.
45 changes: 43 additions & 2 deletions pkg/backends/k8s.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ import (
"github.com/goccy/go-yaml"
"github.com/grycap/oscar/v2/pkg/imagepuller"
"github.com/grycap/oscar/v2/pkg/types"
"github.com/grycap/oscar/v2/pkg/utils"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
Expand Down Expand Up @@ -112,7 +113,23 @@ func (k *KubeBackend) CreateService(service types.Service) error {
}
return err
}

//Create an expose service
if service.ExposeOptions.MaxReplicas != 0 {
exposeConf := utils.Expose{
Name: service.Name,
NameSpace: k.namespace,
Variables: service.Environment.Vars,
Image: service.Image,
MaxReplicas: service.ExposeOptions.MaxReplicas,
}
if service.ExposeOptions.Port != 0 {
exposeConf.Port = service.ExposeOptions.Port
}
if service.ExposeOptions.TopCPU != 0 {
exposeConf.TopCPU = service.ExposeOptions.TopCPU
}
utils.CreateExpose(exposeConf, k.kubeClientset, *k.config)
}
//Create deaemonset to cache the service image on all the nodes
if service.ImagePrefetch {
err = imagepuller.CreateDaemonset(k.config, service, k.kubeClientset)
Expand Down Expand Up @@ -187,6 +204,24 @@ func (k *KubeBackend) UpdateService(service types.Service) error {
return err
}

//Update an expose service
if service.ExposeOptions.MaxReplicas != 0 {
exposeConf := utils.Expose{
Name: service.Name,
NameSpace: k.namespace,
Variables: service.Environment.Vars,
Image: service.Image,
MaxReplicas: service.ExposeOptions.MaxReplicas,
}
if service.ExposeOptions.Port != 0 {
exposeConf.Port = service.ExposeOptions.Port
}
if service.ExposeOptions.TopCPU != 0 {
exposeConf.TopCPU = service.ExposeOptions.TopCPU
}
utils.UpdateExpose(exposeConf, k.kubeClientset)
}

return nil
}

Expand All @@ -205,7 +240,13 @@ func (k *KubeBackend) DeleteService(name string) error {
if err := deleteServiceJobs(name, k.namespace, k.kubeClientset); err != nil {
log.Printf("Error deleting associated jobs for service \"%s\": %v\n", name, err)
}

exposeConf := utils.Expose{
Name: name,
NameSpace: k.namespace,
}
if err2 := utils.DeleteExpose(exposeConf, k.kubeClientset); err2 != nil {
log.Printf("Error deleting all associated kubernetes component of an exposed service \"%s\": %v\n", name, err2)
}
return nil
}

Expand Down
45 changes: 45 additions & 0 deletions pkg/backends/knative.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ import (

"github.com/grycap/oscar/v2/pkg/imagepuller"
"github.com/grycap/oscar/v2/pkg/types"
"github.com/grycap/oscar/v2/pkg/utils"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/kubernetes"
"k8s.io/client-go/rest"
Expand Down Expand Up @@ -119,6 +120,24 @@ func (kn *KnativeBackend) CreateService(service types.Service) error {
return err
}

//Create an expose service
if service.ExposeOptions.MaxReplicas != 0 {
exposeConf := utils.Expose{
Name: service.Name,
NameSpace: kn.namespace,
Variables: service.Environment.Vars,
Image: service.Image,
MaxReplicas: service.ExposeOptions.MaxReplicas,
}
if service.ExposeOptions.Port != 0 {
exposeConf.Port = service.ExposeOptions.Port
}
if service.ExposeOptions.TopCPU != 0 {
exposeConf.TopCPU = service.ExposeOptions.TopCPU
}
utils.CreateExpose(exposeConf, kn.kubeClientset, *kn.config)

}
//Create deaemonset to cache the service image on all the nodes
if service.ImagePrefetch {
err = imagepuller.CreateDaemonset(kn.config, service, kn.kubeClientset)
Expand Down Expand Up @@ -195,6 +214,24 @@ func (kn *KnativeBackend) UpdateService(service types.Service) error {
return err
}

//Update an expose service
if service.ExposeOptions.MaxReplicas != 0 {
exposeConf := utils.Expose{
Name: service.Name,
NameSpace: kn.namespace,
Variables: service.Environment.Vars,
Image: service.Image,
MaxReplicas: service.ExposeOptions.MaxReplicas,
}
if service.ExposeOptions.Port != 0 {
exposeConf.Port = service.ExposeOptions.Port
}
if service.ExposeOptions.TopCPU != 0 {
exposeConf.TopCPU = service.ExposeOptions.TopCPU
}
utils.UpdateExpose(exposeConf, kn.kubeClientset)
}

return nil
}

Expand All @@ -213,6 +250,14 @@ func (kn *KnativeBackend) DeleteService(name string) error {
if err := deleteServiceJobs(name, kn.namespace, kn.kubeClientset); err != nil {
log.Printf("Error deleting associated jobs for service \"%s\": %v\n", name, err)
}
exposeConf := utils.Expose{
Name: name,
NameSpace: kn.namespace,
Image: "service.Image",
}
if err2 := utils.DeleteExpose(exposeConf, kn.kubeClientset); err2 != nil {
log.Printf("Error deleting all associated kubernetes component of an exposed service \"%s\": %v\n", name, err2)
}

return nil
}
Expand Down
1 change: 0 additions & 1 deletion pkg/imagepuller/daemonset.go
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,6 @@ func watchPods(kubeClientset kubernetes.Interface, cfg *types.Config) {
sharedInformerOp := informers.WithTweakListOptions(optionsFunc)

factory := informers.NewSharedInformerFactoryWithOptions(kubeClientset, 2*time.Second, informers.WithNamespace(cfg.ServicesNamespace), sharedInformerOp)
//factory := informers.NewSharedInformerFactory(kubeClientset, 2*time.Second)

podInformer := factory.Core().V1().Pods().Informer()
factory.Start(stopper)
Expand Down
4 changes: 4 additions & 0 deletions pkg/types/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -175,6 +175,9 @@ type Config struct {
// Groups defined in the "eduperson_entitlement" OIDC scope,
// as described here: https://docs.egi.eu/providers/check-in/sp/#10-groups
OIDCGroups []string `json:"-"`

//
IngressHost string `json:"-"`
}

var configVars = []configVar{
Expand Down Expand Up @@ -219,6 +222,7 @@ var configVars = []configVar{
{"OIDCIssuer", "OIDC_ISSUER", false, stringType, "https://aai.egi.eu/oidc/"},
{"OIDCSubject", "OIDC_SUBJECT", false, stringType, ""},
{"OIDCGroups", "OIDC_GROUPS", false, stringSliceType, ""},
{"IngressHost", "INGRESS_HOST", false, stringType, ""},
}

func readConfigVar(cfgVar configVar) (string, error) {
Expand Down
10 changes: 8 additions & 2 deletions pkg/types/service.go
Original file line number Diff line number Diff line change
Expand Up @@ -202,6 +202,12 @@ type Service struct {
// Optional
ImagePullSecrets []string `json:"image_pull_secrets,omitempty"`

ExposeOptions struct {
MaxReplicas int `json:"max_replicas" `
Port int `json:"port" `
TopCPU int32 `json:"top_cpu" `
} `json:"expose_options"`

// The user-defined environment variables assigned to the service
// Optional
Environment struct {
Expand Down Expand Up @@ -240,7 +246,7 @@ func (service *Service) ToPodSpec(cfg *Config) (*v1.PodSpec, error) {
{
Name: ContainerName,
Image: service.Image,
Env: convertEnvVars(service.Environment.Vars),
Env: ConvertEnvVars(service.Environment.Vars),
VolumeMounts: []v1.VolumeMount{
{
Name: VolumeName,
Expand Down Expand Up @@ -299,7 +305,7 @@ func (service *Service) GetMinIOWebhookARN() string {
return fmt.Sprintf("arn:minio:sqs:%s:%s:webhook", service.StorageProviders.MinIO[DefaultProvider].Region, service.Name)
}

func convertEnvVars(vars map[string]string) []v1.EnvVar {
func ConvertEnvVars(vars map[string]string) []v1.EnvVar {
envVars := []v1.EnvVar{}
for k, v := range vars {
envVars = append(envVars, v1.EnvVar{
Expand Down
8 changes: 6 additions & 2 deletions pkg/types/service_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -187,7 +187,7 @@ func TestConvertEnvVars(t *testing.T) {
{Name: "TEST", Value: "test"},
}

res := convertEnvVars(vars)
res := ConvertEnvVars(vars)

if res[0].Name != expected[0].Name && res[0].Value != expected[0].Value {
t.Errorf("invalid conversion of environment variables. Expected: %v, got %v", expected, res)
Expand Down Expand Up @@ -240,6 +240,10 @@ script: testscript
image_pull_secrets:
- testcred1
- testcred2
expose_options:
max_replicas: 0
port: 0
top_cpu: 0
environment:
Variables:
TEST_VAR: testvalue
Expand Down Expand Up @@ -345,7 +349,7 @@ func checkEnvVars(cfg *Config, podSpec *v1.PodSpec) error {
case "max_inflight":
expected = strconv.Itoa(cfg.WatchdogMaxInflight)
if envVar.Value != expected {
return fmt.Errorf("the max_inflight environment variable has not the correct value. Expected: %s, got: %s", expected, envVar.Value)
return fmt.Errorf("componenteax_inflight environment variable has not the correct value. Expected: %s, got: %s", expected, envVar.Value)
}
case "write_debug":
expected = strconv.FormatBool(cfg.WatchdogWriteDebug)
Expand Down
Loading

0 comments on commit d26f8e0

Please sign in to comment.