diff --git a/build/cd/deploy.go b/build/cd/deploy.go index a27d1e323184a952258040bd83d4af0c210bd7ad..e82a1231ca8bbe2a4371bcf08c41cd49899431b1 100644 --- a/build/cd/deploy.go +++ b/build/cd/deploy.go @@ -3,18 +3,20 @@ package main import ( "code.fbi.h-da.de/cocsn/gosdn/nucleus" "context" + log "github.com/sirupsen/logrus" appv1 "k8s.io/api/apps/v1" corev1 "k8s.io/api/core/v1" + netv1 "k8s.io/api/networking/v1beta1" "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/intstr" "k8s.io/client-go/kubernetes" "k8s.io/client-go/tools/clientcmd" - "log" "os" ) func main() { + log.SetFormatter(&log.JSONFormatter{}) kubeconfig, err := clientcmd.BuildConfigFromFlags("https://api.ocp.fbi.h-da.de:6443", "") if err != nil { log.Fatal(err) @@ -33,35 +35,27 @@ func main() { default: tag = os.Getenv("CI_COMMIT_SHA") } - env := "gosdn-" + tag - service := createService(env) - config := createConfigMap(env) - deployment := createDeployment(env, tag) + switch os.Getenv("K8S_OP") { case "create": - if err := create(clientset, service, config, deployment, env); err != nil { - log.Println(err) + if err := create(clientset, tag); err != nil { + log.Fatal(err) } case "delete": - if err := remove(clientset, env); err != nil { - log.Println(err) - } - case "update": - if err := update(clientset, service, env); err != nil { - log.Println(err) - } - if err := update(clientset, config, env); err != nil { - log.Println(err) - } - if err := update(clientset, deployment, env); err != nil { - log.Println(err) + if err := remove(clientset, tag); err != nil { + log.Fatal(err) } default: log.Fatal("invalid option") } } -func create(clientset *kubernetes.Clientset, service *corev1.Service, config *corev1.ConfigMap, deployment *appv1.Deployment, env string) error { +func create(clientset *kubernetes.Clientset, tag string) error { + env := "gosdn-" + tag + service := createService(env) + ingress := createIngress(env) + config := createConfigMap(env) + deployment := createDeployment(env, tag) opts := metav1.CreateOptions{} ctx := context.Background() _, err := clientset.CoreV1().Services("cocsn").Create(ctx, service, opts) @@ -69,35 +63,70 @@ func create(clientset *kubernetes.Clientset, service *corev1.Service, config *co switch err.(type) { case *errors.StatusError: if err.(*errors.StatusError).ErrStatus.Code == 409 { - err = update(clientset, service, env) + if err := update(clientset, service, env); err != nil { + return err + } + } else { + log.Error(err) } default: - return err + log.Error(err) } + } else { + log.Printf("service %v created", service.Name) + } + _, err = clientset.NetworkingV1beta1().Ingresses("cocsn").Create(ctx, ingress, opts) + if err != nil { + switch err.(type) { + case *errors.StatusError: + if err.(*errors.StatusError).ErrStatus.Code == 409 { + if err := update(clientset, ingress, env); err != nil { + log.Error(err) + } + } else { + log.Error(err) + } + default: + log.Error(err) + } + } else { + log.Printf("ingress %v created", ingress.Name) } _, err = clientset.CoreV1().ConfigMaps("cocsn").Create(ctx, config, opts) if err != nil { switch err.(type) { case *errors.StatusError: if err.(*errors.StatusError).ErrStatus.Code == 409 { - err = update(clientset, config, env) + if err := update(clientset, config, env); err != nil { + log.Error(err) + } + } else { + log.Error(err) } default: - return err + log.Error(err) } + } else { + log.Printf("configMap %v created", config.Name) } _, err = clientset.AppsV1().Deployments("cocsn").Create(ctx, deployment, opts) if err != nil { switch err.(type) { case *errors.StatusError: if err.(*errors.StatusError).ErrStatus.Code == 409 { - err = update(clientset, deployment, env) + if err := update(clientset, deployment, env); err != nil { + log.Error(err) + } + } else { + log.Error(err) } default: - return err + log.Error(err) } + } else { + log.Printf("deployment %v created", deployment.Name) } - return err + return nil } func update(clientset *kubernetes.Clientset, resource metav1.Common, env string) error { @@ -116,6 +145,19 @@ func update(clientset *kubernetes.Clientset, resource metav1.Common, env string) if err != nil { return err } + log.Printf("service %v updated", service.Name) + case *netv1.Ingress: + ingress := resource.(*netv1.Ingress) + i, err := clientset.NetworkingV1beta1().Ingresses("cocsn").Get(ctx, env, getOpts) + if err != nil { + return err + } + i.DeepCopyInto(ingress) + _, err = clientset.NetworkingV1beta1().Ingresses("cocsn").Update(ctx, ingress, opts) + if err != nil { + return err + } + log.Printf("ingress %v updated", ingress.Name) case *corev1.ConfigMap: config := resource.(*corev1.ConfigMap) c, err := clientset.CoreV1().ConfigMaps("cocsn").Get(ctx, env+"-config", getOpts) @@ -127,6 +169,7 @@ func update(clientset *kubernetes.Clientset, resource metav1.Common, env string) if err != nil { return err } + log.Printf("configMap %v updated", config.Name) case *appv1.Deployment: deployment := resource.(*appv1.Deployment) d, err := clientset.AppsV1().Deployments("cocsn").Get(ctx, env, getOpts) @@ -138,26 +181,40 @@ func update(clientset *kubernetes.Clientset, resource metav1.Common, env string) if err != nil { return err } + log.Printf("deployment %v updated", deployment.Name) default: return &nucleus.ErrInvalidParameters{} } return nil } -func remove(clientset *kubernetes.Clientset, env string) error { +func remove(clientset *kubernetes.Clientset, tag string) error { + env := "gosdn-" + tag opts := metav1.DeleteOptions{} ctx := context.Background() err := clientset.CoreV1().Services("cocsn").Delete(ctx, env, opts) if err != nil { - log.Println(err) + log.Error(err) + } else { + log.Printf("service %v deleted", env) } err = clientset.CoreV1().ConfigMaps("cocsn").Delete(ctx, env+"-config", opts) if err != nil { - log.Println(err) + log.Error(err) + } else { + log.Printf("config %v deleted", env+"-config") } err = clientset.AppsV1().Deployments("cocsn").Delete(ctx, env, opts) if err != nil { - log.Println(err) + log.Error(err) + } else { + log.Printf("deployment %v deleted", env) + } + err = clientset.NetworkingV1beta1().Ingresses("cocsn").Delete(ctx, env, opts) + if err != nil { + log.Error(err) + } else { + log.Printf("ingress %v deleted", env) } return err } @@ -294,3 +351,37 @@ func createConfigMap(env string) *corev1.ConfigMap { Data: map[string]string{"gosdn.toml": "#empty"}, } } + +func createIngress(env string) *netv1.Ingress { + return &netv1.Ingress{ + TypeMeta: metav1.TypeMeta{ + Kind: "Ingress", + APIVersion: "v1", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: env, + Namespace: "cocsn", + }, + Spec: netv1.IngressSpec{ + Rules: []netv1.IngressRule{ + { + Host: env + ".apps.ocp.fbi.h-da.de", + IngressRuleValue: netv1.IngressRuleValue{ + HTTP: &netv1.HTTPIngressRuleValue{ + Paths: []netv1.HTTPIngressPath{ + { + Path: "/api", + Backend: netv1.IngressBackend{ + ServiceName: env, + ServicePort: intstr.IntOrString{IntVal: 8080}, + }, + }, + }, + }, + }, + }, + }, + }, + Status: netv1.IngressStatus{}, + } +} diff --git a/build/ci/.deploy-k8s.yml b/build/ci/.deploy-k8s.yml index 233052c21dfc216ae7802cb02126ec5a6b9583c7..220e5e93b9183afdbd86f9f76f16e2ed3f5cef46 100644 --- a/build/ci/.deploy-k8s.yml +++ b/build/ci/.deploy-k8s.yml @@ -67,4 +67,5 @@ k8s:destroy: - ./build/cd/k8s-bot needs: - job: "deploy:integration-test" + - job: "build:k8s-bot" artifacts: true \ No newline at end of file diff --git a/build/ci/.test.yml b/build/ci/.test.yml index 2793f91ec4b968ac4da1001d8d082ca7bc4c699c..5970db14de6c93482e613c802c623bbc2a320c0d 100644 --- a/build/ci/.test.yml +++ b/build/ci/.test.yml @@ -1,16 +1,16 @@ integration-test: image: golang:1.14 stage: integration-test - needs: [ "apply" ] + needs: + - job: "apply" + - job: "deploy:integration-test" variables: GOSDN_LOG: "nolog" + GOSDN_TEST_API_ENDPOINT: http://gosdn-$CI_COMMIT_SHA.apps.ocp.fbi.h-da.de/api rules: - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME == $CI_DEFAULT_BRANCH - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - if: $CI_PIPELINE_SOURCE == "merge_request_event" && $CI_MERGE_REQUEST_TARGET_BRANCH_NAME != $CI_DEFAULT_BRANCH allow_failure: true - - if: $CI_COMMIT_BRANCH == "integration-test" - allow_failure: true script: - sleep 1m - go test -race ./test/integration -v -coverprofile=coverage.out diff --git a/test/integration/cliIntegration_test.go b/test/integration/cliIntegration_test.go index 26ddc13a2afc4404a0ee62470c205006f5a58961..d2800b0e0c434d2cf8c9bf2fd6972a03ab1d0a71 100644 --- a/test/integration/cliIntegration_test.go +++ b/test/integration/cliIntegration_test.go @@ -2,15 +2,9 @@ package integration import ( "code.fbi.h-da.de/cocsn/gosdn/cli" - "os" "testing" ) -func TestMain(m *testing.M) { - testSetupIntegration() - os.Exit(m.Run()) -} - func TestCapabilities(t *testing.T) { if testing.Short() { t.Skip("skipping integration test") diff --git a/test/integration/cmdIntegration_test.go b/test/integration/cmdIntegration_test.go index d3327abb85848d115ab6d7be1b2639748358300a..0b56c9a3d8226d8ce3b7908e61e09fae2b59f161 100644 --- a/test/integration/cmdIntegration_test.go +++ b/test/integration/cmdIntegration_test.go @@ -17,12 +17,18 @@ import ( const unreachable = "203.0.113.10:6030" var testAddress = "141.100.70.171:6030" -var testAPIEndpoint = "http://141.100.70.171:8080" +var testAPIEndpoint = "http://141.100.70.171:8080/api" var testUsername = "admin" var testPassword = "arista" var defaultPath = []string{"/system/config/hostname"} var opt *nucleus.GnmiTransportOptions +func TestMain(m *testing.M) { + testSetupIntegration() + os.Exit(m.Run()) +} + + func testSetupIntegration() { if os.Getenv("GOSDN_LOG") == "nolog" { log.SetLevel(log.PanicLevel)