Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Expose service #207

Merged
merged 8 commits into from
Jul 26, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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