diff --git a/cmd/controller-manager/app/options/options.go b/cmd/controller-manager/app/options/options.go
index 89b3703a2497f902ef6a383a9a5e4cbcd2d9b958..7da45f1066bf09c1fae1c99b04b65880d5143ba3 100644
--- a/cmd/controller-manager/app/options/options.go
+++ b/cmd/controller-manager/app/options/options.go
@@ -7,7 +7,7 @@ import (
cliflag "k8s.io/component-base/cli/flag"
"k8s.io/klog"
kubesphereconfig "kubesphere.io/kubesphere/pkg/server/config"
- "kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
"kubesphere.io/kubesphere/pkg/simple/client/s3"
@@ -17,7 +17,7 @@ import (
type KubeSphereControllerManagerOptions struct {
KubernetesOptions *k8s.KubernetesOptions
- DevopsOptions *devops.Options
+ DevopsOptions *jenkins.Options
S3Options *s3.Options
OpenPitrixOptions *openpitrix.Options
@@ -27,7 +27,7 @@ type KubeSphereControllerManagerOptions struct {
func NewKubeSphereControllerManagerOptions() *KubeSphereControllerManagerOptions {
s := &KubeSphereControllerManagerOptions{
KubernetesOptions: k8s.NewKubernetesOptions(),
- DevopsOptions: devops.NewDevopsOptions(),
+ DevopsOptions: jenkins.NewDevopsOptions(),
S3Options: s3.NewS3Options(),
OpenPitrixOptions: openpitrix.NewOpenPitrixOptions(),
LeaderElection: &leaderelection.LeaderElectionConfig{
diff --git a/cmd/ks-apiserver/app/options/options.go b/cmd/ks-apiserver/app/options/options.go
index 66d02c95bbe3cf5633e371da2ffc207548ec1f3a..5cbcb660ae12314aaf4d64a648a5a6203174d366 100644
--- a/cmd/ks-apiserver/app/options/options.go
+++ b/cmd/ks-apiserver/app/options/options.go
@@ -5,7 +5,7 @@ import (
cliflag "k8s.io/component-base/cli/flag"
"k8s.io/klog"
genericoptions "kubesphere.io/kubesphere/pkg/server/options"
- "kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins"
esclient "kubesphere.io/kubesphere/pkg/simple/client/elasticsearch"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/mysql"
@@ -21,7 +21,7 @@ type ServerRunOptions struct {
ConfigFile string
GenericServerRunOptions *genericoptions.ServerRunOptions
KubernetesOptions *k8s.KubernetesOptions
- DevopsOptions *devops.Options
+ DevopsOptions *jenkins.Options
SonarQubeOptions *sonarqube.Options
ServiceMeshOptions *servicemesh.Options
MySQLOptions *mysql.Options
@@ -36,7 +36,7 @@ func NewServerRunOptions() *ServerRunOptions {
s := ServerRunOptions{
GenericServerRunOptions: genericoptions.NewServerRunOptions(),
KubernetesOptions: k8s.NewKubernetesOptions(),
- DevopsOptions: devops.NewDevopsOptions(),
+ DevopsOptions: jenkins.NewDevopsOptions(),
SonarQubeOptions: sonarqube.NewSonarQubeOptions(),
ServiceMeshOptions: servicemesh.NewServiceMeshOptions(),
MySQLOptions: mysql.NewMySQLOptions(),
diff --git a/go.mod b/go.mod
index e55e0cf8aa3fa694f258f4ffdde6e37ce400e63b..9cf07cb09610070377b79600797fa04ccca9b616 100644
--- a/go.mod
+++ b/go.mod
@@ -99,7 +99,7 @@ require (
k8s.io/component-base v0.17.0
k8s.io/klog v1.0.0
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a
- k8s.io/kubectl v0.17.0
+ k8s.io/utils v0.0.0-20191114184206-e782cd3c129f // indirect
kubesphere.io/im v0.1.0 // indirect
openpitrix.io/iam v0.1.0 // indirect
openpitrix.io/openpitrix v0.4.1-0.20190920134345-4d2be6e4965c
diff --git a/go.sum b/go.sum
index 3c4b61c5ea508d5e6e3ba8d7dded649a23f0f44c..40d948b7c640256695ceecead3d754294b01937f 100644
--- a/go.sum
+++ b/go.sum
@@ -18,8 +18,6 @@ github.com/Azure/go-autorest/tracing v0.5.0 h1:TRn4WjSnkcSy5AEG3pnbtFSwNtwzjr4VY
github.com/Azure/go-autorest/tracing v0.5.0/go.mod h1:r/s2XiOKccPW3HrqB+W0TQzfbtp2fGCgRFtBroKn4Dk=
github.com/BurntSushi/toml v0.3.1 h1:WXkYYl6Yr3qBf1K79EBnL4mak0OimBfB0XUf9Vl28OQ=
github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03qcyfWMU=
-github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd h1:sjQovDkwrZp8u+gxLtPgKGjk5hCxuy2hrRejBTA9xFU=
-github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
github.com/Microsoft/go-winio v0.4.12 h1:xAfWHN1IrQ0NJ9TBC0KBZoqLjzDTr1ML+4MywiUOryc=
@@ -62,8 +60,6 @@ github.com/bmizerany/assert v0.0.0-20160611221934-b7ed37b82869/go.mod h1:Ekp36dR
github.com/cenkalti/backoff v2.2.1+incompatible h1:tNowT99t7UNflLxfYYSlKYsBpXdEet03Pg2g16Swow4=
github.com/cenkalti/backoff v2.2.1+incompatible/go.mod h1:90ReRw6GdpyfrHakVjL/QHaoyV4aDUVVkXQJJJ3NXXM=
github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc=
-github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5 h1:7aWHqerlJ41y6FOsEUvknqgXnGmJyJSbjhAWq5pO4F8=
-github.com/chai2010/gettext-go v0.0.0-20160711120539-c6fed771bfd5/go.mod h1:/iP1qXHoty45bqomnu2LM+VVyAEdWN+vtSHGlQgyxbw=
github.com/cheekybits/genny v1.0.0 h1:uGGa4nei+j20rOSeDeP5Of12XVm7TGUd4dJA9RDitfE=
github.com/cheekybits/genny v1.0.0/go.mod h1:+tQajlRqAUrPI7DOSpB0XAqZYtQakVtB7wXkRAgjxjQ=
github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
@@ -81,7 +77,6 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc
github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/daviddengcn/go-colortext v0.0.0-20160507010035-511bcaf42ccd/go.mod h1:dv4zxwHi5C/8AeI+4gX4dCWOIvNi7I6JCSX0HvlKPgE=
github.com/deckarep/golang-set v1.7.1 h1:SCQV0S6gTtp6itiFrTqI+pfmJ4LN85S1YzhDf9rTHJQ=
github.com/deckarep/golang-set v1.7.1/go.mod h1:93vsz/8Wt4joVM7c2AVqh+YRMiUSc14yDtF28KmMOgQ=
github.com/denisenkom/go-mssqldb v0.0.0-20190204142019-df6d76eb9289/go.mod h1:xN/JuLBIz4bjkxNmByTiV1IbhfnYb6oo99phBn4Eqhc=
@@ -120,8 +115,6 @@ github.com/emirpasic/gods v1.12.0/go.mod h1:YfzfFFoVP/catgzJb4IKIqXjX78Ha8FMSDh3
github.com/erikstmartin/go-testdb v0.0.0-20160219214506-8d10e4a1bae5/go.mod h1:a2zkGnVExMxdzMo3M0Hi/3sEU+cWnZpSni0O6/Yb/P0=
github.com/evanphx/json-patch v4.5.0+incompatible h1:ouOWdg56aJriqS0huScTkVXPC5IcNrDCXZ6OoTAWu7M=
github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d h1:105gxyaGwCFad8crR9dcMQWvV9Hvulu6hwUh4tWPJnM=
-github.com/exponent-io/jsonpath v0.0.0-20151013193312-d6023ce2651d/go.mod h1:ZZMPRZwes7CROmyNKgQzC3XPs6L/G2EJLHddWejkmf4=
github.com/fatih/camelcase v1.0.0 h1:hxNvNX/xYBp0ovncs8WyWZrOrpBNub/JfaMvbURyft8=
github.com/fatih/camelcase v1.0.0/go.mod h1:yN2Sb0lFhZJUdVvtELVWefmrXpuZESvPmqwoZc+/fpc=
github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
@@ -198,9 +191,6 @@ github.com/golang/mock v1.2.0 h1:28o5sBqPkBsMGnC6b4MvE2TzSr5/AT4c/1fLqVGIwlk=
github.com/golang/mock v1.2.0/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/protobuf v1.3.2 h1:6nsPYzhq5kReh6QImI3k5qWzO4PEbvbIW2cwSfR/6xs=
github.com/golang/protobuf v1.3.2/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
-github.com/golangplus/bytes v0.0.0-20160111154220-45c989fe5450/go.mod h1:Bk6SMAONeMXrxql8uvOKuAZSu8aM5RUGv+1C6IJaEho=
-github.com/golangplus/fmt v0.0.0-20150411045040-2a5d6d7d2995/go.mod h1:lJgMEyOkYFkPcDKwRXegd+iM6E7matEszMG5HhwytU8=
-github.com/golangplus/testing v0.0.0-20180327235837-af21d9c3145e/go.mod h1:0AA//k/eakGydO4jKRoRL2j92ZKSzTgj9tclaCrvXHk=
github.com/google/btree v1.0.0 h1:0udJVsspx3VBr5FwtLhQQtuAsVc79tTq0ocGIPAU6qo=
github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ=
github.com/google/go-cmp v0.3.0 h1:crn/baboCvb5fXaQ0IJ1SGTsTVrWpDsCWC8EGETZijY=
@@ -296,9 +286,6 @@ github.com/leodido/go-urn v1.1.0 h1:Sm1gr51B1kKyfD2BlRcLSiEkffoG96g6TPv6eRoEiB8=
github.com/leodido/go-urn v1.1.0/go.mod h1:+cyI34gQWZcE1eQU7NVgKkkzdXDQHr1dBMtdAPozLkw=
github.com/lib/pq v1.2.0 h1:LXpIM/LZ5xGFhOpXAQUIMM1HdyqzVYM13zNdjCEEcA0=
github.com/lib/pq v1.2.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo=
-github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de h1:9TO3cAIGXtEhnIaL+V+BEER86oLrvS+kWobKpbJuye0=
-github.com/liggitt/tabwriter v0.0.0-20181228230101-89fcab3d43de/go.mod h1:zAbeS9B/r2mtpb6U+EI2rYA5OAXxsYw6wTamcNW+zcE=
-github.com/lithammer/dedent v1.1.0/go.mod h1:jrXYCQtgg0nJiN+StA2KgR7w6CiQNv9Fd/Z9BP0jIOc=
github.com/lucas-clemente/quic-go v0.11.1 h1:zasajC848Dqq/+WqfqBCkmPw+YHNe1MBts/z7y7nXf4=
github.com/lucas-clemente/quic-go v0.11.1/go.mod h1:PpMmPfPKO9nKJ/psF49ESTAGQSdfXxlg1otPbEB2nOw=
github.com/magiconair/properties v1.8.0 h1:LLgXmsheXeRoUOBOjtwPQCWIYqM/LU1ayDtDePerRcY=
@@ -323,8 +310,6 @@ github.com/miekg/dns v1.1.9 h1:OIdC9wT96RzuZMf2PfKRhFgsStHUUBZLM/lo1LqiM9E=
github.com/miekg/dns v1.1.9/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y=
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
-github.com/mitchellh/go-wordwrap v1.0.0 h1:6GlHJ/LTGMrIJbwgdqdl2eEH8o+Exx/0m8ir9Gns0u4=
-github.com/mitchellh/go-wordwrap v1.0.0/go.mod h1:ZXFpozHsX6DPmq2I0TCekCxypsnAUbP2oI0UX1GXzOo=
github.com/mitchellh/mapstructure v1.1.2 h1:fmNYVwqnSfB9mZU6OS2O6GsXM+wcskZDuKQzvN1EDeE=
github.com/mitchellh/mapstructure v1.1.2/go.mod h1:FVVH3fgwuzCH5S8UJGiWEs2h04kUh9fWfEaFds41c1Y=
github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd h1:TRLaZ9cD/w8PVh93nsPXa1VrQ6jlwL5oN8l14QlcNfg=
@@ -433,7 +418,6 @@ github.com/xanzy/ssh-agent v0.2.1 h1:TCbipTQL2JiiCprBWx9frJ2eJlCYT00NmctrHxVAr70
github.com/xanzy/ssh-agent v0.2.1/go.mod h1:mLlQY/MoOhWBj+gOGMQkOeiEvkx+8pJSI+0Bx9h2kr4=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2 h1:eY9dn8+vbi4tKz5Qo6v2eYzo7kUS51QINcR5jNpbZS8=
github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU=
-github.com/xlab/handysort v0.0.0-20150421192137-fb3537ed64a1/go.mod h1:QcJo0QPSfTONNIgpN5RA8prR7fF8nkF6cTWTcNerRO8=
github.com/xlab/treeprint v0.0.0-20180616005107-d6fb6747feb6/go.mod h1:ce1O1j6UtZfjr22oyGxGLbauSBp2YVXpARAosm7dHBg=
github.com/xordataexchange/crypt v0.0.3-0.20170626215501-b2862e3d0a77/go.mod h1:aYKd//L2LvnjZzWKhF00oedf4jCCReLcmhLdhm1A27Q=
go.etcd.io/bbolt v1.3.3 h1:MUGmc65QhB3pIlaQ5bB4LwqSj6GIonVJXpZiaKNyaKk=
@@ -535,8 +519,6 @@ k8s.io/apimachinery v0.0.0-20191028221656-72ed19daf4bb h1:ZUNsbuPdXWrj0rZziRfCWc
k8s.io/apimachinery v0.0.0-20191028221656-72ed19daf4bb/go.mod h1:llRdnznGEAqC3DcNm6yEj472xaFVfLM7hnYofMb12tQ=
k8s.io/apiserver v0.0.0-20191114103151-9ca1dc586682 h1:+FvAOv/4JyYgZanQI8h+UW9FCmLzyEz7EZunuET6p5g=
k8s.io/apiserver v0.0.0-20191114103151-9ca1dc586682/go.mod h1:Idob8Va6/sMX5SmwPLsU0pdvFlkwxuJ5x+fXMG8NbKE=
-k8s.io/cli-runtime v0.17.0 h1:XEuStbJBHCQlEKFyTQmceDKEWOSYHZkcYWKp3SsQ9Hk=
-k8s.io/cli-runtime v0.17.0/go.mod h1:1E5iQpMODZq2lMWLUJELwRu2MLWIzwvMgDBpn3Y81Qo=
k8s.io/client-go v0.0.0-20191114101535-6c5935290e33 h1:07mhG/2oEoo3N+sHVOo0L9PJ/qvbk3N5n2dj8IWefnQ=
k8s.io/client-go v0.0.0-20191114101535-6c5935290e33/go.mod h1:4L/zQOBkEf4pArQJ+CMk1/5xjA30B5oyWv+Bzb44DOw=
k8s.io/code-generator v0.0.0-20191004115455-8e001e5d1894 h1:NMYlxaF7rYQJk2E2IyrUhaX81zX24+dmoZdkPw0gJqI=
@@ -549,9 +531,6 @@ k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a h1:UcxjrRMyNx/i/y8G7kPvLyy7rfbeuf1PYyBf973pgyU=
k8s.io/kube-openapi v0.0.0-20191107075043-30be4d16710a/go.mod h1:1TqjTSzOxsLGIKfj0lK8EeCP7K1iUG65v09OM0/WG5E=
-k8s.io/kubectl v0.17.0 h1:xD4EWlL+epc/JTO1gvSjmV9yiYF0Z2wiHK2DIek6URY=
-k8s.io/kubectl v0.17.0/go.mod h1:jIPrUAW656Vzn9wZCCe0PC+oTcu56u2HgFD21Xbfk1s=
-k8s.io/metrics v0.17.0/go.mod h1:EH1D3YAwN6d7bMelrElnLhLg72l/ERStyv2SIQVt6Do=
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f h1:GiPwtSzdP43eI1hpPCbROQCCIgCuiMMNF8YUVLF3vJo=
k8s.io/utils v0.0.0-20191114184206-e782cd3c129f/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
kubesphere.io/application v0.0.0-20190404151855-67ae7f915d4e/go.mod h1:NhUQ0ZUdFz8NTQ+SvQG0JUKAn+q71v3TPExjsjRPIZI=
@@ -572,13 +551,9 @@ sigs.k8s.io/controller-runtime v0.4.0 h1:wATM6/m+3w8lj8FXNaO6Fs/rq/vqoOjO1Q116Z9
sigs.k8s.io/controller-runtime v0.4.0/go.mod h1:ApC79lpY3PHW9xj/w9pj+lYkLgwAAUZwfXkME1Lajns=
sigs.k8s.io/controller-tools v0.2.4 h1:la1h46EzElvWefWLqfsXrnsO3lZjpkI0asTpX6h8PLA=
sigs.k8s.io/controller-tools v0.2.4/go.mod h1:m/ztfQNocGYBgTTCmFdnK94uVvgxeZeE3LtJvd/jIzA=
-sigs.k8s.io/kustomize v2.0.3+incompatible h1:JUufWFNlI44MdtnjUqVnvh29rR37PQFzPbLXqhyOyX0=
-sigs.k8s.io/kustomize v2.0.3+incompatible/go.mod h1:MkjgH3RdOWrievjo6c9T245dYlB5QeXV4WCbnt/PEpU=
sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca h1:6dsH6AYQWbyZmtttJNe8Gq1cXOeS1BdV3eW37zHilAQ=
sigs.k8s.io/structured-merge-diff v0.0.0-20190817042607-6149e4549fca/go.mod h1:IIgPezJWb76P0hotTxzDbWsMYB8APh18qZnxkomBpxA=
sigs.k8s.io/testing_frameworks v0.1.2 h1:vK0+tvjF0BZ/RYFeZ1E6BYBwHJJXhjuZ3TdsEKH+UQM=
sigs.k8s.io/testing_frameworks v0.1.2/go.mod h1:ToQrwSC3s8Xf/lADdZp3Mktcql9CG0UAmdJG9th5i0w=
sigs.k8s.io/yaml v1.1.0 h1:4A07+ZFc2wgJwo8YNlQpr1rVlgUDlxXHhPJciaPY5gs=
sigs.k8s.io/yaml v1.1.0/go.mod h1:UJmg0vDUVViEyp3mgSv9WPwZCDxu4rQW1olrI1uml+o=
-vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc h1:MksmcCZQWAQJCTA5T0jgI/0sJ51AVm4Z41MrmfczEoc=
-vbom.ml/util v0.0.0-20160121211510-db5cfe13f5cc/go.mod h1:so/NYdZXCz+E3ZpW0uAoCj6uzU2+8OWDFv/HxUSs7kI=
diff --git a/pkg/apis/logging/v1alpha2/fluentbit_types.go b/pkg/apis/logging/v1alpha2/fluentbit_types.go
index cef27969cda71e1c080b12d808cb3e92aed41ffb..440d85dfffd1b46b36c39ebc60f5aa3f53a3370a 100644
--- a/pkg/apis/logging/v1alpha2/fluentbit_types.go
+++ b/pkg/apis/logging/v1alpha2/fluentbit_types.go
@@ -70,9 +70,8 @@ type FluentBitList struct {
Items []FluentBit `json:"items"`
}
-
type FluentbitOutputsResult struct {
- Status int `json:"status" description:"response status"`
- Error string `json:"error,omitempty" description:"debug information"`
+ Status int `json:"status" description:"response status"`
+ Error string `json:"error,omitempty" description:"debug information"`
Outputs []OutputPlugin `json:"outputs,omitempty" description:"array of fluent bit output plugins"`
-}
\ No newline at end of file
+}
diff --git a/pkg/apiserver/devops/project_credential.go b/pkg/apiserver/devops/project_credential.go
deleted file mode 100644
index 1ad032676f5a10874d5d177dfdf2f33ad6045811..0000000000000000000000000000000000000000
--- a/pkg/apiserver/devops/project_credential.go
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
-Copyright 2019 The KubeSphere Authors.
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package devops
-
-import (
- "github.com/emicklei/go-restful"
- "k8s.io/klog"
- "kubesphere.io/kubesphere/pkg/constants"
- "kubesphere.io/kubesphere/pkg/models/devops"
- "kubesphere.io/kubesphere/pkg/server/errors"
- "net/http"
-)
-
-func CreateDevOpsProjectCredentialHandler(request *restful.Request, resp *restful.Response) {
-
- projectId := request.PathParameter("devops")
- username := request.HeaderParameter(constants.UserNameHeader)
- var credential *devops.JenkinsCredential
- err := request.ReadEntity(&credential)
- if err != nil {
- klog.Errorf("%+v", err)
- errors.ParseSvcErr(restful.NewError(http.StatusBadRequest, err.Error()), resp)
- return
- }
- err = devops.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner, devops.ProjectMaintainer})
- if err != nil {
- klog.Errorf("%+v", err)
- errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
- return
- }
- credentialId, err := devops.CreateProjectCredential(projectId, username, credential)
-
- if err != nil {
- klog.Errorf("%+v", err)
- errors.ParseSvcErr(err, resp)
- return
- }
-
- resp.WriteAsJson(struct {
- Name string `json:"name"`
- }{Name: credentialId})
- return
-}
-
-func UpdateDevOpsProjectCredentialHandler(request *restful.Request, resp *restful.Response) {
-
- projectId := request.PathParameter("devops")
- username := request.HeaderParameter(constants.UserNameHeader)
- credentialId := request.PathParameter("credential")
- var credential *devops.JenkinsCredential
- err := request.ReadEntity(&credential)
- if err != nil {
- klog.Errorf("%+v", err)
- errors.ParseSvcErr(restful.NewError(http.StatusBadRequest, err.Error()), resp)
- return
- }
- err = devops.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner, devops.ProjectMaintainer})
- if err != nil {
- klog.Errorf("%+v", err)
- errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
- return
- }
- credentialId, err = devops.UpdateProjectCredential(projectId, credentialId, credential)
-
- if err != nil {
- klog.Errorf("%+v", err)
- errors.ParseSvcErr(err, resp)
- return
- }
-
- resp.WriteAsJson(struct {
- Name string `json:"name"`
- }{Name: credentialId})
- return
-}
-
-func DeleteDevOpsProjectCredentialHandler(request *restful.Request, resp *restful.Response) {
-
- projectId := request.PathParameter("devops")
- username := request.HeaderParameter(constants.UserNameHeader)
- credentialId := request.PathParameter("credential")
- var credential *devops.JenkinsCredential
- err := request.ReadEntity(&credential)
- if err != nil {
- klog.Errorf("%+v", err)
- errors.ParseSvcErr(restful.NewError(http.StatusBadRequest, err.Error()), resp)
- return
- }
- err = devops.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner, devops.ProjectMaintainer})
- if err != nil {
- klog.Errorf("%+v", err)
- errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
- return
- }
- credentialId, err = devops.DeleteProjectCredential(projectId, credentialId, credential)
-
- if err != nil {
- klog.Errorf("%+v", err)
- errors.ParseSvcErr(err, resp)
- return
- }
-
- resp.WriteAsJson(struct {
- Name string `json:"name"`
- }{Name: credentialId})
- return
-}
-
-func GetDevOpsProjectCredentialHandler(request *restful.Request, resp *restful.Response) {
-
- projectId := request.PathParameter("devops")
- username := request.HeaderParameter(constants.UserNameHeader)
- credentialId := request.PathParameter("credential")
- getContent := request.QueryParameter("content")
- domain := request.QueryParameter("domain")
-
- err := devops.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner, devops.ProjectMaintainer})
- if err != nil {
- klog.Errorf("%+v", err)
- errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
- return
- }
- response, err := devops.GetProjectCredential(projectId, credentialId, domain, getContent)
-
- if err != nil {
- klog.Errorf("%+v", err)
- errors.ParseSvcErr(err, resp)
- return
- }
-
- resp.WriteAsJson(response)
- return
-}
-
-func GetDevOpsProjectCredentialsHandler(request *restful.Request, resp *restful.Response) {
- projectId := request.PathParameter("devops")
- username := request.HeaderParameter(constants.UserNameHeader)
- domain := request.QueryParameter("domain")
-
- err := devops.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner, devops.ProjectMaintainer})
- if err != nil {
- klog.Errorf("%+v", err)
- errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
- return
- }
- jenkinsCredentials, err := devops.GetProjectCredentials(projectId, domain)
- if err != nil {
- klog.Errorf("%+v", err)
- errors.ParseSvcErr(err, resp)
- return
- }
- resp.WriteAsJson(jenkinsCredentials)
- return
-}
diff --git a/pkg/apiserver/openpitrix/attachments.go b/pkg/apiserver/openpitrix/attachments.go
new file mode 100644
index 0000000000000000000000000000000000000000..908a95df0bc787747913cc6248c0497c28d4785b
--- /dev/null
+++ b/pkg/apiserver/openpitrix/attachments.go
@@ -0,0 +1,54 @@
+/*
+ *
+ * Copyright 2019 The KubeSphere Authors.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ * /
+ */
+
+package openpitrix
+
+import (
+ "github.com/emicklei/go-restful"
+ "google.golang.org/grpc/codes"
+ "google.golang.org/grpc/status"
+ "kubesphere.io/kubesphere/pkg/models/openpitrix/attachment"
+ "kubesphere.io/kubesphere/pkg/server/errors"
+ "kubesphere.io/kubesphere/pkg/simple/client"
+ "net/http"
+)
+
+func DescribeAttachment(req *restful.Request, resp *restful.Response) {
+ attachmentId := req.PathParameter("attachment")
+ fileName := req.QueryParameter("filename")
+ result, err := attachment.DescribeAttachment(attachmentId)
+ // file raw
+ if fileName != "" {
+ data := result.AttachmentContent[fileName]
+ resp.Write(data)
+ resp.Header().Set("Content-Type", "text/plain")
+ return
+ }
+
+ if _, notEnabled := err.(client.ClientSetNotEnabledError); notEnabled {
+ resp.WriteHeaderAndEntity(http.StatusNotImplemented, errors.Wrap(err))
+ return
+ }
+
+ if status.Code(err) == codes.NotFound {
+ resp.WriteHeaderAndEntity(http.StatusNotFound, errors.Wrap(err))
+ return
+ }
+
+ resp.WriteEntity(result)
+}
diff --git a/pkg/apiserver/tenant/tenant.go b/pkg/apiserver/tenant/tenant.go
new file mode 100644
index 0000000000000000000000000000000000000000..8f6431a5447004d790e87f440c55fa8690194454
--- /dev/null
+++ b/pkg/apiserver/tenant/tenant.go
@@ -0,0 +1,328 @@
+/*
+
+ Copyright 2019 The KubeSphere Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+*/
+package tenant
+
+import (
+ "github.com/emicklei/go-restful"
+ "k8s.io/api/core/v1"
+ rbacv1 "k8s.io/api/rbac/v1"
+ k8serr "k8s.io/apimachinery/pkg/api/errors"
+ "k8s.io/apimachinery/pkg/util/net"
+ "k8s.io/klog"
+ devopsv1alpha2 "kubesphere.io/kubesphere/pkg/api/devops/v1alpha2"
+ loggingv1alpha2 "kubesphere.io/kubesphere/pkg/api/logging/v1alpha2"
+ "kubesphere.io/kubesphere/pkg/apis/tenant/v1alpha1"
+ "kubesphere.io/kubesphere/pkg/apiserver/logging"
+ "kubesphere.io/kubesphere/pkg/constants"
+ "kubesphere.io/kubesphere/pkg/models/iam"
+ "kubesphere.io/kubesphere/pkg/models/metrics"
+ "kubesphere.io/kubesphere/pkg/models/resources/v1alpha2"
+ "kubesphere.io/kubesphere/pkg/models/tenant"
+ "kubesphere.io/kubesphere/pkg/models/workspaces"
+ "kubesphere.io/kubesphere/pkg/server/errors"
+ "kubesphere.io/kubesphere/pkg/server/params"
+
+ "kubesphere.io/kubesphere/pkg/utils/sliceutil"
+ "net/http"
+ "strings"
+)
+
+func ListWorkspaceRules(req *restful.Request, resp *restful.Response) {
+ workspace := req.PathParameter("workspace")
+ username := req.HeaderParameter(constants.UserNameHeader)
+
+ rules, err := iam.GetUserWorkspaceSimpleRules(workspace, username)
+
+ if err != nil {
+ resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
+ return
+ }
+
+ resp.WriteAsJson(rules)
+}
+
+func ListWorkspaces(req *restful.Request, resp *restful.Response) {
+ username := req.HeaderParameter(constants.UserNameHeader)
+ conditions, err := params.ParseConditions(req.QueryParameter(params.ConditionsParam))
+ orderBy := req.QueryParameter(params.OrderByParam)
+ limit, offset := params.ParsePaging(req.QueryParameter(params.PagingParam))
+ reverse := params.ParseReverse(req)
+
+ if orderBy == "" {
+ orderBy = v1alpha2.CreateTime
+ reverse = true
+ }
+
+ if err != nil {
+ resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
+ return
+ }
+
+ result, err := tenant.ListWorkspaces(username, conditions, orderBy, reverse, limit, offset)
+
+ if err != nil {
+ resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
+ return
+ }
+
+ resp.WriteAsJson(result)
+}
+
+func DescribeWorkspace(req *restful.Request, resp *restful.Response) {
+ username := req.HeaderParameter(constants.UserNameHeader)
+ workspaceName := req.PathParameter("workspace")
+
+ result, err := tenant.DescribeWorkspace(username, workspaceName)
+
+ if err != nil {
+ klog.Errorf("describe workspace failed: %+v", err)
+ if k8serr.IsNotFound(err) {
+ resp.WriteHeaderAndEntity(http.StatusNotFound, errors.Wrap(err))
+ } else {
+ resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
+ }
+ return
+ }
+
+ resp.WriteAsJson(result)
+}
+func ListNamespacesByUsername(req *restful.Request, resp *restful.Response) {
+ ListNamespaces(req, resp)
+}
+
+func ListNamespaces(req *restful.Request, resp *restful.Response) {
+ workspace := req.PathParameter("workspace")
+ username := req.PathParameter("member")
+ // /workspaces/{workspace}/members/{username}/namespaces
+ if username == "" {
+ // /workspaces/{workspace}/namespaces
+ username = req.HeaderParameter(constants.UserNameHeader)
+ }
+
+ conditions, err := params.ParseConditions(req.QueryParameter(params.ConditionsParam))
+ orderBy := req.QueryParameter(params.OrderByParam)
+ limit, offset := params.ParsePaging(req.QueryParameter(params.PagingParam))
+ reverse := params.ParseReverse(req)
+
+ if err != nil {
+ resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
+ return
+ }
+
+ conditions.Match[constants.WorkspaceLabelKey] = workspace
+
+ result, err := tenant.ListNamespaces(username, conditions, orderBy, reverse, limit, offset)
+
+ if err != nil {
+ resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
+ return
+ }
+
+ namespaces := make([]*v1.Namespace, 0)
+
+ for _, item := range result.Items {
+ namespaces = append(namespaces, item.(*v1.Namespace).DeepCopy())
+ }
+
+ namespaces = metrics.GetNamespacesWithMetrics(namespaces)
+
+ items := make([]interface{}, 0)
+
+ for _, item := range namespaces {
+ items = append(items, item)
+ }
+
+ result.Items = items
+
+ resp.WriteAsJson(result)
+}
+
+func CreateNamespace(req *restful.Request, resp *restful.Response) {
+ workspaceName := req.PathParameter("workspace")
+ username := req.HeaderParameter(constants.UserNameHeader)
+ var namespace v1.Namespace
+ err := req.ReadEntity(&namespace)
+ if err != nil {
+ resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
+ return
+ }
+
+ workspace, err := tenant.GetWorkspace(workspaceName)
+
+ err = checkResourceQuotas(workspace)
+
+ if err != nil {
+ resp.WriteHeaderAndEntity(http.StatusForbidden, errors.Wrap(err))
+ return
+ }
+
+ if err != nil {
+ if k8serr.IsNotFound(err) {
+ resp.WriteHeaderAndEntity(http.StatusForbidden, errors.Wrap(err))
+ } else {
+ resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
+ }
+ return
+ }
+
+ created, err := tenant.CreateNamespace(workspaceName, &namespace, username)
+
+ if err != nil {
+ if k8serr.IsAlreadyExists(err) {
+ resp.WriteHeaderAndEntity(http.StatusConflict, err)
+ } else {
+ resp.WriteHeaderAndEntity(http.StatusInternalServerError, err)
+ }
+ return
+ }
+ resp.WriteAsJson(created)
+}
+
+func DeleteNamespace(req *restful.Request, resp *restful.Response) {
+ workspaceName := req.PathParameter("workspace")
+ namespaceName := req.PathParameter("namespace")
+
+ err := workspaces.DeleteNamespace(workspaceName, namespaceName)
+
+ if err != nil {
+ resp.WriteHeaderAndEntity(http.StatusBadRequest, errors.Wrap(err))
+ return
+ }
+
+ resp.WriteAsJson(errors.None)
+}
+
+func checkResourceQuotas(wokrspace *v1alpha1.Workspace) error {
+ return nil
+}
+
+
+func ListNamespaceRules(req *restful.Request, resp *restful.Response) {
+ namespace := req.PathParameter("namespace")
+ username := req.HeaderParameter(constants.UserNameHeader)
+
+ rules, err := iam.GetUserNamespaceSimpleRules(namespace, username)
+
+ if err != nil {
+ resp.WriteError(http.StatusInternalServerError, err)
+ return
+ }
+
+ resp.WriteAsJson(rules)
+}
+
+func LogQuery(req *restful.Request, resp *restful.Response) {
+ operation := req.QueryParameter("operation")
+ req, err := regenerateLoggingRequest(req)
+ switch {
+ case err != nil:
+ resp.WriteHeaderAndEntity(http.StatusInternalServerError, errors.Wrap(err))
+ case req != nil:
+ logging.LoggingQueryCluster(req, resp)
+ default:
+ if operation == "export" {
+ resp.Header().Set(restful.HEADER_ContentType, "text/plain")
+ resp.Header().Set("Content-Disposition", "attachment")
+ resp.Write(nil)
+ } else {
+ resp.WriteAsJson(loggingv1alpha2.QueryResult{Read: new(loggingv1alpha2.ReadResult)})
+ }
+ }
+}
+
+// override namespace query conditions
+func regenerateLoggingRequest(req *restful.Request) (*restful.Request, error) {
+
+ username := req.HeaderParameter(constants.UserNameHeader)
+
+ // regenerate the request for log query
+ newUrl := net.FormatURL("http", "127.0.0.1", 80, "/kapis/logging.kubesphere.io/v1alpha2/cluster")
+ values := req.Request.URL.Query()
+
+ clusterRules, err := iam.GetUserClusterRules(username)
+ if err != nil {
+ klog.Errorln(err)
+ return nil, err
+ }
+
+ hasClusterLogAccess := iam.RulesMatchesRequired(clusterRules, rbacv1.PolicyRule{Verbs: []string{"get"}, Resources: []string{"*"}, APIGroups: []string{"logging.kubesphere.io"}})
+ // if the user is not a cluster admin
+ if !hasClusterLogAccess {
+ queryNamespaces := strings.Split(req.QueryParameter("namespaces"), ",")
+ // then the user can only view logs of namespaces he belongs to
+ namespaces := make([]string, 0)
+ roles, err := iam.GetUserRoles("", username)
+ if err != nil {
+ klog.Errorln(err)
+ return nil, err
+ }
+ for _, role := range roles {
+ if !sliceutil.HasString(namespaces, role.Namespace) && iam.RulesMatchesRequired(role.Rules, rbacv1.PolicyRule{Verbs: []string{"get"}, Resources: []string{"*"}, APIGroups: []string{"logging.kubesphere.io"}}) {
+ namespaces = append(namespaces, role.Namespace)
+ }
+ }
+
+ // if the user belongs to no namespace
+ // then no log visible
+ if len(namespaces) == 0 {
+ return nil, nil
+ } else if len(queryNamespaces) == 1 && queryNamespaces[0] == "" {
+ values.Set("namespaces", strings.Join(namespaces, ","))
+ } else {
+ inter := intersection(queryNamespaces, namespaces)
+ if len(inter) == 0 {
+ return nil, nil
+ }
+ values.Set("namespaces", strings.Join(inter, ","))
+ }
+ }
+
+ newUrl.RawQuery = values.Encode()
+
+ // forward the request to logging model
+ newHttpRequest, _ := http.NewRequest(http.MethodGet, newUrl.String(), nil)
+ return restful.NewRequest(newHttpRequest), nil
+}
+
+func intersection(s1, s2 []string) (inter []string) {
+ hash := make(map[string]bool)
+ for _, e := range s1 {
+ hash[e] = true
+ }
+ for _, e := range s2 {
+ // If elements present in the hashmap then append intersection list.
+ if hash[e] {
+ inter = append(inter, e)
+ }
+ }
+ //Remove dups from slice.
+ inter = removeDups(inter)
+ return
+}
+
+//Remove dups from slice.
+func removeDups(elements []string) (nodups []string) {
+ encountered := make(map[string]bool)
+ for _, element := range elements {
+ if !encountered[element] {
+ nodups = append(nodups, element)
+ encountered[element] = true
+ }
+ }
+ return
+}
diff --git a/pkg/gojenkins/_tests/build_history.txt b/pkg/gojenkins/_tests/build_history.txt
deleted file mode 100644
index b9c777d37d29a85bbcc9ba69066d52e855346a2b..0000000000000000000000000000000000000000
--- a/pkg/gojenkins/_tests/build_history.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-
-
-
-
\ No newline at end of file
diff --git a/pkg/gojenkins/_tests/job.xml b/pkg/gojenkins/_tests/job.xml
deleted file mode 100644
index 76a65ec251656ecca116744c06fe62bd688c7cfa..0000000000000000000000000000000000000000
--- a/pkg/gojenkins/_tests/job.xml
+++ /dev/null
@@ -1,27 +0,0 @@
-
-
-
- Some Job Description
- false
-
-
-
-
- params1
- description
- defaultVal
-
-
-
-
-
- true
- false
- false
- false
-
- false
-
-
-
-
diff --git a/pkg/gojenkins/artifact.go b/pkg/gojenkins/artifact.go
deleted file mode 100644
index 364940656dd5a9dcebf4d763ed20f0d1dfac7e29..0000000000000000000000000000000000000000
--- a/pkg/gojenkins/artifact.go
+++ /dev/null
@@ -1,118 +0,0 @@
-// Copyright 2015 Vadim Kravcenko
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package gojenkins
-
-import (
- "crypto/md5"
- "errors"
- "fmt"
- "io"
- "io/ioutil"
- "os"
- "path"
-)
-
-// Represents an Artifact
-type Artifact struct {
- Jenkins *Jenkins
- Build *Build
- FileName string
- Path string
-}
-
-// Get raw byte data of Artifact
-func (a Artifact) GetData() ([]byte, error) {
- var data string
- response, err := a.Jenkins.Requester.Get(a.Path, &data, nil)
-
- if err != nil {
- return nil, err
- }
-
- code := response.StatusCode
- if code != 200 {
- Error.Printf("Jenkins responded with StatusCode: %d", code)
- return nil, errors.New("Could not get File Contents")
- }
- return []byte(data), nil
-}
-
-// Save artifact to a specific path, using your own filename.
-func (a Artifact) Save(path string) (bool, error) {
- data, err := a.GetData()
-
- if err != nil {
- return false, errors.New("No Data received, not saving file.")
- }
-
- if _, err = os.Stat(path); err == nil {
- Warning.Println("Local Copy already exists, Overwriting...")
- }
-
- err = ioutil.WriteFile(path, data, 0644)
- a.validateDownload(path)
-
- if err != nil {
- return false, err
- }
- return true, nil
-}
-
-// Save Artifact to directory using Artifact filename.
-func (a Artifact) SaveToDir(dir string) (bool, error) {
- if _, err := os.Stat(dir); err != nil {
- Error.Printf("can't save artifact: directory %s does not exist", dir)
- return false, fmt.Errorf("can't save artifact: directory %s does not exist", dir)
- }
- saved, err := a.Save(path.Join(dir, a.FileName))
- if err != nil {
- return saved, nil
- }
- return saved, nil
-}
-
-// Compare Remote and local MD5
-func (a Artifact) validateDownload(path string) (bool, error) {
- localHash := a.getMD5local(path)
-
- fp := FingerPrint{Jenkins: a.Jenkins, Base: "/fingerprint/", Id: localHash, Raw: new(FingerPrintResponse)}
-
- valid, err := fp.ValidateForBuild(a.FileName, a.Build)
-
- if err != nil {
- return false, err
- }
- if !valid {
- return false, errors.New("FingerPrint of the downloaded artifact could not be verified")
- }
- return true, nil
-}
-
-// Get Local MD5
-func (a Artifact) getMD5local(path string) string {
- h := md5.New()
- localFile, err := os.Open(path)
- if err != nil {
- return ""
- }
- buffer := make([]byte, 2^20)
- n, err := localFile.Read(buffer)
- defer localFile.Close()
- for err == nil {
- io.WriteString(h, string(buffer[0:n]))
- n, err = localFile.Read(buffer)
- }
- return fmt.Sprintf("%x", h.Sum(nil))
-}
diff --git a/pkg/gojenkins/build_history.go b/pkg/gojenkins/build_history.go
deleted file mode 100644
index 2e7cae1179d81ab1991f7da2d76bccd1e0900b26..0000000000000000000000000000000000000000
--- a/pkg/gojenkins/build_history.go
+++ /dev/null
@@ -1,109 +0,0 @@
-package gojenkins
-
-import (
- "io"
- "strconv"
- "strings"
-
- "golang.org/x/net/html"
-)
-
-// Parse jenkins ajax response in order find the current jenkins build history
-func parseBuildHistory(d io.Reader) []*History {
- z := html.NewTokenizer(d)
- depth := 0
- buildRowCellDepth := -1
- builds := make([]*History, 0)
- var curBuild *History
- for {
- tt := z.Next()
- switch tt {
- case html.ErrorToken:
- if z.Err() == io.EOF {
- return builds
- }
- case html.SelfClosingTagToken:
- tn, hasAttr := z.TagName()
- // fmt.Println("START__", string(tn), hasAttr)
- if hasAttr {
- a := attr(z)
- //
- if string(tn) == "img" {
- if hasCSSClass(a, "icon-sm") && buildRowCellDepth > -1 {
- if alt, found := a["alt"]; found {
- curBuild.BuildStatus = strings.Fields(alt)[0]
- }
- }
- }
- }
- case html.StartTagToken:
- depth++
- tn, hasAttr := z.TagName()
- // fmt.Println("START__", string(tn), hasAttr)
- if hasAttr {
- a := attr(z)
- //
- if string(tn) == "td" {
- if hasCSSClass(a, "build-row-cell") {
- buildRowCellDepth = depth
- curBuild = &History{}
- builds = append(builds, curBuild)
- }
- }
- // #227
- if string(tn) == "a" {
- if hasCSSClass(a, "build-link") && buildRowCellDepth > -1 {
- if href, found := a["href"]; found {
- parts := strings.Split(href, "/")
- if num, err := strconv.Atoi(parts[len(parts)-2]); err == nil {
- curBuild.BuildNumber = num
- }
- }
- }
- }
- // ...
- if string(tn) == "div" {
- if hasCSSClass(a, "build-details") && buildRowCellDepth > -1 {
- if t, found := a["time"]; found {
- if msec, err := strconv.ParseInt(t, 10, 0); err == nil {
- curBuild.BuildTimestamp = msec / 1000
- }
- }
- }
- }
- }
- case html.EndTagToken:
- tn, _ := z.TagName()
- if string(tn) == "td" && depth == buildRowCellDepth {
- buildRowCellDepth = -1
- curBuild = nil
- }
- depth--
- }
- }
-}
-
-func attr(z *html.Tokenizer) map[string]string {
- a := make(map[string]string)
- for {
- k, v, more := z.TagAttr()
- if k != nil && v != nil {
- a[string(k)] = string(v)
- }
- if !more {
- break
- }
- }
- return a
-}
-
-func hasCSSClass(a map[string]string, className string) bool {
- if classes, found := a["class"]; found {
- for _, class := range strings.Fields(classes) {
- if class == className {
- return true
- }
- }
- }
- return false
-}
diff --git a/pkg/gojenkins/credential.go b/pkg/gojenkins/credential.go
deleted file mode 100644
index da41bb908627d9a732e6714f65b2696ceba48d74..0000000000000000000000000000000000000000
--- a/pkg/gojenkins/credential.go
+++ /dev/null
@@ -1,225 +0,0 @@
-/*
-Copyright 2018 The KubeSphere Authors.
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package gojenkins
-
-const SSHCrenditalStaplerClass = "com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey"
-const DirectSSHCrenditalStaplerClass = "com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey$DirectEntryPrivateKeySource"
-const UsernamePassswordCredentialStaplerClass = "com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl"
-const SecretTextCredentialStaplerClass = "org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl"
-const KubeconfigCredentialStaplerClass = "com.microsoft.jenkins.kubernetes.credentials.KubeconfigCredentials"
-const DirectKubeconfigCredentialStaperClass = "com.microsoft.jenkins.kubernetes.credentials.KubeconfigCredentials$DirectEntryKubeconfigSource"
-const GLOBALScope = "GLOBAL"
-
-type CreateSshCredentialRequest struct {
- Credentials SshCredential `json:"credentials"`
-}
-
-type CreateUsernamePasswordCredentialRequest struct {
- Credentials UsernamePasswordCredential `json:"credentials"`
-}
-
-type CreateSecretTextCredentialRequest struct {
- Credentials SecretTextCredential `json:"credentials"`
-}
-
-type CreateKubeconfigCredentialRequest struct {
- Credentials KubeconfigCredential `json:"credentials"`
-}
-
-type UsernamePasswordCredential struct {
- Scope string `json:"scope"`
- Id string `json:"id"`
- Username string `json:"username"`
- Password string `json:"password"`
- Description string `json:"description"`
- StaplerClass string `json:"stapler-class"`
-}
-
-type SshCredential struct {
- Scope string `json:"scope"`
- Id string `json:"id"`
- Username string `json:"username"`
- Passphrase string `json:"passphrase"`
- KeySource PrivateKeySource `json:"privateKeySource"`
- Description string `json:"description"`
- StaplerClass string `json:"stapler-class"`
-}
-
-type SecretTextCredential struct {
- Scope string `json:"scope"`
- Id string `json:"id"`
- Secret string `json:"secret"`
- Description string `json:"description"`
- StaplerClass string `json:"stapler-class"`
-}
-
-type KubeconfigCredential struct {
- Scope string `json:"scope"`
- Id string `json:"id"`
- Description string `json:"description"`
- KubeconfigSource KubeconfigSource `json:"kubeconfigSource"`
- StaplerClass string `json:"stapler-class"`
-}
-
-type PrivateKeySource struct {
- StaplerClass string `json:"stapler-class"`
- PrivateKey string `json:"privateKey"`
-}
-
-type KubeconfigSource struct {
- StaplerClass string `json:"stapler-class"`
- Content string `json:"content"`
-}
-
-type CredentialResponse struct {
- Id string `json:"id"`
- TypeName string `json:"typeName"`
- DisplayName string `json:"displayName"`
- Fingerprint *struct {
- FileName string `json:"file_name,omitempty" description:"Credential's display name and description"`
- Hash string `json:"hash,omitempty" description:"Credential's hash"`
- Usage []*struct {
- Name string `json:"name,omitempty" description:"Jenkins pipeline full name"`
- Ranges struct {
- Ranges []*struct {
- Start int `json:"start,omitempty" description:"Start build number"`
- End int `json:"end,omitempty" description:"End build number"`
- } `json:"ranges,omitempty"`
- } `json:"ranges,omitempty" description:"The build number of all pipelines that use this credential"`
- } `json:"usage,omitempty" description:"all usage of Credential"`
- } `json:"fingerprint,omitempty" description:"usage of the Credential"`
- Description string `json:"description,omitempty"`
- Domain string `json:"domain"`
-}
-
-func NewCreateSshCredentialRequest(id, username, passphrase, privateKey, description string) *CreateSshCredentialRequest {
-
- keySource := PrivateKeySource{
- StaplerClass: DirectSSHCrenditalStaplerClass,
- PrivateKey: privateKey,
- }
-
- sshCredential := SshCredential{
- Scope: GLOBALScope,
- Id: id,
- Username: username,
- Passphrase: passphrase,
- KeySource: keySource,
- Description: description,
- StaplerClass: SSHCrenditalStaplerClass,
- }
- return &CreateSshCredentialRequest{
- Credentials: sshCredential,
- }
-
-}
-
-func NewCreateUsernamePasswordRequest(id, username, password, description string) *CreateUsernamePasswordCredentialRequest {
- credential := UsernamePasswordCredential{
- Scope: GLOBALScope,
- Id: id,
- Username: username,
- Password: password,
- Description: description,
- StaplerClass: UsernamePassswordCredentialStaplerClass,
- }
- return &CreateUsernamePasswordCredentialRequest{
- Credentials: credential,
- }
-}
-
-func NewCreateSecretTextCredentialRequest(id, secret, description string) *CreateSecretTextCredentialRequest {
- credential := SecretTextCredential{
- Scope: GLOBALScope,
- Id: id,
- Secret: secret,
- Description: description,
- StaplerClass: SecretTextCredentialStaplerClass,
- }
- return &CreateSecretTextCredentialRequest{
- Credentials: credential,
- }
-}
-
-func NewCreateKubeconfigCredentialRequest(id, content, description string) *CreateKubeconfigCredentialRequest {
-
- credentialSource := KubeconfigSource{
- StaplerClass: DirectKubeconfigCredentialStaperClass,
- Content: content,
- }
-
- credential := KubeconfigCredential{
- Scope: GLOBALScope,
- Id: id,
- Description: description,
- KubeconfigSource: credentialSource,
- StaplerClass: KubeconfigCredentialStaplerClass,
- }
- return &CreateKubeconfigCredentialRequest{
- credential,
- }
-}
-
-func NewSshCredential(id, username, passphrase, privateKey, description string) *SshCredential {
- keySource := PrivateKeySource{
- StaplerClass: DirectSSHCrenditalStaplerClass,
- PrivateKey: privateKey,
- }
-
- return &SshCredential{
- Scope: GLOBALScope,
- Id: id,
- Username: username,
- Passphrase: passphrase,
- KeySource: keySource,
- Description: description,
- StaplerClass: SSHCrenditalStaplerClass,
- }
-}
-
-func NewUsernamePasswordCredential(id, username, password, description string) *UsernamePasswordCredential {
- return &UsernamePasswordCredential{
- Scope: GLOBALScope,
- Id: id,
- Username: username,
- Password: password,
- Description: description,
- StaplerClass: UsernamePassswordCredentialStaplerClass,
- }
-}
-
-func NewSecretTextCredential(id, secret, description string) *SecretTextCredential {
- return &SecretTextCredential{
- Scope: GLOBALScope,
- Id: id,
- Secret: secret,
- Description: description,
- StaplerClass: SecretTextCredentialStaplerClass,
- }
-}
-
-func NewKubeconfigCredential(id, content, description string) *KubeconfigCredential {
- credentialSource := KubeconfigSource{
- StaplerClass: DirectKubeconfigCredentialStaperClass,
- Content: content,
- }
-
- return &KubeconfigCredential{
- Scope: GLOBALScope,
- Id: id,
- Description: description,
- KubeconfigSource: credentialSource,
- StaplerClass: KubeconfigCredentialStaplerClass,
- }
-}
diff --git a/pkg/gojenkins/executor.go b/pkg/gojenkins/executor.go
deleted file mode 100644
index e5ba6f6c29dd6296a130e277b60a9f27d2601675..0000000000000000000000000000000000000000
--- a/pkg/gojenkins/executor.go
+++ /dev/null
@@ -1,44 +0,0 @@
-// Copyright 2015 Vadim Kravcenko
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package gojenkins
-
-type Executor struct {
- Raw *ExecutorResponse
- Jenkins *Jenkins
-}
-type ViewData struct {
- Name string `json:"name"`
- URL string `json:"url"`
-}
-type ExecutorResponse struct {
- AssignedLabels []struct{} `json:"assignedLabels"`
- Description interface{} `json:"description"`
- Jobs []InnerJob `json:"jobs"`
- Mode string `json:"mode"`
- NodeDescription string `json:"nodeDescription"`
- NodeName string `json:"nodeName"`
- NumExecutors int64 `json:"numExecutors"`
- OverallLoad struct{} `json:"overallLoad"`
- PrimaryView struct {
- Name string `json:"name"`
- URL string `json:"url"`
- } `json:"primaryView"`
- QuietingDown bool `json:"quietingDown"`
- SlaveAgentPort int64 `json:"slaveAgentPort"`
- UnlabeledLoad struct{} `json:"unlabeledLoad"`
- UseCrumbs bool `json:"useCrumbs"`
- UseSecurity bool `json:"useSecurity"`
- Views []ViewData `json:"views"`
-}
diff --git a/pkg/gojenkins/fingerprint.go b/pkg/gojenkins/fingerprint.go
deleted file mode 100644
index 3afaa8b6a4e288f887bc852b5c99c6d760ccab27..0000000000000000000000000000000000000000
--- a/pkg/gojenkins/fingerprint.go
+++ /dev/null
@@ -1,95 +0,0 @@
-// Copyright 2015 Vadim Kravcenko
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package gojenkins
-
-import (
- "errors"
- "fmt"
-)
-
-type FingerPrint struct {
- Jenkins *Jenkins
- Base string
- Id string
- Raw *FingerPrintResponse
-}
-
-type FingerPrintResponse struct {
- FileName string `json:"fileName"`
- Hash string `json:"hash"`
- Original struct {
- Name string
- Number int64
- } `json:"original"`
- Timestamp int64 `json:"timestamp"`
- Usage []struct {
- Name string `json:"name"`
- Ranges struct {
- Ranges []struct {
- End int64 `json:"end"`
- Start int64 `json:"start"`
- } `json:"ranges"`
- } `json:"ranges"`
- } `json:"usage"`
-}
-
-func (f FingerPrint) Valid() (bool, error) {
- status, err := f.Poll()
-
- if err != nil {
- return false, err
- }
-
- if status != 200 || f.Raw.Hash != f.Id {
- return false, fmt.Errorf("Jenkins says %s is Invalid or the Status is unknown", f.Id)
- }
- return true, nil
-}
-
-func (f FingerPrint) ValidateForBuild(filename string, build *Build) (bool, error) {
- valid, err := f.Valid()
- if err != nil {
- return false, err
- }
-
- if valid {
- return true, nil
- }
-
- if f.Raw.FileName != filename {
- return false, errors.New("Filename does not Match")
- }
- if build != nil && f.Raw.Original.Name == build.Job.GetName() &&
- f.Raw.Original.Number == build.GetBuildNumber() {
- return true, nil
- }
- return false, nil
-}
-
-func (f FingerPrint) GetInfo() (*FingerPrintResponse, error) {
- _, err := f.Poll()
- if err != nil {
- return nil, err
- }
- return f.Raw, nil
-}
-
-func (f FingerPrint) Poll() (int, error) {
- response, err := f.Jenkins.Requester.GetJSON(f.Base+f.Id, f.Raw, nil)
- if err != nil {
- return 0, err
- }
- return response.StatusCode, nil
-}
diff --git a/pkg/gojenkins/jenkins.go b/pkg/gojenkins/jenkins.go
deleted file mode 100644
index feaf49c659d6500e596ca0f3bdb3810e8c64d6b4..0000000000000000000000000000000000000000
--- a/pkg/gojenkins/jenkins.go
+++ /dev/null
@@ -1,1083 +0,0 @@
-// Copyright 2015 Vadim Kravcenko
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-// Gojenkins is a Jenkins Client in Go, that exposes the jenkins REST api in a more developer friendly way.
-package gojenkins
-
-import (
- "encoding/json"
- "errors"
- "fmt"
- "log"
- "net/http"
- "os"
- "reflect"
- "strconv"
- "strings"
-)
-
-// Basic Authentication
-type BasicAuth struct {
- Username string
- Password string
-}
-
-type Jenkins struct {
- Server string
- Version string
- Raw *ExecutorResponse
- Requester *Requester
-}
-
-// Loggers
-var (
- Info *log.Logger
- Warning *log.Logger
- Error *log.Logger
-)
-
-// Init Method. Should be called after creating a Jenkins Instance.
-// e.g jenkins := CreateJenkins("url").Init()
-// HTTP Client is set here, Connection to jenkins is tested here.
-func (j *Jenkins) Init() (*Jenkins, error) {
- j.initLoggers()
-
- // Check Connection
- j.Raw = new(ExecutorResponse)
- rsp, err := j.Requester.GetJSON("/", j.Raw, nil)
- if err != nil {
- return nil, err
- }
-
- j.Version = rsp.Header.Get("X-Jenkins")
- if j.Raw == nil {
- return nil, errors.New("Connection Failed, Please verify that the host and credentials are correct.")
- }
-
- return j, nil
-}
-
-func (j *Jenkins) initLoggers() {
- Info = log.New(os.Stdout,
- "INFO: ",
- log.Ldate|log.Ltime|log.Lshortfile)
-
- Warning = log.New(os.Stdout,
- "WARNING: ",
- log.Ldate|log.Ltime|log.Lshortfile)
-
- Error = log.New(os.Stderr,
- "ERROR: ",
- log.Ldate|log.Ltime|log.Lshortfile)
-}
-
-// Get Basic Information About Jenkins
-func (j *Jenkins) Info() (*ExecutorResponse, error) {
- _, err := j.Requester.Get("/", j.Raw, nil)
-
- if err != nil {
- return nil, err
- }
- return j.Raw, nil
-}
-
-// Create a new Node
-// Can be JNLPLauncher or SSHLauncher
-// Example : jenkins.CreateNode("nodeName", 1, "Description", "/var/lib/jenkins", "jdk8 docker", map[string]string{"method": "JNLPLauncher"})
-// By Default JNLPLauncher is created
-// Multiple labels should be separated by blanks
-func (j *Jenkins) CreateNode(name string, numExecutors int, description string, remoteFS string, label string, options ...interface{}) (*Node, error) {
- params := map[string]string{"method": "JNLPLauncher"}
-
- if len(options) > 0 {
- params, _ = options[0].(map[string]string)
- }
-
- if _, ok := params["method"]; !ok {
- params["method"] = "JNLPLauncher"
- }
-
- method := params["method"]
- var launcher map[string]string
- switch method {
- case "":
- fallthrough
- case "JNLPLauncher":
- launcher = map[string]string{"stapler-class": "hudson.slaves.JNLPLauncher"}
- case "SSHLauncher":
- launcher = map[string]string{
- "stapler-class": "hudson.plugins.sshslaves.SSHLauncher",
- "$class": "hudson.plugins.sshslaves.SSHLauncher",
- "host": params["host"],
- "port": params["port"],
- "credentialsId": params["credentialsId"],
- "jvmOptions": params["jvmOptions"],
- "javaPath": params["javaPath"],
- "prefixStartSlaveCmd": params["prefixStartSlaveCmd"],
- "suffixStartSlaveCmd": params["suffixStartSlaveCmd"],
- "maxNumRetries": params["maxNumRetries"],
- "retryWaitTime": params["retryWaitTime"],
- "lanuchTimeoutSeconds": params["lanuchTimeoutSeconds"],
- "type": "hudson.slaves.DumbSlave",
- "stapler-class-bag": "true"}
- default:
- return nil, errors.New("launcher method not supported")
- }
-
- node := &Node{Jenkins: j, Raw: new(NodeResponse), Base: "/computer/" + name}
- NODE_TYPE := "hudson.slaves.DumbSlave$DescriptorImpl"
- MODE := "NORMAL"
- qr := map[string]string{
- "name": name,
- "type": NODE_TYPE,
- "json": makeJson(map[string]interface{}{
- "name": name,
- "nodeDescription": description,
- "remoteFS": remoteFS,
- "numExecutors": numExecutors,
- "mode": MODE,
- "type": NODE_TYPE,
- "labelString": label,
- "retentionsStrategy": map[string]string{"stapler-class": "hudson.slaves.RetentionStrategy$Always"},
- "nodeProperties": map[string]string{"stapler-class-bag": "true"},
- "launcher": launcher,
- }),
- }
-
- resp, err := j.Requester.Post("/computer/doCreateItem", nil, nil, qr)
-
- if err != nil {
- return nil, err
- }
-
- if resp.StatusCode < 400 {
- _, err := node.Poll()
- if err != nil {
- return nil, err
- }
- return node, nil
- }
- return nil, errors.New(strconv.Itoa(resp.StatusCode))
-}
-
-// Delete a Jenkins slave node
-func (j *Jenkins) DeleteNode(name string) (bool, error) {
- node := Node{Jenkins: j, Raw: new(NodeResponse), Base: "/computer/" + name}
- return node.Delete()
-}
-
-// Create a new folder
-// This folder can be nested in other parent folders
-// Example: jenkins.CreateFolder("newFolder", "grandparentFolder", "parentFolder")
-func (j *Jenkins) CreateFolder(name, description string, parents ...string) (*Folder, error) {
- folderObj := &Folder{Jenkins: j, Raw: new(FolderResponse), Base: "/job/" + strings.Join(append(parents, name), "/job/")}
- folder, err := folderObj.Create(name, description)
- if err != nil {
- return nil, err
- }
- return folder, nil
-}
-
-// Create a new job in the folder
-// Example: jenkins.CreateJobInFolder("", "newJobName", "myFolder", "parentFolder")
-func (j *Jenkins) CreateJobInFolder(config string, jobName string, parentIDs ...string) (*Job, error) {
- jobObj := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + strings.Join(append(parentIDs, jobName), "/job/")}
- qr := map[string]string{
- "name": jobName,
- }
- job, err := jobObj.Create(config, qr)
- if err != nil {
- return nil, err
- }
- return job, nil
-}
-
-// Create a new job from config File
-// Method takes XML string as first parameter, and if the name is not specified in the config file
-// takes name as string as second parameter
-// e.g jenkins.CreateJob("","newJobName")
-func (j *Jenkins) CreateJob(config string, options ...interface{}) (*Job, error) {
- qr := make(map[string]string)
- if len(options) > 0 {
- qr["name"] = options[0].(string)
- } else {
- return nil, errors.New("Error Creating Job, job name is missing")
- }
- jobObj := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + qr["name"]}
- job, err := jobObj.Create(config, qr)
- if err != nil {
- return nil, err
- }
- return job, nil
-}
-
-// Rename a job.
-// First parameter job old name, Second parameter job new name.
-func (j *Jenkins) RenameJob(job string, name string) *Job {
- jobObj := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + job}
- jobObj.Rename(name)
- return &jobObj
-}
-
-// Create a copy of a job.
-// First parameter Name of the job to copy from, Second parameter new job name.
-func (j *Jenkins) CopyJob(copyFrom string, newName string) (*Job, error) {
- job := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + copyFrom}
- _, err := job.Poll()
- if err != nil {
- return nil, err
- }
- return job.Copy(newName)
-}
-
-// Delete a job.
-func (j *Jenkins) DeleteJob(name string, parentIDs ...string) (bool, error) {
- job := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + strings.Join(append(parentIDs, name), "/job/")}
- return job.Delete()
-}
-
-// Invoke a job.
-// First parameter job name, second parameter is optional Build parameters.
-func (j *Jenkins) BuildJob(name string, options ...interface{}) (int64, error) {
- job := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + name}
- var params map[string]string
- if len(options) > 0 {
- params, _ = options[0].(map[string]string)
- }
- return job.InvokeSimple(params)
-}
-
-func (j *Jenkins) GetNode(name string) (*Node, error) {
- node := Node{Jenkins: j, Raw: new(NodeResponse), Base: "/computer/" + name}
- status, err := node.Poll()
- if err != nil {
- return nil, err
- }
- if status == 200 {
- return &node, nil
- }
- return nil, errors.New("No node found")
-}
-
-func (j *Jenkins) GetLabel(name string) (*Label, error) {
- label := Label{Jenkins: j, Raw: new(LabelResponse), Base: "/label/" + name}
- status, err := label.Poll()
- if err != nil {
- return nil, err
- }
- if status == 200 {
- return &label, nil
- }
- return nil, errors.New("No label found")
-}
-
-func (j *Jenkins) GetBuild(jobName string, number int64) (*Build, error) {
- job, err := j.GetJob(jobName)
- if err != nil {
- return nil, err
- }
- build, err := job.GetBuild(number)
-
- if err != nil {
- return nil, err
- }
- return build, nil
-}
-
-func (j *Jenkins) GetJob(id string, parentIDs ...string) (*Job, error) {
- job := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + strings.Join(append(parentIDs, id), "/job/")}
- status, err := job.Poll()
- if err != nil {
- return nil, err
- }
- if status == 200 {
- return &job, nil
- }
- return nil, errors.New(strconv.Itoa(status))
-}
-
-func (j *Jenkins) GetSubJob(parentId string, childId string) (*Job, error) {
- job := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + parentId + "/job/" + childId}
- status, err := job.Poll()
- if err != nil {
- return nil, fmt.Errorf("trouble polling job: %v", err)
- }
- if status == 200 {
- return &job, nil
- }
- return nil, errors.New(strconv.Itoa(status))
-}
-
-func (j *Jenkins) GetFolder(id string, parents ...string) (*Folder, error) {
- folder := Folder{Jenkins: j, Raw: new(FolderResponse), Base: "/job/" + strings.Join(append(parents, id), "/job/")}
- status, err := folder.Poll()
- if err != nil {
- return nil, fmt.Errorf("trouble polling folder: %v", err)
- }
- if status == 200 {
- return &folder, nil
- }
- return nil, errors.New(strconv.Itoa(status))
-}
-
-func (j *Jenkins) GetAllNodes() ([]*Node, error) {
- computers := new(Computers)
-
- qr := map[string]string{
- "depth": "1",
- }
-
- _, err := j.Requester.GetJSON("/computer", computers, qr)
- if err != nil {
- return nil, err
- }
-
- nodes := make([]*Node, len(computers.Computers))
- for i, node := range computers.Computers {
- nodes[i] = &Node{Jenkins: j, Raw: node, Base: "/computer/" + node.DisplayName}
- }
-
- return nodes, nil
-}
-
-// Get all builds Numbers and URLS for a specific job.
-// There are only build IDs here,
-// To get all the other info of the build use jenkins.GetBuild(job,buildNumber)
-// or job.GetBuild(buildNumber)
-func (j *Jenkins) GetAllBuildIds(job string) ([]JobBuild, error) {
- jobObj, err := j.GetJob(job)
- if err != nil {
- return nil, err
- }
- return jobObj.GetAllBuildIds()
-}
-
-func (j *Jenkins) GetAllBuildStatus(jobId string) ([]JobBuildStatus, error) {
- job, err := j.GetJob(jobId)
- if err != nil {
- return nil, err
- }
- return job.GetAllBuildStatus()
-}
-
-// Get Only Array of Job Names, Color, URL
-// Does not query each single Job.
-func (j *Jenkins) GetAllJobNames() ([]InnerJob, error) {
- exec := Executor{Raw: new(ExecutorResponse), Jenkins: j}
- _, err := j.Requester.GetJSON("/", exec.Raw, nil)
-
- if err != nil {
- return nil, err
- }
-
- return exec.Raw.Jobs, nil
-}
-
-// Get All Possible Job Objects.
-// Each job will be queried.
-func (j *Jenkins) GetAllJobs() ([]*Job, error) {
- exec := Executor{Raw: new(ExecutorResponse), Jenkins: j}
- _, err := j.Requester.GetJSON("/", exec.Raw, nil)
-
- if err != nil {
- return nil, err
- }
-
- jobs := make([]*Job, len(exec.Raw.Jobs))
- for i, job := range exec.Raw.Jobs {
- ji, err := j.GetJob(job.Name)
- if err != nil {
- return nil, err
- }
- jobs[i] = ji
- }
- return jobs, nil
-}
-
-// Returns a Queue
-func (j *Jenkins) GetQueue() (*Queue, error) {
- q := &Queue{Jenkins: j, Raw: new(queueResponse), Base: j.GetQueueUrl()}
- _, err := q.Poll()
- if err != nil {
- return nil, err
- }
- return q, nil
-}
-
-func (j *Jenkins) GetQueueUrl() string {
- return "/queue"
-}
-
-// Get Artifact data by Hash
-func (j *Jenkins) GetArtifactData(id string) (*FingerPrintResponse, error) {
- fp := FingerPrint{Jenkins: j, Base: "/fingerprint/", Id: id, Raw: new(FingerPrintResponse)}
- return fp.GetInfo()
-}
-
-// Returns the list of all plugins installed on the Jenkins server.
-// You can supply depth parameter, to limit how much data is returned.
-func (j *Jenkins) GetPlugins(depth int) (*Plugins, error) {
- p := Plugins{Jenkins: j, Raw: new(PluginResponse), Base: "/pluginManager", Depth: depth}
- _, err := p.Poll()
- if err != nil {
- return nil, err
- }
- return &p, nil
-}
-
-// Check if the plugin is installed on the server.
-// Depth level 1 is used. If you need to go deeper, you can use GetPlugins, and iterate through them.
-func (j *Jenkins) HasPlugin(name string) (*Plugin, error) {
- p, err := j.GetPlugins(1)
-
- if err != nil {
- return nil, err
- }
- return p.Contains(name), nil
-}
-
-// Verify FingerPrint
-func (j *Jenkins) ValidateFingerPrint(id string) (bool, error) {
- fp := FingerPrint{Jenkins: j, Base: "/fingerprint/", Id: id, Raw: new(FingerPrintResponse)}
- valid, err := fp.Valid()
- if err != nil {
- return false, err
- }
- if valid {
- return true, nil
- }
- return false, nil
-}
-
-func (j *Jenkins) GetView(name string) (*View, error) {
- url := "/view/" + name
- view := View{Jenkins: j, Raw: new(ViewResponse), Base: url}
- _, err := view.Poll()
- if err != nil {
- return nil, err
- }
- return &view, nil
-}
-
-func (j *Jenkins) GetAllViews() ([]*View, error) {
- _, err := j.Poll()
- if err != nil {
- return nil, err
- }
- views := make([]*View, len(j.Raw.Views))
- for i, v := range j.Raw.Views {
- views[i], _ = j.GetView(v.Name)
- }
- return views, nil
-}
-
-// Create View
-// First Parameter - name of the View
-// Second parameter - Type
-// Possible Types:
-// gojenkins.LIST_VIEW
-// gojenkins.NESTED_VIEW
-// gojenkins.MY_VIEW
-// gojenkins.DASHBOARD_VIEW
-// gojenkins.PIPELINE_VIEW
-// Example: jenkins.CreateView("newView",gojenkins.LIST_VIEW)
-func (j *Jenkins) CreateView(name string, viewType string) (*View, error) {
- view := &View{Jenkins: j, Raw: new(ViewResponse), Base: "/view/" + name}
- endpoint := "/createView"
- data := map[string]string{
- "name": name,
- "mode": viewType,
- "Submit": "OK",
- "json": makeJson(map[string]string{
- "name": name,
- "mode": viewType,
- }),
- }
- r, err := j.Requester.Post(endpoint, nil, view.Raw, data)
-
- if err != nil {
- return nil, err
- }
-
- if r.StatusCode == 200 {
- return j.GetView(name)
- }
- return nil, errors.New(strconv.Itoa(r.StatusCode))
-}
-
-func (j *Jenkins) Poll() (int, error) {
- resp, err := j.Requester.GetJSON("/", j.Raw, nil)
- if err != nil {
- return 0, err
- }
- return resp.StatusCode, nil
-}
-
-// Create a ssh credentials
-// return credentials id
-func (j *Jenkins) CreateSshCredential(id, username, passphrase, privateKey, description string) (*string, error) {
- requestStruct := NewCreateSshCredentialRequest(id, username, passphrase, privateKey, description)
- param := map[string]string{"json": makeJson(requestStruct)}
- responseString := ""
- response, err := j.Requester.Post("/credentials/store/system/domain/_/createCredentials",
- nil, &responseString, param)
- if err != nil {
- return nil, err
- }
- if response.StatusCode != http.StatusOK {
- return nil, errors.New(strconv.Itoa(response.StatusCode))
- }
- return &requestStruct.Credentials.Id, nil
-}
-
-func (j *Jenkins) CreateUsernamePasswordCredential(id, username, password, description string) (*string, error) {
- requestStruct := NewCreateUsernamePasswordRequest(id, username, password, description)
- param := map[string]string{"json": makeJson(requestStruct)}
- responseString := ""
- response, err := j.Requester.Post("/credentials/store/system/domain/_/createCredentials",
- nil, &responseString, param)
- if err != nil {
- return nil, err
- }
- if response.StatusCode != http.StatusOK {
- return nil, errors.New(strconv.Itoa(response.StatusCode))
- }
- return &requestStruct.Credentials.Id, nil
-}
-
-func (j *Jenkins) CreateSshCredentialInFolder(domain, id, username, passphrase, privateKey, description string, folders ...string) (*string, error) {
- requestStruct := NewCreateSshCredentialRequest(id, username, passphrase, privateKey, description)
- param := map[string]string{"json": makeJson(requestStruct)}
- responseString := ""
- prePath := ""
- if domain == "" {
- domain = "_"
- }
- if len(folders) == 0 {
- return nil, fmt.Errorf("folder name shoud not be nil")
- }
- for _, folder := range folders {
- prePath = prePath + fmt.Sprintf("/job/%s", folder)
- }
- response, err := j.Requester.Post(prePath+
- fmt.Sprintf("/credentials/store/folder/domain/%s/createCredentials", domain),
- nil, &responseString, param)
- if err != nil {
- return nil, err
- }
- if response.StatusCode != http.StatusOK {
- return nil, errors.New(strconv.Itoa(response.StatusCode))
- }
- return &requestStruct.Credentials.Id, nil
-}
-
-func (j *Jenkins) CreateUsernamePasswordCredentialInFolder(domain, id, username, password, description string, folders ...string) (*string, error) {
- requestStruct := NewCreateUsernamePasswordRequest(id, username, password, description)
- param := map[string]string{"json": makeJson(requestStruct)}
- responseString := ""
- prePath := ""
- if domain == "" {
- domain = "_"
- }
- if len(folders) == 0 {
- return nil, fmt.Errorf("folder name shoud not be nil")
- }
- for _, folder := range folders {
- prePath = prePath + fmt.Sprintf("/job/%s", folder)
- }
- response, err := j.Requester.Post(prePath+
- fmt.Sprintf("/credentials/store/folder/domain/%s/createCredentials", domain),
- nil, &responseString, param)
- if err != nil {
- return nil, err
- }
- if response.StatusCode != http.StatusOK {
- return nil, errors.New(strconv.Itoa(response.StatusCode))
- }
- return &requestStruct.Credentials.Id, nil
-}
-
-func (j *Jenkins) CreateSecretTextCredentialInFolder(domain, id, secret, description string, folders ...string) (*string, error) {
- requestStruct := NewCreateSecretTextCredentialRequest(id, secret, description)
- param := map[string]string{"json": makeJson(requestStruct)}
- responseString := ""
- prePath := ""
- if domain == "" {
- domain = "_"
- }
- if len(folders) == 0 {
- return nil, fmt.Errorf("folder name shoud not be nil")
- }
- for _, folder := range folders {
- prePath = prePath + fmt.Sprintf("/job/%s", folder)
- }
- response, err := j.Requester.Post(prePath+
- fmt.Sprintf("/credentials/store/folder/domain/%s/createCredentials", domain),
- nil, &responseString, param)
- if err != nil {
- return nil, err
- }
- if response.StatusCode != http.StatusOK {
- return nil, errors.New(strconv.Itoa(response.StatusCode))
- }
- return &requestStruct.Credentials.Id, nil
-}
-
-func (j *Jenkins) CreateKubeconfigCredentialInFolder(domain, id, content, description string, folders ...string) (*string, error) {
- requestStruct := NewCreateKubeconfigCredentialRequest(id, content, description)
- param := map[string]string{"json": makeJson(requestStruct)}
- responseString := ""
- prePath := ""
- if domain == "" {
- domain = "_"
- }
- if len(folders) == 0 {
- return nil, fmt.Errorf("folder name shoud not be nil")
- }
- for _, folder := range folders {
- prePath = prePath + fmt.Sprintf("/job/%s", folder)
- }
- response, err := j.Requester.Post(prePath+
- fmt.Sprintf("/credentials/store/folder/domain/%s/createCredentials", domain),
- nil, &responseString, param)
- if err != nil {
- return nil, err
- }
- if response.StatusCode != http.StatusOK {
- return nil, errors.New(strconv.Itoa(response.StatusCode))
- }
- return &requestStruct.Credentials.Id, nil
-}
-
-func (j *Jenkins) UpdateSshCredentialInFolder(domain, id, username, passphrase, privateKey, description string, folders ...string) (*string, error) {
- requestStruct := NewSshCredential(id, username, passphrase, privateKey, description)
- param := map[string]string{"json": makeJson(requestStruct)}
- prePath := ""
- if domain == "" {
- domain = "_"
- }
- if len(folders) == 0 {
- return nil, fmt.Errorf("folder name shoud not be nil")
- }
- for _, folder := range folders {
- prePath = prePath + fmt.Sprintf("/job/%s", folder)
- }
- response, err := j.Requester.Post(prePath+
- fmt.Sprintf("/credentials/store/folder/domain/%s/credential/%s/updateSubmit", domain, id),
- nil, nil, param)
- if err != nil {
- return nil, err
- }
- if response.StatusCode != http.StatusOK {
- return nil, errors.New(strconv.Itoa(response.StatusCode))
- }
- return &id, nil
-}
-
-func (j *Jenkins) UpdateUsernamePasswordCredentialInFolder(domain, id, username, password, description string, folders ...string) (*string, error) {
- requestStruct := NewUsernamePasswordCredential(id, username, password, description)
- param := map[string]string{"json": makeJson(requestStruct)}
- prePath := ""
- if domain == "" {
- domain = "_"
- }
- if len(folders) == 0 {
- return nil, fmt.Errorf("folder name shoud not be nil")
- }
- for _, folder := range folders {
- prePath = prePath + fmt.Sprintf("/job/%s", folder)
- }
- response, err := j.Requester.Post(prePath+
- fmt.Sprintf("/credentials/store/folder/domain/%s/credential/%s/updateSubmit", domain, id),
- nil, nil, param)
- if err != nil {
- return nil, err
- }
- if response.StatusCode != http.StatusOK {
- return nil, errors.New(strconv.Itoa(response.StatusCode))
- }
- return &id, nil
-}
-
-func (j *Jenkins) UpdateSecretTextCredentialInFolder(domain, id, secret, description string, folders ...string) (*string, error) {
- requestStruct := NewSecretTextCredential(id, secret, description)
- param := map[string]string{"json": makeJson(requestStruct)}
- prePath := ""
- if domain == "" {
- domain = "_"
- }
- if len(folders) == 0 {
- return nil, fmt.Errorf("folder name shoud not be nil")
- }
- for _, folder := range folders {
- prePath = prePath + fmt.Sprintf("/job/%s", folder)
- }
- response, err := j.Requester.Post(prePath+
- fmt.Sprintf("/credentials/store/folder/domain/%s/credential/%s/updateSubmit", domain, id),
- nil, nil, param)
- if err != nil {
- return nil, err
- }
- if response.StatusCode != http.StatusOK {
- return nil, errors.New(strconv.Itoa(response.StatusCode))
- }
- return &id, nil
-}
-
-func (j *Jenkins) UpdateKubeconfigCredentialInFolder(domain, id, content, description string, folders ...string) (*string, error) {
- requestStruct := NewKubeconfigCredential(id, content, description)
- param := map[string]string{"json": makeJson(requestStruct)}
- prePath := ""
- if domain == "" {
- domain = "_"
- }
- if len(folders) == 0 {
- return nil, fmt.Errorf("folder name shoud not be nil")
- }
- for _, folder := range folders {
- prePath = prePath + fmt.Sprintf("/job/%s", folder)
- }
- response, err := j.Requester.Post(prePath+
- fmt.Sprintf("/credentials/store/folder/domain/%s/credential/%s/updateSubmit", domain, id),
- nil, nil, param)
- if err != nil {
- return nil, err
- }
- if response.StatusCode != http.StatusOK {
- return nil, errors.New(strconv.Itoa(response.StatusCode))
- }
- return &id, nil
-}
-
-func (j *Jenkins) GetCredentialInFolder(domain, id string, folders ...string) (*CredentialResponse, error) {
- responseStruct := &CredentialResponse{}
- prePath := ""
- if domain == "" {
- domain = "_"
- }
- if len(folders) == 0 {
- return nil, fmt.Errorf("folder name shoud not be nil")
- }
- for _, folder := range folders {
- prePath = prePath + fmt.Sprintf("/job/%s", folder)
- }
- response, err := j.Requester.GetJSON(prePath+
- fmt.Sprintf("/credentials/store/folder/domain/%s/credential/%s", domain, id),
- responseStruct, map[string]string{
- "depth": "2",
- })
- if err != nil {
- return nil, err
- }
- if response.StatusCode != http.StatusOK {
- return nil, errors.New(strconv.Itoa(response.StatusCode))
- }
- responseStruct.Domain = domain
- return responseStruct, nil
-}
-
-func (j *Jenkins) GetCredentialContentInFolder(domain, id string, folders ...string) (string, error) {
- responseStruct := ""
- prePath := ""
- if domain == "" {
- domain = "_"
- }
- if len(folders) == 0 {
- return "", fmt.Errorf("folder name shoud not be nil")
- }
- for _, folder := range folders {
- prePath = prePath + fmt.Sprintf("/job/%s", folder)
- }
- response, err := j.Requester.GetHtml(prePath+
- fmt.Sprintf("/credentials/store/folder/domain/%s/credential/%s/update", domain, id),
- &responseStruct, nil)
- if err != nil {
- return "", err
- }
- if response.StatusCode != http.StatusOK {
- return "", errors.New(strconv.Itoa(response.StatusCode))
- }
- return responseStruct, nil
-}
-
-func (j *Jenkins) GetCredentialsInFolder(domain string, folders ...string) ([]*CredentialResponse, error) {
- prePath := ""
- if len(folders) == 0 {
- return nil, fmt.Errorf("folder name shoud not be nil")
- }
- for _, folder := range folders {
- prePath = prePath + fmt.Sprintf("/job/%s", folder)
- }
-
- if domain == "" {
- var responseStruct = &struct {
- Domains map[string]struct {
- Credentials []*CredentialResponse `json:"credentials"`
- } `json:"domains"`
- }{}
- response, err := j.Requester.GetJSON(prePath+
- "/credentials/store/folder/",
- responseStruct, map[string]string{
- "depth": "2",
- })
- if err != nil {
- return nil, err
- }
- if response.StatusCode != http.StatusOK {
- return nil, errors.New(strconv.Itoa(response.StatusCode))
- }
- responseArray := make([]*CredentialResponse, 0)
- for domainName, domain := range responseStruct.Domains {
- for _, credential := range domain.Credentials {
- credential.Domain = domainName
- responseArray = append(responseArray, credential)
- }
- }
- return responseArray, nil
- }
-
- var responseStruct = &struct {
- Credentials []*CredentialResponse `json:"credentials"`
- }{}
- response, err := j.Requester.GetJSON(prePath+
- fmt.Sprintf("/credentials/store/folder/domain/%s", domain),
- responseStruct, map[string]string{
- "depth": "2",
- })
- if err != nil {
- return nil, err
- }
- if response.StatusCode != http.StatusOK {
- return nil, errors.New(strconv.Itoa(response.StatusCode))
- }
- for _, credential := range responseStruct.Credentials {
- credential.Domain = domain
- }
- return responseStruct.Credentials, nil
-
-}
-
-func (j *Jenkins) DeleteCredentialInFolder(domain, id string, folders ...string) (*string, error) {
- prePath := ""
- if domain == "" {
- domain = "_"
- }
- if len(folders) == 0 {
- return nil, fmt.Errorf("folder name shoud not be nil")
- }
- for _, folder := range folders {
- prePath = prePath + fmt.Sprintf("/job/%s", folder)
- }
- response, err := j.Requester.Post(prePath+
- fmt.Sprintf("/credentials/store/folder/domain/%s/credential/%s/doDelete", domain, id),
- nil, nil, nil)
- if err != nil {
- return nil, err
- }
- if response.StatusCode != http.StatusOK {
- return nil, errors.New(strconv.Itoa(response.StatusCode))
- }
- return &id, nil
-}
-
-func (j *Jenkins) GetGlobalRole(roleName string) (*GlobalRole, error) {
- roleResponse := &GlobalRoleResponse{
- RoleName: roleName,
- }
- stringResponse := ""
- response, err := j.Requester.Get("/role-strategy/strategy/getRole",
- &stringResponse,
- map[string]string{
- "roleName": roleName,
- "type": GLOBAL_ROLE,
- })
- if err != nil {
- return nil, err
- }
- if response.StatusCode != http.StatusOK {
- return nil, errors.New(strconv.Itoa(response.StatusCode))
- }
- if stringResponse == "{}" {
- return nil, nil
- }
- err = json.Unmarshal([]byte(stringResponse), roleResponse)
- if err != nil {
- return nil, err
- }
- return &GlobalRole{
- Jenkins: j,
- Raw: *roleResponse,
- }, nil
-}
-
-func (j *Jenkins) GetProjectRole(roleName string) (*ProjectRole, error) {
- roleResponse := &ProjectRoleResponse{
- RoleName: roleName,
- }
- stringResponse := ""
- response, err := j.Requester.Get("/role-strategy/strategy/getRole",
- &stringResponse,
- map[string]string{
- "roleName": roleName,
- "type": PROJECT_ROLE,
- })
- if err != nil {
- return nil, err
- }
- if response.StatusCode != http.StatusOK {
- return nil, errors.New(strconv.Itoa(response.StatusCode))
- }
- if stringResponse == "{}" {
- return nil, nil
- }
- err = json.Unmarshal([]byte(stringResponse), roleResponse)
- if err != nil {
- return nil, err
- }
- return &ProjectRole{
- Jenkins: j,
- Raw: *roleResponse,
- }, nil
-}
-
-func (j *Jenkins) AddGlobalRole(roleName string, ids GlobalPermissionIds, overwrite bool) (*GlobalRole, error) {
- responseRole := &GlobalRole{
- Jenkins: j,
- Raw: GlobalRoleResponse{
- RoleName: roleName,
- PermissionIds: ids,
- }}
- var idArray []string
- values := reflect.ValueOf(ids)
- for i := 0; i < values.NumField(); i++ {
- field := values.Field(i)
- if field.Bool() {
- idArray = append(idArray, values.Type().Field(i).Tag.Get("json"))
- }
- }
- param := map[string]string{
- "roleName": roleName,
- "type": GLOBAL_ROLE,
- "permissionIds": strings.Join(idArray, ","),
- "overwrite": strconv.FormatBool(overwrite),
- }
- responseString := ""
- response, err := j.Requester.Post("/role-strategy/strategy/addRole", nil, &responseString, param)
- if err != nil {
- return nil, err
- }
- if response.StatusCode != http.StatusOK {
- return nil, errors.New(strconv.Itoa(response.StatusCode))
- }
- return responseRole, nil
-}
-
-func (j *Jenkins) DeleteProjectRoles(roleName ...string) error {
- responseString := ""
-
- response, err := j.Requester.Post("/role-strategy/strategy/removeRoles", nil, &responseString, map[string]string{
- "type": PROJECT_ROLE,
- "roleNames": strings.Join(roleName, ","),
- })
- if err != nil {
- return err
- }
- if response.StatusCode != http.StatusOK {
- fmt.Println(responseString)
- return errors.New(strconv.Itoa(response.StatusCode))
- }
- return nil
-}
-
-func (j *Jenkins) AddProjectRole(roleName string, pattern string, ids ProjectPermissionIds, overwrite bool) (*ProjectRole, error) {
- responseRole := &ProjectRole{
- Jenkins: j,
- Raw: ProjectRoleResponse{
- RoleName: roleName,
- PermissionIds: ids,
- Pattern: pattern,
- }}
- var idArray []string
- values := reflect.ValueOf(ids)
- for i := 0; i < values.NumField(); i++ {
- field := values.Field(i)
- if field.Bool() {
- idArray = append(idArray, values.Type().Field(i).Tag.Get("json"))
- }
- }
- param := map[string]string{
- "roleName": roleName,
- "type": PROJECT_ROLE,
- "permissionIds": strings.Join(idArray, ","),
- "overwrite": strconv.FormatBool(overwrite),
- "pattern": pattern,
- }
- responseString := ""
- response, err := j.Requester.Post("/role-strategy/strategy/addRole", nil, &responseString, param)
- if err != nil {
- return nil, err
- }
- if response.StatusCode != http.StatusOK {
- return nil, errors.New(strconv.Itoa(response.StatusCode))
- }
- return responseRole, nil
-}
-
-func (j *Jenkins) DeleteUserInProject(username string) error {
- param := map[string]string{
- "type": PROJECT_ROLE,
- "sid": username,
- }
- responseString := ""
- response, err := j.Requester.Post("/role-strategy/strategy/deleteSid", nil, &responseString, param)
- if err != nil {
- return err
- }
- if response.StatusCode != http.StatusOK {
- return errors.New(strconv.Itoa(response.StatusCode))
- }
- return nil
-}
-
-func (j *Jenkins) GetQueueItem(number int64) (*QueueItemResponse, error) {
- responseItem := &QueueItemResponse{}
- response, err := j.Requester.GetJSON(fmt.Sprintf("/queue/item/%s", strconv.FormatInt(number, 10)),
- responseItem, nil)
- if err != nil {
- return nil, err
- }
- if response.StatusCode != http.StatusOK {
- return nil, errors.New(strconv.Itoa(response.StatusCode))
- }
- return responseItem, nil
-}
-
-// Creates a new Jenkins Instance
-// Optional parameters are: client, username, password
-// After creating an instance call init method.
-func CreateJenkins(client *http.Client, base string, maxConnection int, auth ...interface{}) *Jenkins {
- j := &Jenkins{}
- if strings.HasSuffix(base, "/") {
- base = base[:len(base)-1]
- }
- j.Server = base
- j.Requester = &Requester{Base: base, SslVerify: true, Client: client, connControl: make(chan struct{}, maxConnection)}
- if j.Requester.Client == nil {
- j.Requester.Client = http.DefaultClient
- }
- if len(auth) == 2 {
- j.Requester.BasicAuth = &BasicAuth{Username: auth[0].(string), Password: auth[1].(string)}
- }
- return j
-}
diff --git a/pkg/gojenkins/label.go b/pkg/gojenkins/label.go
deleted file mode 100644
index a757b630faa6fd677facc0e466f721759c7c1b1c..0000000000000000000000000000000000000000
--- a/pkg/gojenkins/label.go
+++ /dev/null
@@ -1,62 +0,0 @@
-// Copyright 2015 Vadim Kravcenko
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package gojenkins
-
-type Label struct {
- Raw *LabelResponse
- Jenkins *Jenkins
- Base string
-}
-
-type MODE string
-
-const (
- NORMAL MODE = "NORMAL"
- EXCLUSIVE = "EXCLUSIVE"
-)
-
-type LabelNode struct {
- NodeName string `json:"nodeName"`
- NodeDescription string `json:"nodeDescription"`
- NumExecutors int64 `json:"numExecutors"`
- Mode string `json:"mode"`
- Class string `json:"_class"`
-}
-
-type LabelResponse struct {
- Name string `json:"name"`
- Description string `json:"description"`
- Nodes []LabelNode `json:"nodes"`
- Offline bool `json:"offline"`
- IdleExecutors int64 `json:"idleExecutors"`
- BusyExecutors int64 `json:"busyExecutors"`
- TotalExecutors int64 `json:"totalExecutors"`
-}
-
-func (l *Label) GetName() string {
- return l.Raw.Name
-}
-
-func (l *Label) GetNodes() []LabelNode {
- return l.Raw.Nodes
-}
-
-func (l *Label) Poll() (int, error) {
- response, err := l.Jenkins.Requester.GetJSON(l.Base, l.Raw, nil)
- if err != nil {
- return 0, err
- }
- return response.StatusCode, nil
-}
diff --git a/pkg/gojenkins/node.go b/pkg/gojenkins/node.go
deleted file mode 100644
index 14a6face86b22be7f3dada569041f3428e0ff2ae..0000000000000000000000000000000000000000
--- a/pkg/gojenkins/node.go
+++ /dev/null
@@ -1,230 +0,0 @@
-// Copyright 2015 Vadim Kravcenko
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package gojenkins
-
-import "errors"
-
-// Nodes
-
-type Computers struct {
- BusyExecutors int `json:"busyExecutors"`
- Computers []*NodeResponse `json:"computer"`
- DisplayName string `json:"displayName"`
- TotalExecutors int `json:"totalExecutors"`
-}
-
-type Node struct {
- Raw *NodeResponse
- Jenkins *Jenkins
- Base string
-}
-
-type NodeResponse struct {
- Actions []interface{} `json:"actions"`
- DisplayName string `json:"displayName"`
- Executors []struct {
- CurrentExecutable struct {
- Number int `json:"number"`
- URL string `json:"url"`
- SubBuilds []struct {
- Abort bool `json:"abort"`
- Build interface{} `json:"build"`
- BuildNumber int `json:"buildNumber"`
- Duration string `json:"duration"`
- Icon string `json:"icon"`
- JobName string `json:"jobName"`
- ParentBuildNumber int `json:"parentBuildNumber"`
- ParentJobName string `json:"parentJobName"`
- PhaseName string `json:"phaseName"`
- Result string `json:"result"`
- Retry bool `json:"retry"`
- URL string `json:"url"`
- } `json:"subBuilds"`
- } `json:"currentExecutable"`
- } `json:"executors"`
- Icon string `json:"icon"`
- IconClassName string `json:"iconClassName"`
- Idle bool `json:"idle"`
- JnlpAgent bool `json:"jnlpAgent"`
- LaunchSupported bool `json:"launchSupported"`
- LoadStatistics struct{} `json:"loadStatistics"`
- ManualLaunchAllowed bool `json:"manualLaunchAllowed"`
- MonitorData struct {
- Hudson_NodeMonitors_ArchitectureMonitor interface{} `json:"hudson.node_monitors.ArchitectureMonitor"`
- Hudson_NodeMonitors_ClockMonitor interface{} `json:"hudson.node_monitors.ClockMonitor"`
- Hudson_NodeMonitors_DiskSpaceMonitor interface{} `json:"hudson.node_monitors.DiskSpaceMonitor"`
- Hudson_NodeMonitors_ResponseTimeMonitor struct {
- Average int64 `json:"average"`
- } `json:"hudson.node_monitors.ResponseTimeMonitor"`
- Hudson_NodeMonitors_SwapSpaceMonitor interface{} `json:"hudson.node_monitors.SwapSpaceMonitor"`
- Hudson_NodeMonitors_TemporarySpaceMonitor interface{} `json:"hudson.node_monitors.TemporarySpaceMonitor"`
- } `json:"monitorData"`
- NumExecutors int64 `json:"numExecutors"`
- Offline bool `json:"offline"`
- OfflineCause struct{} `json:"offlineCause"`
- OfflineCauseReason string `json:"offlineCauseReason"`
- OneOffExecutors []interface{} `json:"oneOffExecutors"`
- TemporarilyOffline bool `json:"temporarilyOffline"`
-}
-
-func (n *Node) Info() (*NodeResponse, error) {
- _, err := n.Poll()
- if err != nil {
- return nil, err
- }
- return n.Raw, nil
-}
-
-func (n *Node) GetName() string {
- return n.Raw.DisplayName
-}
-
-func (n *Node) Delete() (bool, error) {
- resp, err := n.Jenkins.Requester.Post(n.Base+"/doDelete", nil, nil, nil)
- if err != nil {
- return false, err
- }
- return resp.StatusCode == 200, nil
-}
-
-func (n *Node) IsOnline() (bool, error) {
- _, err := n.Poll()
- if err != nil {
- return false, err
- }
- return !n.Raw.Offline, nil
-}
-
-func (n *Node) IsTemporarilyOffline() (bool, error) {
- _, err := n.Poll()
- if err != nil {
- return false, err
- }
- return n.Raw.TemporarilyOffline, nil
-}
-
-func (n *Node) IsIdle() (bool, error) {
- _, err := n.Poll()
- if err != nil {
- return false, err
- }
- return n.Raw.Idle, nil
-}
-
-func (n *Node) IsJnlpAgent() (bool, error) {
- _, err := n.Poll()
- if err != nil {
- return false, err
- }
- return n.Raw.JnlpAgent, nil
-}
-
-func (n *Node) SetOnline() (bool, error) {
- _, err := n.Poll()
-
- if err != nil {
- return false, err
- }
-
- if n.Raw.Offline && !n.Raw.TemporarilyOffline {
- return false, errors.New("Node is Permanently offline, can't bring it up")
- }
-
- if n.Raw.Offline && n.Raw.TemporarilyOffline {
- return n.ToggleTemporarilyOffline()
- }
-
- return true, nil
-}
-
-func (n *Node) SetOffline(options ...interface{}) (bool, error) {
- if !n.Raw.Offline {
- return n.ToggleTemporarilyOffline(options...)
- }
- return false, errors.New("Node already Offline")
-}
-
-func (n *Node) ToggleTemporarilyOffline(options ...interface{}) (bool, error) {
- state_before, err := n.IsTemporarilyOffline()
- if err != nil {
- return false, err
- }
- qr := map[string]string{"offlineMessage": "requested from gojenkins"}
- if len(options) > 0 {
- qr["offlineMessage"] = options[0].(string)
- }
- _, err = n.Jenkins.Requester.Post(n.Base+"/toggleOffline", nil, nil, qr)
- if err != nil {
- return false, err
- }
- new_state, err := n.IsTemporarilyOffline()
- if err != nil {
- return false, err
- }
- if state_before == new_state {
- return false, errors.New("Node state not changed")
- }
- return true, nil
-}
-
-func (n *Node) Poll() (int, error) {
- response, err := n.Jenkins.Requester.GetJSON(n.Base, n.Raw, nil)
- if err != nil {
- return 0, err
- }
- return response.StatusCode, nil
-}
-
-func (n *Node) LaunchNodeBySSH() (int, error) {
- qr := map[string]string{
- "json": "",
- "Submit": "Launch slave agent",
- }
- response, err := n.Jenkins.Requester.Post(n.Base+"/launchSlaveAgent", nil, nil, qr)
- if err != nil {
- return 0, err
- }
- return response.StatusCode, nil
-}
-
-func (n *Node) Disconnect() (int, error) {
- qr := map[string]string{
- "offlineMessage": "",
- "json": makeJson(map[string]string{"offlineMessage": ""}),
- "Submit": "Yes",
- }
- response, err := n.Jenkins.Requester.Post(n.Base+"/doDisconnect", nil, nil, qr)
- if err != nil {
- return 0, err
- }
- return response.StatusCode, nil
-}
-
-func (n *Node) GetLogText() (string, error) {
- var log string
-
- _, err := n.Jenkins.Requester.Post(n.Base+"/log", nil, nil, nil)
- if err != nil {
- return "", err
- }
-
- qr := map[string]string{"start": "0"}
- _, err = n.Jenkins.Requester.GetJSON(n.Base+"/logText/progressiveHtml/", &log, qr)
- if err != nil {
- return "", nil
- }
-
- return log, nil
-}
diff --git a/pkg/gojenkins/plugin.go b/pkg/gojenkins/plugin.go
deleted file mode 100644
index 5e44717db37f62b5ac18e4709e565ebf00e3a2bf..0000000000000000000000000000000000000000
--- a/pkg/gojenkins/plugin.go
+++ /dev/null
@@ -1,75 +0,0 @@
-// Copyright 2015 Vadim Kravcenko
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package gojenkins
-
-import (
- "strconv"
-)
-
-type Plugins struct {
- Jenkins *Jenkins
- Raw *PluginResponse
- Base string
- Depth int
-}
-
-type PluginResponse struct {
- Plugins []Plugin `json:"plugins"`
-}
-
-type Plugin struct {
- Active bool `json:"active"`
- BackupVersion interface{} `json:"backupVersion"`
- Bundled bool `json:"bundled"`
- Deleted bool `json:"deleted"`
- Dependencies []struct {
- Optional string `json:"optional"`
- ShortName string `json:"shortname"`
- Version string `json:"version"`
- } `json:"dependencies"`
- Downgradable bool `json:"downgradable"`
- Enabled bool `json:"enabled"`
- HasUpdate bool `json:"hasUpdate"`
- LongName string `json:"longName"`
- Pinned bool `json:"pinned"`
- ShortName string `json:"shortName"`
- SupportsDynamicLoad string `json:"supportsDynamicLoad"`
- URL string `json:"url"`
- Version string `json:"version"`
-}
-
-func (p *Plugins) Count() int {
- return len(p.Raw.Plugins)
-}
-
-func (p *Plugins) Contains(name string) *Plugin {
- for _, p := range p.Raw.Plugins {
- if p.LongName == name || p.ShortName == name {
- return &p
- }
- }
- return nil
-}
-
-func (p *Plugins) Poll() (int, error) {
- qr := map[string]string{
- "depth": strconv.Itoa(p.Depth),
- }
- response, err := p.Jenkins.Requester.GetJSON(p.Base, p.Raw, qr)
- if err != nil {
- return 0, err
- }
- return response.StatusCode, nil
-}
diff --git a/pkg/gojenkins/queue.go b/pkg/gojenkins/queue.go
deleted file mode 100644
index e73c939b5dea136e379afe07960b43391aa67648..0000000000000000000000000000000000000000
--- a/pkg/gojenkins/queue.go
+++ /dev/null
@@ -1,158 +0,0 @@
-// Copyright 2015 Vadim Kravcenko
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package gojenkins
-
-import (
- "strconv"
-)
-
-type Queue struct {
- Jenkins *Jenkins
- Raw *queueResponse
- Base string
-}
-
-type queueResponse struct {
- Items []taskResponse
-}
-
-type Task struct {
- Raw *taskResponse
- Jenkins *Jenkins
- Queue *Queue
-}
-
-type taskResponse struct {
- Actions []generalAction `json:"actions"`
- Blocked bool `json:"blocked"`
- Buildable bool `json:"buildable"`
- BuildableStartMilliseconds int64 `json:"buildableStartMilliseconds"`
- ID int64 `json:"id"`
- InQueueSince int64 `json:"inQueueSince"`
- Params string `json:"params"`
- Pending bool `json:"pending"`
- Stuck bool `json:"stuck"`
- Task struct {
- Color string `json:"color"`
- Name string `json:"name"`
- URL string `json:"url"`
- } `json:"task"`
- URL string `json:"url"`
- Why string `json:"why"`
-}
-
-type generalAction struct {
- Causes []map[string]interface{}
- Parameters []parameter
-}
-
-type QueueItemResponse struct {
- Actions []generalAction `json:"actions"`
- Blocked bool `json:"blocked"`
- Buildable bool `json:"buildable"`
- ID int64 `json:"id"`
- InQueueSince int64 `json:"inQueueSince"`
- Params string `json:"params"`
- Stuck bool `json:"stuck"`
- Task struct {
- Color string `json:"color"`
- Name string `json:"name"`
- URL string `json:"url"`
- } `json:"task"`
- URL string `json:"url"`
- Cancelled bool `json:"cancelled"`
- Why string `json:"why"`
- Executable struct {
- Number int64 `json:"number"`
- Url string `json:"url"`
- } `json:"executable"`
-}
-
-func (q *Queue) Tasks() []*Task {
- tasks := make([]*Task, len(q.Raw.Items))
- for i, t := range q.Raw.Items {
- tasks[i] = &Task{Jenkins: q.Jenkins, Queue: q, Raw: &t}
- }
- return tasks
-}
-
-func (q *Queue) GetTaskById(id int64) *Task {
- for _, t := range q.Raw.Items {
- if t.ID == id {
- return &Task{Jenkins: q.Jenkins, Queue: q, Raw: &t}
- }
- }
- return nil
-}
-
-func (q *Queue) GetTasksForJob(name string) []*Task {
- tasks := make([]*Task, 0)
- for _, t := range q.Raw.Items {
- if t.Task.Name == name {
- tasks = append(tasks, &Task{Jenkins: q.Jenkins, Queue: q, Raw: &t})
- }
- }
- return tasks
-}
-
-func (q *Queue) CancelTask(id int64) (bool, error) {
- task := q.GetTaskById(id)
- return task.Cancel()
-}
-
-func (t *Task) Cancel() (bool, error) {
- qr := map[string]string{
- "id": strconv.FormatInt(t.Raw.ID, 10),
- }
- response, err := t.Jenkins.Requester.Post(t.Jenkins.GetQueueUrl()+"/cancelItem", nil, t.Raw, qr)
- if err != nil {
- return false, err
- }
- return response.StatusCode == 200, nil
-}
-
-func (t *Task) GetJob() (*Job, error) {
- return t.Jenkins.GetJob(t.Raw.Task.Name)
-}
-
-func (t *Task) GetWhy() string {
- return t.Raw.Why
-}
-
-func (t *Task) GetParameters() []parameter {
- for _, a := range t.Raw.Actions {
- if a.Parameters != nil {
- return a.Parameters
- }
- }
- return nil
-}
-
-func (t *Task) GetCauses() []map[string]interface{} {
- for _, a := range t.Raw.Actions {
- if a.Causes != nil {
- return a.Causes
- }
- }
- return nil
-}
-
-func (q *Queue) Poll() (int, error) {
- response, err := q.Jenkins.Requester.GetJSON(q.Base, q.Raw, nil)
- if err != nil {
- return 0, err
- }
- return response.StatusCode, nil
-}
diff --git a/pkg/gojenkins/utils.go b/pkg/gojenkins/utils.go
deleted file mode 100644
index 92b714492ebf4041ccfba5c99c29f264e79807f7..0000000000000000000000000000000000000000
--- a/pkg/gojenkins/utils.go
+++ /dev/null
@@ -1,61 +0,0 @@
-// Copyright 2015 Vadim Kravcenko
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package gojenkins
-
-import (
- "encoding/json"
- "strings"
- "time"
- "unicode/utf8"
-)
-
-func makeJson(data interface{}) string {
- str, err := json.Marshal(data)
- if err != nil {
- return ""
- }
- return string(json.RawMessage(str))
-}
-
-func Reverse(s string) string {
- size := len(s)
- buf := make([]byte, size)
- for start := 0; start < size; {
- r, n := utf8.DecodeRuneInString(s[start:])
- start += n
- utf8.EncodeRune(buf[size-start:], r)
- }
- return string(buf)
-}
-
-type JenkinsBlueTime time.Time
-
-func (t *JenkinsBlueTime) UnmarshalJSON(b []byte) error {
- if b == nil || strings.Trim(string(b), "\"") == "null" {
- *t = JenkinsBlueTime(time.Time{})
- return nil
- }
- j, err := time.Parse("2006-01-02T15:04:05.000-0700", strings.Trim(string(b), "\""))
-
- if err != nil {
- return err
- }
- *t = JenkinsBlueTime(j)
- return nil
-}
-
-func (t JenkinsBlueTime) MarshalJSON() ([]byte, error) {
- return json.Marshal(time.Time(t))
-}
diff --git a/pkg/gojenkins/utils/utils.go b/pkg/gojenkins/utils/utils.go
deleted file mode 100644
index 93ad30b3be13a54567cd87c522813ca834ba2a04..0000000000000000000000000000000000000000
--- a/pkg/gojenkins/utils/utils.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package utils
-
-import (
- "github.com/asaskevich/govalidator"
- "kubesphere.io/kubesphere/pkg/gojenkins"
- "net/http"
- "strconv"
-)
-
-func GetJenkinsStatusCode(jenkinsErr error) int {
- if code, err := strconv.Atoi(jenkinsErr.Error()); err == nil {
- message := http.StatusText(code)
- if !govalidator.IsNull(message) {
- return code
- }
- }
- if jErr, ok := jenkinsErr.(*gojenkins.ErrorResponse); ok {
- return jErr.Response.StatusCode
- }
- return http.StatusInternalServerError
-}
diff --git a/pkg/gojenkins/views.go b/pkg/gojenkins/views.go
deleted file mode 100644
index 99b802643ad77f2e7721b505af68e7553c44db7c..0000000000000000000000000000000000000000
--- a/pkg/gojenkins/views.go
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright 2015 Vadim Kravcenko
-//
-// Licensed under the Apache License, Version 2.0 (the "License"): you may
-// not use this file except in compliance with the License. You may obtain
-// a copy of the License at
-//
-// http://www.apache.org/licenses/LICENSE-2.0
-//
-// Unless required by applicable law or agreed to in writing, software
-// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
-// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
-// License for the specific language governing permissions and limitations
-// under the License.
-
-package gojenkins
-
-import (
- "errors"
- "strconv"
-)
-
-type View struct {
- Raw *ViewResponse
- Jenkins *Jenkins
- Base string
-}
-
-type ViewResponse struct {
- Description string `json:"description"`
- Jobs []InnerJob `json:"jobs"`
- Name string `json:"name"`
- Property []interface{} `json:"property"`
- URL string `json:"url"`
-}
-
-var (
- LIST_VIEW = "hudson.model.ListView"
- NESTED_VIEW = "hudson.plugins.nested_view.NestedView"
- MY_VIEW = "hudson.model.MyView"
- DASHBOARD_VIEW = "hudson.plugins.view.dashboard.Dashboard"
- PIPELINE_VIEW = "au.com.centrumsystems.hudson.plugin.buildpipeline.BuildPipelineView"
-)
-
-// Returns True if successfully added Job, otherwise false
-func (v *View) AddJob(name string) (bool, error) {
- url := "/addJobToView"
- qr := map[string]string{"name": name}
- resp, err := v.Jenkins.Requester.Post(v.Base+url, nil, nil, qr)
- if err != nil {
- return false, err
- }
- if resp.StatusCode == 200 {
- return true, nil
- }
- return false, errors.New(strconv.Itoa(resp.StatusCode))
-}
-
-// Returns True if successfully deleted Job, otherwise false
-func (v *View) DeleteJob(name string) (bool, error) {
- url := "/removeJobFromView"
- qr := map[string]string{"name": name}
- resp, err := v.Jenkins.Requester.Post(v.Base+url, nil, nil, qr)
- if err != nil {
- return false, err
- }
- if resp.StatusCode == 200 {
- return true, nil
- }
- return false, errors.New(strconv.Itoa(resp.StatusCode))
-}
-
-func (v *View) GetDescription() string {
- return v.Raw.Description
-}
-
-func (v *View) GetJobs() []InnerJob {
- return v.Raw.Jobs
-}
-
-func (v *View) GetName() string {
- return v.Raw.Name
-}
-
-func (v *View) GetUrl() string {
- return v.Raw.URL
-}
-
-func (v *View) Poll() (int, error) {
- response, err := v.Jenkins.Requester.GetJSON(v.Base, v.Raw, nil)
- if err != nil {
- return 0, err
- }
- return response.StatusCode, nil
-}
diff --git a/pkg/apiserver/devops/OWNERS b/pkg/kapis/devops/v1alpha2/OWNERS
similarity index 100%
rename from pkg/apiserver/devops/OWNERS
rename to pkg/kapis/devops/v1alpha2/OWNERS
diff --git a/pkg/apiserver/devops/devops.go b/pkg/kapis/devops/v1alpha2/devops.go
similarity index 55%
rename from pkg/apiserver/devops/devops.go
rename to pkg/kapis/devops/v1alpha2/devops.go
index a4277c5e32ff92ca696821c9f5c776f68a570f54..d7aea16c59363f53ae0b6d2dbbd5ababe7b039ca 100644
--- a/pkg/apiserver/devops/devops.go
+++ b/pkg/kapis/devops/v1alpha2/devops.go
@@ -15,10 +15,9 @@
limitations under the License.
*/
-package devops
+package v1alpha2
import (
- "encoding/json"
"github.com/emicklei/go-restful"
log "k8s.io/klog"
"kubesphere.io/kubesphere/pkg/models/devops"
@@ -28,328 +27,319 @@ import (
const jenkinsHeaderPre = "X-"
-func GetPipeline(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) GetPipeline(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
- res, err := devops.GetPipeline(projectName, pipelineName, req.Request)
+ res, err := h.devopsOperator.GetPipeline(projectName, pipelineName, req.Request)
if err != nil {
parseErr(err, resp)
return
}
resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func SearchPipelines(req *restful.Request, resp *restful.Response) {
- res, err := devops.SearchPipelines(req.Request)
+func (h *ProjectPipelineHandler) ListPipelines(req *restful.Request, resp *restful.Response) {
+ res, err := h.devopsOperator.ListPipelines(req.Request)
if err != nil {
parseErr(err, resp)
return
}
resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func SearchPipelineRuns(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) GetPipelineRun(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
+ runId := req.PathParameter("run")
- res, err := devops.SearchPipelineRuns(projectName, pipelineName, req.Request)
+ res, err := h.devopsOperator.GetPipelineRun(projectName, pipelineName, runId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func GetBranchPipelineRun(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) ListPipelineRuns(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
- branchName := req.PathParameter("branch")
- runId := req.PathParameter("run")
- res, err := devops.GetBranchPipelineRun(projectName, pipelineName, branchName, runId, req.Request)
+ res, err := h.devopsOperator.ListPipelineRuns(projectName, pipelineName, req.Request)
if err != nil {
parseErr(err, resp)
return
}
resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func GetPipelineRunNodesbyBranch(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) StopPipeline(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
- branchName := req.PathParameter("branch")
runId := req.PathParameter("run")
- res, err := devops.GetPipelineRunNodesbyBranch(projectName, pipelineName, branchName, runId, req.Request)
+ res, err := h.devopsOperator.StopPipeline(projectName, pipelineName, runId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func GetBranchStepLog(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) ReplayPipeline(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
- branchName := req.PathParameter("branch")
runId := req.PathParameter("run")
- nodeId := req.PathParameter("node")
- stepId := req.PathParameter("step")
-
- res, header, err := devops.GetBranchStepLog(projectName, pipelineName, branchName, runId, nodeId, stepId, req.Request)
+ res, err := h.devopsOperator.ReplayPipeline(projectName, pipelineName, runId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
- for k, v := range header {
- if strings.HasPrefix(k, jenkinsHeaderPre) {
- resp.AddHeader(k, v[0])
- }
- }
- resp.Write(res)
+
+ resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
+ resp.WriteAsJson(res)
}
-func GetStepLog(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) RunPipeline(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
- runId := req.PathParameter("run")
- nodeId := req.PathParameter("node")
- stepId := req.PathParameter("step")
- res, header, err := devops.GetStepLog(projectName, pipelineName, runId, nodeId, stepId, req.Request)
+ res, err := h.devopsOperator.RunPipeline(projectName, pipelineName, req.Request)
if err != nil {
parseErr(err, resp)
return
}
- for k, v := range header {
- if strings.HasPrefix(k, jenkinsHeaderPre) {
- resp.AddHeader(k, v[0])
- }
- }
- resp.Write(res)
+
+ resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
+ resp.WriteAsJson(res)
}
-func GetSCMServers(req *restful.Request, resp *restful.Response) {
- scmId := req.PathParameter("scm")
+func (h *ProjectPipelineHandler) GetArtifacts(req *restful.Request, resp *restful.Response) {
+ projectName := req.PathParameter("devops")
+ pipelineName := req.PathParameter("pipeline")
+ runId := req.PathParameter("run")
- res, err := devops.GetSCMServers(scmId, req.Request)
+ res, err := h.devopsOperator.GetArtifacts(projectName, pipelineName, runId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
-
resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func CreateSCMServers(req *restful.Request, resp *restful.Response) {
- scmId := req.PathParameter("scm")
+func (h *ProjectPipelineHandler) GetRunLog(req *restful.Request, resp *restful.Response) {
+ projectName := req.PathParameter("devops")
+ pipelineName := req.PathParameter("pipeline")
+ runId := req.PathParameter("run")
- res, err := devops.CreateSCMServers(scmId, req.Request)
+ res, err := h.devopsOperator.GetRunLog(projectName, pipelineName, runId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
- resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
resp.Write(res)
}
-func Validate(req *restful.Request, resp *restful.Response) {
- scmId := req.PathParameter("scm")
+func (h *ProjectPipelineHandler) GetStepLog(req *restful.Request, resp *restful.Response) {
+ projectName := req.PathParameter("devops")
+ pipelineName := req.PathParameter("pipeline")
+ runId := req.PathParameter("run")
+ nodeId := req.PathParameter("node")
+ stepId := req.PathParameter("step")
- res, err := devops.Validate(scmId, req.Request)
+ res, header, err := h.devopsOperator.GetStepLog(projectName, pipelineName, runId, nodeId, stepId, req.Request)
if err != nil {
- log.Error(err)
- if jErr, ok := err.(*devops.JkError); ok {
- if jErr.Code != http.StatusUnauthorized {
- resp.WriteError(jErr.Code, err)
- } else {
- resp.WriteHeader(http.StatusPreconditionRequired)
- }
- } else {
- resp.WriteError(http.StatusInternalServerError, err)
- }
+ parseErr(err, resp)
return
}
-
- resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
+ for k, v := range header {
+ if strings.HasPrefix(k, jenkinsHeaderPre) {
+ resp.AddHeader(k, v[0])
+ }
+ }
resp.Write(res)
}
-func GetSCMOrg(req *restful.Request, resp *restful.Response) {
- scmId := req.PathParameter("scm")
+func (h *ProjectPipelineHandler) GetNodeSteps(req *restful.Request, resp *restful.Response) {
+ projectName := req.PathParameter("devops")
+ pipelineName := req.PathParameter("pipeline")
+ runId := req.PathParameter("run")
+ nodeId := req.PathParameter("node")
- res, err := devops.GetSCMOrg(scmId, req.Request)
+ res, err := h.devopsOperator.GetNodeSteps(projectName, pipelineName, runId, nodeId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
-
resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func GetOrgRepo(req *restful.Request, resp *restful.Response) {
- scmId := req.PathParameter("scm")
- organizationId := req.PathParameter("organization")
+func (h *ProjectPipelineHandler) GetPipelineRunNodes(req *restful.Request, resp *restful.Response) {
+ projectName := req.PathParameter("devops")
+ pipelineName := req.PathParameter("pipeline")
+ runId := req.PathParameter("run")
- res, err := devops.GetOrgRepo(scmId, organizationId, req.Request)
+ res, err := h.devopsOperator.GetPipelineRunNodes(projectName, pipelineName, runId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
-
resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func StopBranchPipeline(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) SubmitInputStep(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
- branchName := req.PathParameter("branch")
runId := req.PathParameter("run")
+ nodeId := req.PathParameter("node")
+ stepId := req.PathParameter("step")
- res, err := devops.StopBranchPipeline(projectName, pipelineName, branchName, runId, req.Request)
+ res, err := h.devopsOperator.SubmitInputStep(projectName, pipelineName, runId, nodeId, stepId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
- resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
resp.Write(res)
}
-func StopPipeline(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) GetNodesDetail(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
runId := req.PathParameter("run")
- res, err := devops.StopPipeline(projectName, pipelineName, runId, req.Request)
+ res, err := h.devopsOperator.GetNodesDetail(projectName, pipelineName, runId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
-
- resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func ReplayBranchPipeline(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) GetBranchPipeline(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
branchName := req.PathParameter("branch")
- runId := req.PathParameter("run")
- res, err := devops.ReplayBranchPipeline(projectName, pipelineName, branchName, runId, req.Request)
+ res, err := h.devopsOperator.GetBranchPipeline(projectName, pipelineName, branchName, req.Request)
if err != nil {
parseErr(err, resp)
return
}
resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func ReplayPipeline(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) GetBranchPipelineRun(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
+ branchName := req.PathParameter("branch")
runId := req.PathParameter("run")
- res, err := devops.ReplayPipeline(projectName, pipelineName, runId, req.Request)
+ res, err := h.devopsOperator.GetBranchPipelineRun(projectName, pipelineName, branchName, runId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func GetBranchRunLog(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) StopBranchPipeline(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
branchName := req.PathParameter("branch")
runId := req.PathParameter("run")
- res, err := devops.GetBranchRunLog(projectName, pipelineName, branchName, runId, req.Request)
+ res, err := h.devopsOperator.StopBranchPipeline(projectName, pipelineName, branchName, runId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
- resp.Write(res)
+ resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
+ resp.WriteAsJson(res)
}
-func GetRunLog(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) ReplayBranchPipeline(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
+ branchName := req.PathParameter("branch")
runId := req.PathParameter("run")
- res, err := devops.GetRunLog(projectName, pipelineName, runId, req.Request)
+ res, err := h.devopsOperator.ReplayBranchPipeline(projectName, pipelineName, branchName, runId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
- resp.Write(res)
+ resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
+ resp.WriteAsJson(res)
}
-func GetBranchArtifacts(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) RunBranchPipeline(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
branchName := req.PathParameter("branch")
- runId := req.PathParameter("run")
- res, err := devops.GetBranchArtifacts(projectName, pipelineName, branchName, runId, req.Request)
+ res, err := h.devopsOperator.RunBranchPipeline(projectName, pipelineName, branchName, req.Request)
if err != nil {
parseErr(err, resp)
return
}
+
resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func GetArtifacts(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) GetBranchArtifacts(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
+ branchName := req.PathParameter("branch")
runId := req.PathParameter("run")
- res, err := devops.GetArtifacts(projectName, pipelineName, runId, req.Request)
+ res, err := h.devopsOperator.GetBranchArtifacts(projectName, pipelineName, branchName, runId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func GetPipeBranch(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) GetBranchRunLog(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
+ branchName := req.PathParameter("branch")
+ runId := req.PathParameter("run")
- res, err := devops.GetPipeBranch(projectName, pipelineName, req.Request)
+ res, err := h.devopsOperator.GetBranchRunLog(projectName, pipelineName, branchName, runId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
- resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
+
resp.Write(res)
}
-func SubmitBranchInputStep(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) GetBranchStepLog(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
branchName := req.PathParameter("branch")
@@ -357,49 +347,61 @@ func SubmitBranchInputStep(req *restful.Request, resp *restful.Response) {
nodeId := req.PathParameter("node")
stepId := req.PathParameter("step")
- res, err := devops.SubmitBranchInputStep(projectName, pipelineName, branchName, runId, nodeId, stepId, req.Request)
+ res, header, err := h.devopsOperator.GetBranchStepLog(projectName, pipelineName, branchName, runId, nodeId, stepId, req.Request)
+
if err != nil {
parseErr(err, resp)
return
}
-
+ for k, v := range header {
+ if strings.HasPrefix(k, jenkinsHeaderPre) {
+ resp.AddHeader(k, v[0])
+ }
+ }
resp.Write(res)
}
-func SubmitInputStep(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) GetBranchNodeSteps(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
+ branchName := req.PathParameter("branch")
runId := req.PathParameter("run")
nodeId := req.PathParameter("node")
- stepId := req.PathParameter("step")
- res, err := devops.SubmitInputStep(projectName, pipelineName, runId, nodeId, stepId, req.Request)
+ res, err := h.devopsOperator.GetBranchNodeSteps(projectName, pipelineName, branchName, runId, nodeId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
-
- resp.Write(res)
+ resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
+ resp.WriteAsJson(res)
}
-func GetConsoleLog(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) GetBranchPipelineRunNodes(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
+ branchName := req.PathParameter("branch")
+ runId := req.PathParameter("run")
- res, err := devops.GetConsoleLog(projectName, pipelineName, req.Request)
+ res, err := h.devopsOperator.GetBranchPipelineRunNodes(projectName, pipelineName, branchName, runId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
- resp.Write(res)
+ resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
+ resp.WriteAsJson(res)
}
-func ScanBranch(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) SubmitBranchInputStep(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
+ branchName := req.PathParameter("branch")
+ runId := req.PathParameter("run")
+ nodeId := req.PathParameter("node")
+ stepId := req.PathParameter("step")
- res, err := devops.ScanBranch(projectName, pipelineName, req.Request)
+ res, err := h.devopsOperator.SubmitBranchInputStep(projectName, pipelineName, branchName, runId, nodeId, stepId, req.Request)
if err != nil {
parseErr(err, resp)
return
@@ -408,77 +410,61 @@ func ScanBranch(req *restful.Request, resp *restful.Response) {
resp.Write(res)
}
-func RunBranchPipeline(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) GetBranchNodesDetail(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
branchName := req.PathParameter("branch")
+ runId := req.PathParameter("run")
- res, err := devops.RunBranchPipeline(projectName, pipelineName, branchName, req.Request)
+ res, err := h.devopsOperator.GetBranchNodesDetail(projectName, pipelineName, branchName, runId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
-
- resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func RunPipeline(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) GetPipelineBranch(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
- res, err := devops.RunPipeline(projectName, pipelineName, req.Request)
+ res, err := h.devopsOperator.GetPipelineBranch(projectName, pipelineName, req.Request)
if err != nil {
parseErr(err, resp)
return
}
-
resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func GetCrumb(req *restful.Request, resp *restful.Response) {
- res, err := devops.GetCrumb(req.Request)
+func (h *ProjectPipelineHandler) ScanBranch(req *restful.Request, resp *restful.Response) {
+ projectName := req.PathParameter("devops")
+ pipelineName := req.PathParameter("pipeline")
+
+ res, err := h.devopsOperator.ScanBranch(projectName, pipelineName, req.Request)
if err != nil {
parseErr(err, resp)
return
}
- resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
resp.Write(res)
}
-func CheckScriptCompile(req *restful.Request, resp *restful.Response) {
+func (h *ProjectPipelineHandler) GetConsoleLog(req *restful.Request, resp *restful.Response) {
projectName := req.PathParameter("devops")
pipelineName := req.PathParameter("pipeline")
- resBody, err := devops.CheckScriptCompile(projectName, pipelineName, req.Request)
+ res, err := h.devopsOperator.GetConsoleLog(projectName, pipelineName, req.Request)
if err != nil {
parseErr(err, resp)
return
}
- // Jenkins will return different struct according to different results.
- var resJson = new(devops.CheckScript)
- if ok := json.Unmarshal(resBody, &resJson); ok != nil {
- var resJson []interface{}
- err := json.Unmarshal(resBody, &resJson)
- if err != nil {
- resp.WriteError(http.StatusInternalServerError, err)
- return
- }
- resp.WriteAsJson(resJson[0])
- return
-
- }
-
- resp.WriteAsJson(resJson)
+ resp.Write(res)
}
-func CheckCron(req *restful.Request, resp *restful.Response) {
- projectName := req.PathParameter("devops")
-
- res, err := devops.CheckCron(projectName, req.Request)
+func (h *ProjectPipelineHandler) GetCrumb(req *restful.Request, resp *restful.Response) {
+ res, err := h.devopsOperator.GetCrumb(req.Request)
if err != nil {
parseErr(err, resp)
return
@@ -488,103 +474,101 @@ func CheckCron(req *restful.Request, resp *restful.Response) {
resp.WriteAsJson(res)
}
-func GetPipelineRun(req *restful.Request, resp *restful.Response) {
- projectName := req.PathParameter("devops")
- pipelineName := req.PathParameter("pipeline")
- runId := req.PathParameter("run")
+func (h *ProjectPipelineHandler) GetSCMServers(req *restful.Request, resp *restful.Response) {
+ scmId := req.PathParameter("scm")
- res, err := devops.GetPipelineRun(projectName, pipelineName, runId, req.Request)
+ res, err := h.devopsOperator.GetSCMServers(scmId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func GetBranchPipeline(req *restful.Request, resp *restful.Response) {
- projectName := req.PathParameter("devops")
- pipelineName := req.PathParameter("pipeline")
- branchName := req.PathParameter("branch")
+func (h *ProjectPipelineHandler) GetSCMOrg(req *restful.Request, resp *restful.Response) {
+ scmId := req.PathParameter("scm")
- res, err := devops.GetBranchPipeline(projectName, pipelineName, branchName, req.Request)
+ res, err := h.devopsOperator.GetSCMOrg(scmId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func GetPipelineRunNodes(req *restful.Request, resp *restful.Response) {
- projectName := req.PathParameter("devops")
- pipelineName := req.PathParameter("pipeline")
- runId := req.PathParameter("run")
+func (h *ProjectPipelineHandler) GetOrgRepo(req *restful.Request, resp *restful.Response) {
+ scmId := req.PathParameter("scm")
+ organizationId := req.PathParameter("organization")
- res, err := devops.GetPipelineRunNodes(projectName, pipelineName, runId, req.Request)
+ res, err := h.devopsOperator.GetOrgRepo(scmId, organizationId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
+
resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func GetBranchNodeSteps(req *restful.Request, resp *restful.Response) {
- projectName := req.PathParameter("devops")
- pipelineName := req.PathParameter("pipeline")
- branchName := req.PathParameter("branch")
- runId := req.PathParameter("run")
- nodeId := req.PathParameter("node")
+func (h *ProjectPipelineHandler) CreateSCMServers(req *restful.Request, resp *restful.Response) {
+ scmId := req.PathParameter("scm")
- res, err := devops.GetBranchNodeSteps(projectName, pipelineName, branchName, runId, nodeId, req.Request)
+ res, err := h.devopsOperator.CreateSCMServers(scmId, req.Request)
if err != nil {
parseErr(err, resp)
return
}
+
resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func GetNodeSteps(req *restful.Request, resp *restful.Response) {
- projectName := req.PathParameter("devops")
- pipelineName := req.PathParameter("pipeline")
- runId := req.PathParameter("run")
- nodeId := req.PathParameter("node")
+func (h *ProjectPipelineHandler) Validate(req *restful.Request, resp *restful.Response) {
+ scmId := req.PathParameter("scm")
- res, err := devops.GetNodeSteps(projectName, pipelineName, runId, nodeId, req.Request)
+ res, err := h.devopsOperator.Validate(scmId, req.Request)
if err != nil {
- parseErr(err, resp)
+ log.Error(err)
+ if jErr, ok := err.(*devops.JkError); ok {
+ if jErr.Code != http.StatusUnauthorized {
+ resp.WriteError(jErr.Code, err)
+ } else {
+ resp.WriteHeader(http.StatusPreconditionRequired)
+ }
+ } else {
+ resp.WriteError(http.StatusInternalServerError, err)
+ }
return
}
+
resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
- resp.Write(res)
+ resp.WriteAsJson(res)
}
-func ToJenkinsfile(req *restful.Request, resp *restful.Response) {
- res, err := devops.ToJenkinsfile(req.Request)
+func (h *ProjectPipelineHandler) GetNotifyCommit(req *restful.Request, resp *restful.Response) {
+ res, err := h.devopsOperator.GetNotifyCommit(req.Request)
if err != nil {
parseErr(err, resp)
return
}
- resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
resp.Write(res)
}
-func ToJson(req *restful.Request, resp *restful.Response) {
- res, err := devops.ToJson(req.Request)
+func (h *ProjectPipelineHandler) PostNotifyCommit(req *restful.Request, resp *restful.Response) {
+ res, err := h.devopsOperator.GetNotifyCommit(req.Request)
if err != nil {
parseErr(err, resp)
return
}
- resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
resp.Write(res)
}
-func GetNotifyCommit(req *restful.Request, resp *restful.Response) {
- res, err := devops.GetNotifyCommit(req.Request)
+func (h *ProjectPipelineHandler) GithubWebhook(req *restful.Request, resp *restful.Response) {
+ res, err := h.devopsOperator.GithubWebhook(req.Request)
if err != nil {
parseErr(err, resp)
return
@@ -592,47 +576,49 @@ func GetNotifyCommit(req *restful.Request, resp *restful.Response) {
resp.Write(res)
}
-func PostNotifyCommit(req *restful.Request, resp *restful.Response) {
- res, err := devops.GetNotifyCommit(req.Request)
+func (h *ProjectPipelineHandler) CheckScriptCompile(req *restful.Request, resp *restful.Response) {
+ projectName := req.PathParameter("devops")
+ pipelineName := req.PathParameter("pipeline")
+
+ resBody, err := h.devopsOperator.CheckScriptCompile(projectName, pipelineName, req.Request)
if err != nil {
parseErr(err, resp)
return
}
- resp.Write(res)
+
+ resp.WriteAsJson(resBody)
}
-func GithubWebhook(req *restful.Request, resp *restful.Response) {
- res, err := devops.GithubWebhook(req.Request)
+
+func (h *ProjectPipelineHandler) CheckCron(req *restful.Request, resp *restful.Response) {
+ projectName := req.PathParameter("devops")
+
+ res, err := h.devopsOperator.CheckCron(projectName, req.Request)
if err != nil {
parseErr(err, resp)
return
}
- resp.Write(res)
-}
-func GetBranchNodesDetail(req *restful.Request, resp *restful.Response) {
- projectName := req.PathParameter("devops")
- pipelineName := req.PathParameter("pipeline")
- branchName := req.PathParameter("branch")
- runId := req.PathParameter("run")
+ resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
+ resp.WriteAsJson(res)
+}
- res, err := devops.GetBranchNodesDetail(projectName, pipelineName, branchName, runId, req.Request)
+func (h *ProjectPipelineHandler) ToJenkinsfile(req *restful.Request, resp *restful.Response) {
+ res, err := h.devopsOperator.ToJenkinsfile(req.Request)
if err != nil {
parseErr(err, resp)
return
}
+ resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
resp.WriteAsJson(res)
}
-func GetNodesDetail(req *restful.Request, resp *restful.Response) {
- projectName := req.PathParameter("devops")
- pipelineName := req.PathParameter("pipeline")
- runId := req.PathParameter("run")
-
- res, err := devops.GetNodesDetail(projectName, pipelineName, runId, req.Request)
+func (h *ProjectPipelineHandler) ToJson(req *restful.Request, resp *restful.Response) {
+ res, err := h.devopsOperator.ToJson(req.Request)
if err != nil {
parseErr(err, resp)
return
}
+ resp.Header().Set(restful.HEADER_ContentType, restful.MIME_JSON)
resp.WriteAsJson(res)
}
diff --git a/pkg/kapis/devops/v1alpha2/handler.go b/pkg/kapis/devops/v1alpha2/handler.go
index aaaf31cd3afc5823aec7a3853c6593e7771cac85..3ad4daae6c6eecad80063f6478fda5093f7ab605 100644
--- a/pkg/kapis/devops/v1alpha2/handler.go
+++ b/pkg/kapis/devops/v1alpha2/handler.go
@@ -1 +1,43 @@
package v1alpha2
+
+import (
+ "kubesphere.io/kubesphere/pkg/client/clientset/versioned"
+ "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
+ "kubesphere.io/kubesphere/pkg/models/devops"
+ devopsClient "kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "kubesphere.io/kubesphere/pkg/simple/client/mysql"
+ "kubesphere.io/kubesphere/pkg/simple/client/s3"
+ "kubesphere.io/kubesphere/pkg/simple/client/sonarqube"
+)
+
+type ProjectPipelineHandler struct {
+ projectCredentialOperator devops.ProjectCredentialOperator
+ projectMemberOperator devops.ProjectMemberOperator
+ projectPipelineOperator devops.ProjectPipelineOperator
+ devopsOperator devops.DevopsOperator
+ projectOperator devops.ProjectOperator
+}
+
+type PipelineSonarHandler struct {
+ pipelineSonarGetter devops.PipelineSonarGetter
+}
+
+func NewProjectPipelineHandler(devopsClient devopsClient.Interface, dbClient *mysql.Database) ProjectPipelineHandler {
+ return ProjectPipelineHandler{
+ projectCredentialOperator: devops.NewProjectCredentialOperator(devopsClient, dbClient),
+ projectMemberOperator: devops.NewProjectMemberOperator(devopsClient, dbClient),
+ projectPipelineOperator: devops.NewProjectPipelineOperator(devopsClient),
+ devopsOperator: devops.NewDevopsOperator(devopsClient),
+ projectOperator: devops.NewProjectOperator(dbClient),
+ }
+}
+
+func NewPipelineSonarHandler(devopsClient devopsClient.Interface, sonarClient sonarqube.SonarInterface) PipelineSonarHandler {
+ return PipelineSonarHandler{
+ pipelineSonarGetter: devops.NewPipelineSonarGetter(devopsClient, sonarClient),
+ }
+}
+
+func NewS2iBinaryHandler(client versioned.Interface, informers externalversions.SharedInformerFactory, s3Client s3.Interface) S2iBinaryHandler {
+ return S2iBinaryHandler{devops.NewS2iBinaryUploader(client, informers, s3Client)}
+}
diff --git a/pkg/apiserver/devops/member.go b/pkg/kapis/devops/v1alpha2/member.go
similarity index 73%
rename from pkg/apiserver/devops/member.go
rename to pkg/kapis/devops/v1alpha2/member.go
index d168e833d33249a1db932bca1973f15afd141542..42a4b15616120c42ed151f55ef630ac73d2db4dd 100644
--- a/pkg/apiserver/devops/member.go
+++ b/pkg/kapis/devops/v1alpha2/member.go
@@ -11,7 +11,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-package devops
+package v1alpha2
import (
"fmt"
@@ -19,19 +19,19 @@ import (
"github.com/emicklei/go-restful"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/constants"
- "kubesphere.io/kubesphere/pkg/models/devops"
"kubesphere.io/kubesphere/pkg/server/errors"
"kubesphere.io/kubesphere/pkg/server/params"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
"kubesphere.io/kubesphere/pkg/utils/reflectutils"
"net/http"
)
-func GetDevOpsProjectMembersHandler(request *restful.Request, resp *restful.Response) {
+func (h ProjectPipelineHandler) GetDevOpsProjectMembersHandler(request *restful.Request, resp *restful.Response) {
projectId := request.PathParameter("devops")
username := request.HeaderParameter(constants.UserNameHeader)
- err := devops.CheckProjectUserInRole(username, projectId, devops.AllRoleSlice)
+ err := h.projectOperator.CheckProjectUserInRole(username, projectId, devops.AllRoleSlice)
if err != nil {
klog.Errorf("%+v", err)
errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
@@ -42,7 +42,7 @@ func GetDevOpsProjectMembersHandler(request *restful.Request, resp *restful.Resp
limit, offset := params.ParsePaging(request.QueryParameter(params.PagingParam))
conditions, err := params.ParseConditions(request.QueryParameter(params.ConditionsParam))
- project, err := devops.GetProjectMembers(projectId, conditions, orderBy, reverse, limit, offset)
+ project, err := h.projectMemberOperator.GetProjectMembers(projectId, conditions, orderBy, reverse, limit, offset)
if err != nil {
klog.Errorf("%+v", err)
@@ -54,19 +54,19 @@ func GetDevOpsProjectMembersHandler(request *restful.Request, resp *restful.Resp
return
}
-func GetDevOpsProjectMemberHandler(request *restful.Request, resp *restful.Response) {
+func (h ProjectPipelineHandler) GetDevOpsProjectMemberHandler(request *restful.Request, resp *restful.Response) {
projectId := request.PathParameter("devops")
username := request.HeaderParameter(constants.UserNameHeader)
member := request.PathParameter("member")
- err := devops.CheckProjectUserInRole(username, projectId, devops.AllRoleSlice)
+ err := h.projectOperator.CheckProjectUserInRole(username, projectId, devops.AllRoleSlice)
if err != nil {
klog.Errorf("%+v", err)
errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
return
}
- project, err := devops.GetProjectMember(projectId, member)
+ project, err := h.projectMemberOperator.GetProjectMember(projectId, member)
if err != nil {
klog.Errorf("%+v", err)
@@ -78,11 +78,11 @@ func GetDevOpsProjectMemberHandler(request *restful.Request, resp *restful.Respo
return
}
-func AddDevOpsProjectMemberHandler(request *restful.Request, resp *restful.Response) {
+func (h ProjectPipelineHandler) AddDevOpsProjectMemberHandler(request *restful.Request, resp *restful.Response) {
projectId := request.PathParameter("devops")
username := request.HeaderParameter(constants.UserNameHeader)
- member := &devops.DevOpsProjectMembership{}
+ member := &devops.ProjectMembership{}
err := request.ReadEntity(&member)
if err != nil {
klog.Errorf("%+v", err)
@@ -102,14 +102,15 @@ func AddDevOpsProjectMemberHandler(request *restful.Request, resp *restful.Respo
errors.ParseSvcErr(restful.NewError(http.StatusBadRequest, err.Error()), resp)
return
}
-
- err = devops.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner})
+ err = h.projectOperator.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner})
if err != nil {
klog.Errorf("%+v", err)
errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
return
}
- project, err := devops.AddProjectMember(projectId, username, member)
+
+ member.GrantBy = username
+ project, err := h.projectMemberOperator.AddProjectMember(projectId, member)
if err != nil {
klog.Errorf("%+v", err)
@@ -121,11 +122,11 @@ func AddDevOpsProjectMemberHandler(request *restful.Request, resp *restful.Respo
return
}
-func UpdateDevOpsProjectMemberHandler(request *restful.Request, resp *restful.Response) {
+func (h ProjectPipelineHandler) UpdateDevOpsProjectMemberHandler(request *restful.Request, resp *restful.Response) {
projectId := request.PathParameter("devops")
username := request.HeaderParameter(constants.UserNameHeader)
- member := &devops.DevOpsProjectMembership{}
+ member := &devops.ProjectMembership{}
err := request.ReadEntity(&member)
if err != nil {
klog.Errorf("%+v", err)
@@ -153,13 +154,13 @@ func UpdateDevOpsProjectMemberHandler(request *restful.Request, resp *restful.Re
return
}
- err = devops.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner})
+ err = h.projectOperator.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner})
if err != nil {
klog.Errorf("%+v", err)
errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
return
}
- project, err := devops.UpdateProjectMember(projectId, username, member)
+ project, err := h.projectMemberOperator.UpdateProjectMember(projectId, member)
if err != nil {
klog.Errorf("%+v", err)
@@ -171,19 +172,19 @@ func UpdateDevOpsProjectMemberHandler(request *restful.Request, resp *restful.Re
return
}
-func DeleteDevOpsProjectMemberHandler(request *restful.Request, resp *restful.Response) {
+func (h ProjectPipelineHandler) DeleteDevOpsProjectMemberHandler(request *restful.Request, resp *restful.Response) {
projectId := request.PathParameter("devops")
username := request.HeaderParameter(constants.UserNameHeader)
member := request.PathParameter("member")
- err := devops.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner})
+ err := h.projectOperator.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner})
if err != nil {
klog.Errorf("%+v", err)
errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
return
}
- username, err = devops.DeleteProjectMember(projectId, member)
+ username, err = h.projectMemberOperator.DeleteProjectMember(projectId, member)
if err != nil {
klog.Errorf("%+v", err)
errors.ParseSvcErr(err, resp)
diff --git a/pkg/kapis/devops/v1alpha2/pipeline_sonar.go b/pkg/kapis/devops/v1alpha2/pipeline_sonar.go
new file mode 100644
index 0000000000000000000000000000000000000000..8b5ecee3c4e263fcbd4b296b7c9631d2f3618d2d
--- /dev/null
+++ b/pkg/kapis/devops/v1alpha2/pipeline_sonar.go
@@ -0,0 +1,49 @@
+package v1alpha2
+
+import (
+ "github.com/emicklei/go-restful"
+ "k8s.io/klog"
+ "kubesphere.io/kubesphere/pkg/constants"
+ "kubesphere.io/kubesphere/pkg/models/devops"
+ "kubesphere.io/kubesphere/pkg/server/errors"
+ "net/http"
+)
+
+func (h PipelineSonarHandler) GetPipelineSonarStatusHandler(request *restful.Request, resp *restful.Response) {
+ projectId := request.PathParameter("devops")
+ username := request.HeaderParameter(constants.UserNameHeader)
+ pipelineId := request.PathParameter("pipeline")
+ err := devops.CheckProjectUserInRole(username, projectId, devops.AllRoleSlice)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
+ return
+ }
+ sonarStatus, err := h.pipelineSonarGetter.GetPipelineSonar(projectId, pipelineId)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ errors.ParseSvcErr(err, resp)
+ return
+ }
+ resp.WriteAsJson(sonarStatus)
+}
+
+func (h PipelineSonarHandler) GetMultiBranchesPipelineSonarStatusHandler(request *restful.Request, resp *restful.Response) {
+ projectId := request.PathParameter("devops")
+ username := request.HeaderParameter(constants.UserNameHeader)
+ pipelineId := request.PathParameter("pipeline")
+ branchId := request.PathParameter("branch")
+ err := devops.CheckProjectUserInRole(username, projectId, devops.AllRoleSlice)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
+ return
+ }
+ sonarStatus, err := h.pipelineSonarGetter.GetMultiBranchPipelineSonar(projectId, pipelineId, branchId)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ errors.ParseSvcErr(err, resp)
+ return
+ }
+ resp.WriteAsJson(sonarStatus)
+}
diff --git a/pkg/apiserver/devops/project.go b/pkg/kapis/devops/v1alpha2/project.go
similarity index 76%
rename from pkg/apiserver/devops/project.go
rename to pkg/kapis/devops/v1alpha2/project.go
index 5589dac6f2479a2bad93761d568e294505a3f413..2bd4b88a9bbac2adeb2111f3b53cfa39d6382606 100644
--- a/pkg/apiserver/devops/project.go
+++ b/pkg/kapis/devops/v1alpha2/project.go
@@ -11,30 +11,30 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-package devops
+package v1alpha2
import (
"github.com/emicklei/go-restful"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/api/devops/v1alpha2"
"kubesphere.io/kubesphere/pkg/constants"
- "kubesphere.io/kubesphere/pkg/models/devops"
"kubesphere.io/kubesphere/pkg/server/errors"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
"net/http"
)
-func GetDevOpsProjectHandler(request *restful.Request, resp *restful.Response) {
+func (h ProjectPipelineHandler) GetDevOpsProjectHandler(request *restful.Request, resp *restful.Response) {
projectId := request.PathParameter("devops")
username := request.HeaderParameter(constants.UserNameHeader)
- err := devops.CheckProjectUserInRole(username, projectId, devops.AllRoleSlice)
+ err := h.projectOperator.CheckProjectUserInRole(username, projectId, devops.AllRoleSlice)
if err != nil {
klog.Errorf("%+v", err)
errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
return
}
- project, err := devops.GetProject(projectId)
+ project, err := h.projectOperator.GetProject(projectId)
if err != nil {
klog.Errorf("%+v", err)
@@ -46,7 +46,7 @@ func GetDevOpsProjectHandler(request *restful.Request, resp *restful.Response) {
return
}
-func UpdateProjectHandler(request *restful.Request, resp *restful.Response) {
+func (h ProjectPipelineHandler) UpdateProjectHandler(request *restful.Request, resp *restful.Response) {
projectId := request.PathParameter("devops")
username := request.HeaderParameter(constants.UserNameHeader)
@@ -58,13 +58,13 @@ func UpdateProjectHandler(request *restful.Request, resp *restful.Response) {
return
}
project.ProjectId = projectId
- err = devops.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner})
+ err = h.projectOperator.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner})
if err != nil {
klog.Errorf("%+v", err)
errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
return
}
- project, err = devops.UpdateProject(project)
+ project, err = h.projectOperator.UpdateProject(project)
if err != nil {
klog.Errorf("%+v", err)
diff --git a/pkg/kapis/devops/v1alpha2/project_credential.go b/pkg/kapis/devops/v1alpha2/project_credential.go
new file mode 100644
index 0000000000000000000000000000000000000000..9d9d9289204bc3a4b604dcfb383be0e314d1b212
--- /dev/null
+++ b/pkg/kapis/devops/v1alpha2/project_credential.go
@@ -0,0 +1,122 @@
+/*
+Copyright 2019 The KubeSphere Authors.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package v1alpha2
+
+import (
+ "github.com/emicklei/go-restful"
+ "k8s.io/klog"
+ "kubesphere.io/kubesphere/pkg/constants"
+ "kubesphere.io/kubesphere/pkg/server/errors"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "net/http"
+)
+
+func (h ProjectPipelineHandler) CreateDevOpsProjectCredentialHandler(request *restful.Request, resp *restful.Response) {
+
+ projectId := request.PathParameter("devops")
+ username := request.HeaderParameter(constants.UserNameHeader)
+ var credential *devops.Credential
+ err := request.ReadEntity(&credential)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ errors.ParseSvcErr(restful.NewError(http.StatusBadRequest, err.Error()), resp)
+ return
+ }
+ credentialId, err := h.projectCredentialOperator.CreateProjectCredential(projectId, username, credential)
+
+ if err != nil {
+ klog.Errorf("%+v", err)
+ errors.ParseSvcErr(err, resp)
+ return
+ }
+
+ resp.WriteAsJson(struct {
+ Name string `json:"name"`
+ }{Name: credentialId})
+ return
+}
+
+func (h ProjectPipelineHandler) UpdateDevOpsProjectCredentialHandler(request *restful.Request, resp *restful.Response) {
+
+ projectId := request.PathParameter("devops")
+ credentialId := request.PathParameter("credential")
+ var credential *devops.Credential
+ err := request.ReadEntity(&credential)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ errors.ParseSvcErr(restful.NewError(http.StatusBadRequest, err.Error()), resp)
+ return
+ }
+ credentialId, err = h.projectCredentialOperator.UpdateProjectCredential(projectId, credentialId, credential)
+
+ if err != nil {
+ klog.Errorf("%+v", err)
+ errors.ParseSvcErr(err, resp)
+ return
+ }
+
+ resp.WriteAsJson(struct {
+ Name string `json:"name"`
+ }{Name: credentialId})
+ return
+}
+
+func (h ProjectPipelineHandler) DeleteDevOpsProjectCredentialHandler(request *restful.Request, resp *restful.Response) {
+
+ projectId := request.PathParameter("devops")
+ credentialId := request.PathParameter("credential")
+
+ credentialId, err := h.projectCredentialOperator.DeleteProjectCredential(projectId, credentialId)
+
+ if err != nil {
+ klog.Errorf("%+v", err)
+ errors.ParseSvcErr(err, resp)
+ return
+ }
+
+ resp.WriteAsJson(struct {
+ Name string `json:"name"`
+ }{Name: credentialId})
+ return
+}
+
+func (h ProjectPipelineHandler) GetDevOpsProjectCredentialHandler(request *restful.Request, resp *restful.Response) {
+
+ projectId := request.PathParameter("devops")
+ credentialId := request.PathParameter("credential")
+ getContent := request.QueryParameter("content")
+ response, err := h.projectCredentialOperator.GetProjectCredential(projectId, credentialId, getContent)
+
+ if err != nil {
+ klog.Errorf("%+v", err)
+ errors.ParseSvcErr(err, resp)
+ return
+ }
+
+ resp.WriteAsJson(response)
+ return
+}
+
+func (h ProjectPipelineHandler) GetDevOpsProjectCredentialsHandler(request *restful.Request, resp *restful.Response) {
+ projectId := request.PathParameter("devops")
+
+ jenkinsCredentials, err := h.projectCredentialOperator.GetProjectCredentials(projectId)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ errors.ParseSvcErr(err, resp)
+ return
+ }
+ resp.WriteAsJson(jenkinsCredentials)
+ return
+}
diff --git a/pkg/apiserver/devops/project_pipeline.go b/pkg/kapis/devops/v1alpha2/project_pipeline.go
similarity index 53%
rename from pkg/apiserver/devops/project_pipeline.go
rename to pkg/kapis/devops/v1alpha2/project_pipeline.go
index fe62c69e4d1512475acc9b5cdc6677cf1150b526..b752dafd9dcd6421a86c384ef707fe5f0b608844 100644
--- a/pkg/apiserver/devops/project_pipeline.go
+++ b/pkg/kapis/devops/v1alpha2/project_pipeline.go
@@ -11,18 +11,18 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-package devops
+package v1alpha2
import (
"github.com/emicklei/go-restful"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/constants"
- "kubesphere.io/kubesphere/pkg/models/devops"
"kubesphere.io/kubesphere/pkg/server/errors"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
"net/http"
)
-func CreateDevOpsProjectPipelineHandler(request *restful.Request, resp *restful.Response) {
+func (h ProjectPipelineHandler) CreateDevOpsProjectPipelineHandler(request *restful.Request, resp *restful.Response) {
projectId := request.PathParameter("devops")
username := request.HeaderParameter(constants.UserNameHeader)
@@ -33,13 +33,13 @@ func CreateDevOpsProjectPipelineHandler(request *restful.Request, resp *restful.
errors.ParseSvcErr(restful.NewError(http.StatusBadRequest, err.Error()), resp)
return
}
- err = devops.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner, devops.ProjectMaintainer})
+ err = h.projectOperator.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner, devops.ProjectMaintainer})
if err != nil {
klog.Errorf("%+v", err)
errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
return
}
- pipelineName, err := devops.CreateProjectPipeline(projectId, pipeline)
+ pipelineName, err := h.projectPipelineOperator.CreateProjectPipeline(projectId, pipeline)
if err != nil {
klog.Errorf("%+v", err)
@@ -53,18 +53,18 @@ func CreateDevOpsProjectPipelineHandler(request *restful.Request, resp *restful.
return
}
-func DeleteDevOpsProjectPipelineHandler(request *restful.Request, resp *restful.Response) {
+func (h ProjectPipelineHandler) DeleteDevOpsProjectPipelineHandler(request *restful.Request, resp *restful.Response) {
projectId := request.PathParameter("devops")
username := request.HeaderParameter(constants.UserNameHeader)
pipelineId := request.PathParameter("pipeline")
- err := devops.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner, devops.ProjectMaintainer})
+ err := h.projectOperator.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner, devops.ProjectMaintainer})
if err != nil {
klog.Errorf("%+v", err)
errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
return
}
- pipelineName, err := devops.DeleteProjectPipeline(projectId, pipelineId)
+ pipelineName, err := h.projectPipelineOperator.DeleteProjectPipeline(projectId, pipelineId)
if err != nil {
klog.Errorf("%+v", err)
@@ -78,7 +78,7 @@ func DeleteDevOpsProjectPipelineHandler(request *restful.Request, resp *restful.
return
}
-func UpdateDevOpsProjectPipelineHandler(request *restful.Request, resp *restful.Response) {
+func (h ProjectPipelineHandler) UpdateDevOpsProjectPipelineHandler(request *restful.Request, resp *restful.Response) {
projectId := request.PathParameter("devops")
username := request.HeaderParameter(constants.UserNameHeader)
@@ -90,13 +90,13 @@ func UpdateDevOpsProjectPipelineHandler(request *restful.Request, resp *restful.
errors.ParseSvcErr(restful.NewError(http.StatusBadRequest, err.Error()), resp)
return
}
- err = devops.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner, devops.ProjectMaintainer})
+ err = h.projectOperator.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner, devops.ProjectMaintainer})
if err != nil {
klog.Errorf("%+v", err)
errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
return
}
- pipelineName, err := devops.UpdateProjectPipeline(projectId, pipelineId, pipeline)
+ pipelineName, err := h.projectPipelineOperator.UpdateProjectPipeline(projectId, pipelineId, pipeline)
if err != nil {
klog.Errorf("%+v", err)
@@ -110,19 +110,19 @@ func UpdateDevOpsProjectPipelineHandler(request *restful.Request, resp *restful.
return
}
-func GetDevOpsProjectPipelineHandler(request *restful.Request, resp *restful.Response) {
+func (h ProjectPipelineHandler) GetDevOpsProjectPipelineConfigHandler(request *restful.Request, resp *restful.Response) {
projectId := request.PathParameter("devops")
username := request.HeaderParameter(constants.UserNameHeader)
pipelineId := request.PathParameter("pipeline")
- err := devops.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner, devops.ProjectMaintainer})
+ err := h.projectOperator.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner, devops.ProjectMaintainer})
if err != nil {
klog.Errorf("%+v", err)
errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
return
}
- pipeline, err := devops.GetProjectPipeline(projectId, pipelineId)
+ pipeline, err := h.projectPipelineOperator.GetProjectPipelineConfig(projectId, pipelineId)
if err != nil {
klog.Errorf("%+v", err)
@@ -133,42 +133,3 @@ func GetDevOpsProjectPipelineHandler(request *restful.Request, resp *restful.Res
resp.WriteAsJson(pipeline)
return
}
-
-func GetPipelineSonarStatusHandler(request *restful.Request, resp *restful.Response) {
- projectId := request.PathParameter("devops")
- username := request.HeaderParameter(constants.UserNameHeader)
- pipelineId := request.PathParameter("pipeline")
- err := devops.CheckProjectUserInRole(username, projectId, devops.AllRoleSlice)
- if err != nil {
- klog.Errorf("%+v", err)
- errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
- return
- }
- sonarStatus, err := devops.GetPipelineSonar(projectId, pipelineId)
- if err != nil {
- klog.Errorf("%+v", err)
- errors.ParseSvcErr(err, resp)
- return
- }
- resp.WriteAsJson(sonarStatus)
-}
-
-func GetMultiBranchesPipelineSonarStatusHandler(request *restful.Request, resp *restful.Response) {
- projectId := request.PathParameter("devops")
- username := request.HeaderParameter(constants.UserNameHeader)
- pipelineId := request.PathParameter("pipeline")
- branchId := request.PathParameter("branch")
- err := devops.CheckProjectUserInRole(username, projectId, devops.AllRoleSlice)
- if err != nil {
- klog.Errorf("%+v", err)
- errors.ParseSvcErr(restful.NewError(http.StatusForbidden, err.Error()), resp)
- return
- }
- sonarStatus, err := devops.GetMultiBranchPipelineSonar(projectId, pipelineId, branchId)
- if err != nil {
- klog.Errorf("%+v", err)
- errors.ParseSvcErr(err, resp)
- return
- }
- resp.WriteAsJson(sonarStatus)
-}
diff --git a/pkg/kapis/devops/v1alpha2/register.go b/pkg/kapis/devops/v1alpha2/register.go
index ea7668192f7135a36ab40bf407ef871538027cde..68c088de458187015defddd995fc1fbe013c3e31 100644
--- a/pkg/kapis/devops/v1alpha2/register.go
+++ b/pkg/kapis/devops/v1alpha2/register.go
@@ -24,10 +24,10 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
"kubesphere.io/kubesphere/pkg/api/devops/v1alpha2"
devopsv1alpha1 "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha1"
- devopsapi "kubesphere.io/kubesphere/pkg/apiserver/devops"
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
"kubesphere.io/kubesphere/pkg/constants"
- "kubesphere.io/kubesphere/pkg/models/devops"
+ //"kubesphere.io/kubesphere/pkg/models/devops"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
"kubesphere.io/kubesphere/pkg/server/params"
"net/http"
@@ -49,8 +49,14 @@ func addWebService(c *restful.Container) error {
webservice := runtime.NewWebService(GroupVersion)
+ sonarHandler := NewPipelineSonarHandler()
+
+ projectPipelineHander := NewProjectPipelineHandler()
+
+ s2iHandler := NewS2iBinaryHandler()
+
webservice.Route(webservice.GET("/devops/{devops}").
- To(devopsapi.GetDevOpsProjectHandler).
+ To(projectPipelineHander.GetDevOpsProjectHandler).
Doc("Get the specified DevOps Project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
@@ -58,7 +64,7 @@ func addWebService(c *restful.Container) error {
Writes(v1alpha2.DevOpsProject{}))
webservice.Route(webservice.PATCH("/devops/{devops}").
- To(devopsapi.UpdateProjectHandler).
+ To(projectPipelineHander.UpdateProjectHandler).
Doc("Update the specified DevOps Project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
@@ -67,7 +73,7 @@ func addWebService(c *restful.Container) error {
Writes(v1alpha2.DevOpsProject{}))
webservice.Route(webservice.GET("/devops/{devops}/defaultroles").
- To(devopsapi.GetDevOpsProjectDefaultRoles).
+ To(GetDevOpsProjectDefaultRoles).
Doc("Get the build-in roles info of the specified DevOps project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectMemberTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
@@ -75,7 +81,7 @@ func addWebService(c *restful.Container) error {
Writes([]devops.Role{}))
webservice.Route(webservice.GET("/devops/{devops}/members").
- To(devopsapi.GetDevOpsProjectMembersHandler).
+ To(projectPipelineHander.GetDevOpsProjectMembersHandler).
Doc("Get the members of the specified DevOps project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectMemberTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
@@ -90,7 +96,7 @@ func addWebService(c *restful.Container) error {
Writes([]devops.DevOpsProjectMembership{}))
webservice.Route(webservice.GET("/devops/{devops}/members/{member}").
- To(devopsapi.GetDevOpsProjectMemberHandler).
+ To(projectPipelineHander.GetDevOpsProjectMemberHandler).
Doc("Get the specified member of the DevOps project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectMemberTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
@@ -99,7 +105,7 @@ func addWebService(c *restful.Container) error {
Writes(devops.DevOpsProjectMembership{}))
webservice.Route(webservice.POST("/devops/{devops}/members").
- To(devopsapi.AddDevOpsProjectMemberHandler).
+ To(projectPipelineHander.AddDevOpsProjectMemberHandler).
Doc("Add a member to the specified DevOps project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectMemberTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
@@ -108,7 +114,7 @@ func addWebService(c *restful.Container) error {
Reads(devops.DevOpsProjectMembership{}))
webservice.Route(webservice.PATCH("/devops/{devops}/members/{member}").
- To(devopsapi.UpdateDevOpsProjectMemberHandler).
+ To(projectPipelineHander.UpdateDevOpsProjectMemberHandler).
Doc("Update the specified member of the DevOps project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectMemberTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
@@ -118,7 +124,7 @@ func addWebService(c *restful.Container) error {
Writes(devops.DevOpsProjectMembership{}))
webservice.Route(webservice.DELETE("/devops/{devops}/members/{member}").
- To(devopsapi.DeleteDevOpsProjectMemberHandler).
+ To(projectPipelineHander.DeleteDevOpsProjectMemberHandler).
Doc("Delete the specified member of the DevOps project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectMemberTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
@@ -126,7 +132,7 @@ func addWebService(c *restful.Container) error {
Writes(devops.DevOpsProjectMembership{}))
webservice.Route(webservice.POST("/devops/{devops}/pipelines").
- To(devopsapi.CreateDevOpsProjectPipelineHandler).
+ To(projectPipelineHander.CreateDevOpsProjectPipelineHandler).
Doc("Create a DevOps project pipeline").
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
@@ -135,7 +141,7 @@ func addWebService(c *restful.Container) error {
Reads(devops.ProjectPipeline{}))
webservice.Route(webservice.PUT("/devops/{devops}/pipelines/{pipeline}").
- To(devopsapi.UpdateDevOpsProjectPipelineHandler).
+ To(projectPipelineHander.UpdateDevOpsProjectPipelineHandler).
Doc("Update the specified pipeline of the DevOps project").
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("pipeline", "the name of pipeline, e.g. sample-pipeline")).
@@ -144,14 +150,14 @@ func addWebService(c *restful.Container) error {
Reads(devops.ProjectPipeline{}))
webservice.Route(webservice.DELETE("/devops/{devops}/pipelines/{pipeline}").
- To(devopsapi.DeleteDevOpsProjectPipelineHandler).
+ To(projectPipelineHander.DeleteDevOpsProjectPipelineHandler).
Doc("Delete the specified pipeline of the DevOps project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("pipeline", "the name of pipeline, e.g. sample-pipeline")))
webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/config").
- To(devopsapi.GetDevOpsProjectPipelineHandler).
+ To(projectPipelineHander.GetDevOpsProjectPipelineConfigHandler).
Doc("Get the configuration information of the specified pipeline of the DevOps Project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
@@ -160,7 +166,7 @@ func addWebService(c *restful.Container) error {
Writes(devops.ProjectPipeline{}))
webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/sonarstatus").
- To(devopsapi.GetPipelineSonarStatusHandler).
+ To(sonarHandler.GetPipelineSonarStatusHandler).
Doc("Get the sonar quality information for the specified pipeline of the DevOps project. More info: https://docs.sonarqube.org/7.4/user-guide/metric-definitions/").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
@@ -169,7 +175,7 @@ func addWebService(c *restful.Container) error {
Writes([]devops.SonarStatus{}))
webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/sonarstatus").
- To(devopsapi.GetMultiBranchesPipelineSonarStatusHandler).
+ To(sonarHandler.GetMultiBranchesPipelineSonarStatusHandler).
Doc("Get the sonar quality check information for the specified pipeline branch of the DevOps project. More info: https://docs.sonarqube.org/7.4/user-guide/metric-definitions/").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
@@ -179,29 +185,29 @@ func addWebService(c *restful.Container) error {
Writes([]devops.SonarStatus{}))
webservice.Route(webservice.POST("/devops/{devops}/credentials").
- To(devopsapi.CreateDevOpsProjectCredentialHandler).
+ To(projectPipelineHander.CreateDevOpsProjectCredentialHandler).
Doc("Create a credential in the specified DevOps project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectCredentialTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
- Reads(devops.JenkinsCredential{}))
+ Reads(devops.Credential{}))
webservice.Route(webservice.PUT("/devops/{devops}/credentials/{credential}").
- To(devopsapi.UpdateDevOpsProjectCredentialHandler).
+ To(projectPipelineHander.UpdateDevOpsProjectCredentialHandler).
Doc("Update the specified credential of the DevOps project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectCredentialTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("credential", "credential's ID, e.g. dockerhub-id")).
- Reads(devops.JenkinsCredential{}))
+ Reads(devops.Credential{}))
webservice.Route(webservice.DELETE("/devops/{devops}/credentials/{credential}").
- To(devopsapi.DeleteDevOpsProjectCredentialHandler).
+ To(projectPipelineHander.DeleteDevOpsProjectCredentialHandler).
Doc("Delete the specified credential of the DevOps project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectCredentialTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("credential", "credential's ID, e.g. dockerhub-id")))
webservice.Route(webservice.GET("/devops/{devops}/credentials/{credential}").
- To(devopsapi.GetDevOpsProjectCredentialHandler).
+ To(projectPipelineHander.GetDevOpsProjectCredentialHandler).
Doc("Get the specified credential of the DevOps project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectCredentialTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
@@ -212,18 +218,18 @@ Specifically, there are three types of info in a credential. One is the basic in
The second one is non-encrypted info such as the username of the username-password type of credential, which returns when the "content" parameter is set to non-empty.
The last one is encrypted info, such as the password of the username-password type of credential, which never returns.
`)).
- Returns(http.StatusOK, RespOK, devops.JenkinsCredential{}))
+ Returns(http.StatusOK, RespOK, devops.Credential{}))
webservice.Route(webservice.GET("/devops/{devops}/credentials").
- To(devopsapi.GetDevOpsProjectCredentialsHandler).
+ To(projectPipelineHander.GetDevOpsProjectCredentialsHandler).
Doc("Get all credentials of the specified DevOps project").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsProjectCredentialTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
- Returns(http.StatusOK, RespOK, []devops.JenkinsCredential{}))
+ Returns(http.StatusOK, RespOK, []devops.Credential{}))
// match Jenkisn api "/blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}"
webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}").
- To(devopsapi.GetPipeline).
+ To(projectPipelineHander.GetPipeline).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Doc("Get the specified pipeline of the DevOps project").
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
@@ -233,7 +239,7 @@ The last one is encrypted info, such as the password of the username-password ty
// match Jenkisn api: "jenkins_api/blue/rest/search"
webservice.Route(webservice.GET("/search").
- To(devopsapi.SearchPipelines).
+ To(projectPipelineHander.ListPipelines).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Doc("Search DevOps resource. More info: https://github.com/jenkinsci/blueocean-plugin/tree/master/blueocean-rest#get-pipelines-across-organization").
Param(webservice.QueryParameter("q", "query pipelines, condition for filtering.").
@@ -248,18 +254,23 @@ The last one is encrypted info, such as the password of the username-password ty
Param(webservice.QueryParameter("limit", "the limit item count of the search.").
Required(false).
DataFormat("limit=%d")).
- Returns(http.StatusOK, RespOK, struct {
- Items []devops.Pipeline `json:"items"`
- Total int `json:"total_count"`
- }{}).
- Writes(struct {
- Items []devops.Pipeline `json:"items"`
- Total int `json:"total_count"`
- }{}))
+ Returns(http.StatusOK, RespOK, devops.PipelineList{}).
+ Writes(devops.PipelineList{}))
+
+ // match /blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/runs/{run}/
+ webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/runs/{run}").
+ To(projectPipelineHander.GetPipelineRun).
+ Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
+ Doc("Get details in the specified pipeline activity.").
+ Param(webservice.PathParameter("devops", "the name of devops project")).
+ Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
+ Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
+ Returns(http.StatusOK, RespOK, devops.PipelineRun{}).
+ Writes(devops.PipelineRun{}))
// match Jenkisn api "/blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/runs/"
webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/runs").
- To(devopsapi.SearchPipelineRuns).
+ To(projectPipelineHander.ListPipelineRuns).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Doc("Get all runs of the specified pipeline").
Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
@@ -273,63 +284,76 @@ The last one is encrypted info, such as the password of the username-password ty
Param(webservice.QueryParameter("branch", "the name of branch, same as repository branch, will be filtered by branch.").
Required(false).
DataFormat("branch=%s")).
- Returns(http.StatusOK, RespOK, struct {
- Items []devops.BranchPipelineRun `json:"items"`
- Total int `json:"total_count"`
- }{}).
- Writes(struct {
- Items []devops.BranchPipelineRun `json:"items"`
- Total int `json:"total_count"`
- }{}).
- Writes(struct {
- Items []devops.BranchPipelineRun `json:"items"`
- Total int `json:"total_count"`
- }{}).
- Writes(struct {
- Items []devops.BranchPipelineRun `json:"items"`
- Total int `json:"total_count"`
- }{}))
+ Returns(http.StatusOK, RespOK, devops.PipelineRunList{}).
+ Writes(devops.PipelineRunList{}))
- // match Jenkins api "/blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/branches/{branch}/runs/{run}/"
- webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}").
- To(devopsapi.GetBranchPipelineRun).
+ // match /blue/rest/organizations/jenkins/pipelines/{devops}/pipelines/{pipeline}/runs/{run}/stop/
+ webservice.Route(webservice.POST("/devops/{devops}/pipelines/{pipeline}/runs/{run}/stop").
+ To(projectPipelineHander.StopPipeline).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("(MultiBranchesPipeline) Get all runs in the specified branch").
+ Doc("Stop pipeline").
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
- Param(webservice.PathParameter("branch", "the name of branch, same as repository branch.")).
- Param(webservice.PathParameter("run", "pipeline run id, the unique id for a pipeline once build.")).
- Returns(http.StatusOK, RespOK, devops.BranchPipelineRun{}).
- Writes(devops.BranchPipelineRun{}))
+ Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
+ Param(webservice.QueryParameter("blocking", "stop and between each retries will sleep.").
+ Required(false).
+ DataFormat("blocking=%t").
+ DefaultValue("blocking=false")).
+ Param(webservice.QueryParameter("timeOutInSecs", "the time of stop and between each retries sleep.").
+ Required(false).
+ DataFormat("timeOutInSecs=%d").
+ DefaultValue("timeOutInSecs=10")).
+ Returns(http.StatusOK, RespOK, devops.StopPipeline{}).
+ Writes(devops.StopPipeline{}))
- // match Jenkins api "/blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/branches/{branch}/runs/{run}/nodes"
- webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}/nodes").
- To(devopsapi.GetPipelineRunNodesbyBranch).
+ // match /blue/rest/organizations/jenkins/pipelines/{devops}/pipelines/{pipeline}/runs/{run}/Replay/
+ webservice.Route(webservice.POST("/devops/{devops}/pipelines/{pipeline}/runs/{run}/replay").
+ To(projectPipelineHander.ReplayPipeline).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("(MultiBranchesPipeline) Get run nodes.").
+ Doc("Replay pipeline").
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
- Param(webservice.PathParameter("branch", "the name of branch, same as repository branch.")).
- Param(webservice.PathParameter("run", "pipeline run id, the unique id for a pipeline once build.")).
+ Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
+ Returns(http.StatusOK, RespOK, devops.ReplayPipeline{}).
+ Writes(devops.ReplayPipeline{}))
+
+ // match /blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/runs/
+ webservice.Route(webservice.POST("/devops/{devops}/pipelines/{pipeline}/runs").
+ To(projectPipelineHander.RunPipeline).
+ Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
+ Doc("Run pipeline.").
+ Reads(devops.RunPayload{}).
+ Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
+ Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
+ Returns(http.StatusOK, RespOK, devops.RunPipeline{}).
+ Writes(devops.RunPipeline{}))
+
+ // match /blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/runs/{run}/artifacts
+ webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/runs/{run}/artifacts").
+ To(projectPipelineHander.GetArtifacts).
+ Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
+ Doc("Get all artifacts in the specified pipeline.").
+ Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
+ Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
+ Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
+ Param(webservice.QueryParameter("start", "the item number that the search starts from.").
+ Required(false).
+ DataFormat("start=%d")).
Param(webservice.QueryParameter("limit", "the limit item count of the search.").
Required(false).
- DataFormat("limit=%d").
- DefaultValue("limit=10000")).
- Returns(http.StatusOK, RespOK, []devops.BranchPipelineRunNodes{}).
- Writes([]devops.BranchPipelineRunNodes{}))
+ DataFormat("limit=%d")).
+ Returns(http.StatusOK, "The filed of \"Url\" in response can download artifacts", []devops.Artifacts{}).
+ Writes([]devops.Artifacts{}))
- // match "/blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/branches/{branch}/runs/{run}/nodes/{node}/steps/{step}/log/?start=0"
- webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}/nodes/{node}/steps/{step}/log").
- To(devopsapi.GetBranchStepLog).
+ // match /blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/runs/{run}/log/?start=0
+ webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/runs/{run}/log").
+ To(projectPipelineHander.GetRunLog).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("(MultiBranchesPipeline) Get the step logs in the specified pipeline activity.").
+ Doc("Get run logs of the specified pipeline activity.").
Produces("text/plain; charset=utf-8").
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
- Param(webservice.PathParameter("branch", "the name of branch, same as repository branch.")).
- Param(webservice.PathParameter("run", "pipeline run id, the unique id for a pipeline once build.")).
- Param(webservice.PathParameter("node", "pipeline node id, the stage in pipeline.")).
- Param(webservice.PathParameter("step", "pipeline step id, the step in pipeline.")).
+ Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
Param(webservice.QueryParameter("start", "the item number that the search starts from.").
Required(false).
DataFormat("start=%d").
@@ -337,7 +361,7 @@ The last one is encrypted info, such as the password of the username-password ty
// match "/blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/runs/{run}/nodes/{node}/steps/{step}/log/?start=0"
webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/runs/{run}/nodes/{node}/steps/{step}/log").
- To(devopsapi.GetStepLog).
+ To(projectPipelineHander.GetStepLog).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Doc("Get pipelines step log.").
Produces("text/plain; charset=utf-8").
@@ -351,92 +375,85 @@ The last one is encrypted info, such as the password of the username-password ty
DataFormat("start=%d").
DefaultValue("start=0")))
- // match "/blue/rest/organizations/jenkins/scm/github/validate/"
- webservice.Route(webservice.POST("/scms/{scm}/verify").
- To(devopsapi.Validate).
- Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsScmTag}).
- Doc("Validate the access token of the specified source configuration management (SCM) such as Github").
- Param(webservice.PathParameter("scm", "the ID of the source configuration management (SCM).")).
- Returns(http.StatusOK, RespOK, devops.Validates{}).
- Writes(devops.Validates{}))
+ // match /blue/rest/organizations/jenkins/pipelines/%s/%s/runs/%s/nodes/%s/steps/?limit=
+ webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/runs/{run}/nodes/{node}/steps").
+ To(projectPipelineHander.GetNodeSteps).
+ Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
+ Doc("Get all steps in the specified node.").
+ Param(webservice.PathParameter("devops", "the name of devops project")).
+ Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
+ Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build")).
+ Param(webservice.PathParameter("node", "pipeline node ID, the stage in pipeline.")).
+ Returns(http.StatusOK, RespOK, []devops.NodeSteps{}).
+ Writes([]devops.NodeSteps{}))
- // match "/blue/rest/organizations/jenkins/scm/{scm}/organizations/?credentialId=github"
- webservice.Route(webservice.GET("/scms/{scm}/organizations").
- To(devopsapi.GetSCMOrg).
- Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsScmTag}).
- Doc("List all organizations of the specified source configuration management (SCM) such as Github.").
- Param(webservice.PathParameter("scm", "the ID of the source configuration management (SCM).")).
- Param(webservice.QueryParameter("credentialId", "credential ID for source configuration management (SCM).").
- Required(true).
- DataFormat("credentialId=%s")).
- Returns(http.StatusOK, RespOK, []devops.SCMOrg{}).
- Writes([]devops.SCMOrg{}))
+ // match /blue/rest/organizations/jenkins/pipelines/{devops}/pipelines/{pipeline}/runs/{run}/nodes/?limit=10000
+ webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/runs/{run}/nodes").
+ To(projectPipelineHander.GetPipelineRunNodes).
+ Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
+ Doc("Get all nodes in the specified activity. node is the stage in the pipeline task").
+ Param(webservice.PathParameter("devops", "the name of devops project")).
+ Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
+ Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build")).
+ Returns(http.StatusOK, RespOK, []devops.PipelineRunNodes{}).
+ Writes([]devops.PipelineRunNodes{}))
- // match "/blue/rest/organizations/jenkins/scm/%s/servers/"
- webservice.Route(webservice.GET("/scms/{scm}/servers").
- To(devopsapi.GetSCMServers).
- Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsScmTag}).
- Doc("List all servers in the jenkins.").
- Param(webservice.PathParameter("scm", "The ID of the source configuration management (SCM).")).
- Returns(http.StatusOK, RespOK, []devops.SCMServer{}).
- Writes([]devops.SCMServer{}))
+ // match /blue/rest/organizations/jenkins/pipelines/{devops}/pipelines/{pipeline}/runs/{run}/nodes/{node}/steps/{step}
+ webservice.Route(webservice.POST("/devops/{devops}/pipelines/{pipeline}/runs/{run}/nodes/{node}/steps/{step}").
+ To(projectPipelineHander.SubmitInputStep).
+ Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
+ Doc("Proceed or Break the paused pipeline which is waiting for user input.").
+ Reads(devops.CheckPlayload{}).
+ Produces("text/plain; charset=utf-8").
+ Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
+ Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
+ Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
+ Param(webservice.PathParameter("node", "pipeline node ID, the stage in pipeline.")).
+ Param(webservice.PathParameter("step", "pipeline step ID")))
- // match "/blue/rest/organizations/jenkins/scm/%s/servers/"
- webservice.Route(webservice.POST("/scms/{scm}/servers").
- To(devopsapi.CreateSCMServers).
- Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsScmTag}).
- Doc("Create scm server in the jenkins.").
- Param(webservice.PathParameter("scm", "The ID of the source configuration management (SCM).")).
- Reads(devops.CreateScmServerReq{}).
- Returns(http.StatusOK, RespOK, devops.SCMServer{}).
- Writes(devops.SCMServer{}))
+ // out of scm get all steps in nodes.
+ webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/runs/{run}/nodesdetail").
+ To(projectPipelineHander.GetNodesDetail).
+ Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
+ Doc("Get steps details inside a activity node. For a node, the steps which defined inside the node.").
+ Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
+ Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
+ Param(webservice.PathParameter("branch", "the name of branch, same as repository branch.")).
+ Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
+ Returns(http.StatusOK, RespOK, []devops.NodesDetail{}).
+ Writes(devops.NodesDetail{}))
- // match "/blue/rest/organizations/jenkins/scm/{scm}/organizations/{organization}/repositories/?credentialId=&pageNumber&pageSize="
- webservice.Route(webservice.GET("/scms/{scm}/organizations/{organization}/repositories").
- To(devopsapi.GetOrgRepo).
- Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsScmTag}).
- Doc("List all repositories in the specified organization.").
- Param(webservice.PathParameter("scm", "The ID of the source configuration management (SCM).")).
- Param(webservice.PathParameter("organization", "organization ID, such as github username.")).
- Param(webservice.QueryParameter("credentialId", "credential ID for SCM.").
- Required(true).
- DataFormat("credentialId=%s")).
- Param(webservice.QueryParameter("pageNumber", "page number.").
- Required(true).
- DataFormat("pageNumber=%d")).
- Param(webservice.QueryParameter("pageSize", "the item count of one page.").
- Required(true).
- DataFormat("pageSize=%d")).
- Returns(http.StatusOK, RespOK, []devops.OrgRepo{}).
- Writes([]devops.OrgRepo{}))
+ // match /blue/rest/organizations/jenkins/pipelines/{devops}/pipelines/{pipeline}/branches/{branch}
+ webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches/{branch}").
+ To(projectPipelineHander.GetBranchPipeline).
+ Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
+ Doc("(MultiBranchesPipeline) Get the specified branch pipeline of the DevOps project").
+ Param(webservice.PathParameter("devops", "the name of devops project")).
+ Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
+ Param(webservice.PathParameter("branch", "the name of branch, same as repository branch")).
+ Returns(http.StatusOK, RespOK, devops.BranchPipeline{}).
+ Writes(devops.BranchPipeline{}))
- // match /blue/rest/organizations/jenkins/pipelines/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}/stop/
- webservice.Route(webservice.POST("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}/stop").
- To(devopsapi.StopBranchPipeline).
+ // match Jenkins api "/blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/branches/{branch}/runs/{run}/"
+ webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}").
+ To(projectPipelineHander.GetBranchPipelineRun).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("(MultiBranchesPipeline) Stop the specified pipeline of the DevOps project.").
+ Doc("(MultiBranchesPipeline) Get details in the specified pipeline activity.").
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
Param(webservice.PathParameter("branch", "the name of branch, same as repository branch.")).
- Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
- Param(webservice.QueryParameter("blocking", "stop and between each retries will sleep.").
- Required(false).
- DataFormat("blocking=%t").
- DefaultValue("blocking=false")).
- Param(webservice.QueryParameter("timeOutInSecs", "the time of stop and between each retries sleep.").
- Required(false).
- DataFormat("timeOutInSecs=%d").
- DefaultValue("timeOutInSecs=10")).
- Returns(http.StatusOK, RespOK, devops.StopPipe{}).
- Writes(devops.StopPipe{}))
+ Param(webservice.PathParameter("run", "pipeline run id, the unique id for a pipeline once build.")).
+ Returns(http.StatusOK, RespOK, devops.PipelineRun{}).
+ Writes(devops.PipelineRun{}))
- // match /blue/rest/organizations/jenkins/pipelines/{devops}/pipelines/{pipeline}/runs/{run}/stop/
- webservice.Route(webservice.POST("/devops/{devops}/pipelines/{pipeline}/runs/{run}/stop").
- To(devopsapi.StopPipeline).
+ // match /blue/rest/organizations/jenkins/pipelines/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}/stop/
+ webservice.Route(webservice.POST("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}/stop").
+ To(projectPipelineHander.StopBranchPipeline).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("Stop pipeline").
+ Doc("(MultiBranchesPipeline) Stop the specified pipeline of the DevOps project.").
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
+ Param(webservice.PathParameter("branch", "the name of branch, same as repository branch.")).
Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
Param(webservice.QueryParameter("blocking", "stop and between each retries will sleep.").
Required(false).
@@ -446,35 +463,54 @@ The last one is encrypted info, such as the password of the username-password ty
Required(false).
DataFormat("timeOutInSecs=%d").
DefaultValue("timeOutInSecs=10")).
- Returns(http.StatusOK, RespOK, devops.StopPipe{}).
- Writes(devops.StopPipe{}))
+ Returns(http.StatusOK, RespOK, devops.StopPipeline{}).
+ Writes(devops.StopPipeline{}))
// match /blue/rest/organizations/jenkins/pipelines/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}/Replay/
webservice.Route(webservice.POST("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}/replay").
- To(devopsapi.ReplayBranchPipeline).
+ To(projectPipelineHander.ReplayBranchPipeline).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Doc("(MultiBranchesPipeline) Replay the specified pipeline of the DevOps project").
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
Param(webservice.PathParameter("branch", "the name of branch, same as repository branch.")).
Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
- Returns(http.StatusOK, RespOK, devops.ReplayPipe{}).
- Writes(devops.ReplayPipe{}))
+ Returns(http.StatusOK, RespOK, devops.ReplayPipeline{}).
+ Writes(devops.ReplayPipeline{}))
- // match /blue/rest/organizations/jenkins/pipelines/{devops}/pipelines/{pipeline}/runs/{run}/Replay/
- webservice.Route(webservice.POST("/devops/{devops}/pipelines/{pipeline}/runs/{run}/replay").
- To(devopsapi.ReplayPipeline).
+ // match /blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/branches/{}/runs/
+ webservice.Route(webservice.POST("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/runs").
+ To(projectPipelineHander.RunBranchPipeline).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("Replay pipeline").
+ Doc("(MultiBranchesPipeline) Run the specified pipeline of the DevOps project.").
+ Reads(devops.RunPayload{}).
+ Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
+ Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
+ Param(webservice.PathParameter("branch", "the name of branch, same as repository branch.")).
+ Returns(http.StatusOK, RespOK, devops.RunPipeline{}).
+ Writes(devops.RunPipeline{}))
+
+ // match /blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/branches/{branch}/runs/{run}/artifacts
+ webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}/artifacts").
+ To(projectPipelineHander.GetBranchArtifacts).
+ Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
+ Doc("(MultiBranchesPipeline) Get all artifacts generated from the specified run of the pipeline branch.").
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
+ Param(webservice.PathParameter("branch", "the name of branch, same as repository branch.")).
Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
- Returns(http.StatusOK, RespOK, devops.ReplayPipe{}).
- Writes(devops.ReplayPipe{}))
+ Param(webservice.QueryParameter("start", "the item number that the search starts from.").
+ Required(false).
+ DataFormat("start=%d")).
+ Param(webservice.QueryParameter("limit", "the limit item count of the search.").
+ Required(false).
+ DataFormat("limit=%d")).
+ Returns(http.StatusOK, "The filed of \"Url\" in response can download artifacts", []devops.Artifacts{}).
+ Writes([]devops.Artifacts{}))
// match /blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/branches/{branch}/runs/{run}/log/?start=0
webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}/log").
- To(devopsapi.GetBranchRunLog).
+ To(projectPipelineHander.GetBranchRunLog).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Doc("(MultiBranchesPipeline) Get run logs of the specified pipeline activity.").
Produces("text/plain; charset=utf-8").
@@ -487,77 +523,55 @@ The last one is encrypted info, such as the password of the username-password ty
DataFormat("start=%d").
DefaultValue("start=0")))
- // match /blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/runs/{run}/log/?start=0
- webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/runs/{run}/log").
- To(devopsapi.GetRunLog).
+ // match "/blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/branches/{branch}/runs/{run}/nodes/{node}/steps/{step}/log/?start=0"
+ webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}/nodes/{node}/steps/{step}/log").
+ To(projectPipelineHander.GetBranchStepLog).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("Get run logs of the specified pipeline activity.").
+ Doc("(MultiBranchesPipeline) Get the step logs in the specified pipeline activity.").
Produces("text/plain; charset=utf-8").
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
- Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
+ Param(webservice.PathParameter("branch", "the name of branch, same as repository branch.")).
+ Param(webservice.PathParameter("run", "pipeline run id, the unique id for a pipeline once build.")).
+ Param(webservice.PathParameter("node", "pipeline node id, the stage in pipeline.")).
+ Param(webservice.PathParameter("step", "pipeline step id, the step in pipeline.")).
Param(webservice.QueryParameter("start", "the item number that the search starts from.").
Required(false).
DataFormat("start=%d").
DefaultValue("start=0")))
- // match /blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/branches/{branch}/runs/{run}/artifacts
- webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}/artifacts").
- To(devopsapi.GetBranchArtifacts).
+ // match /blue/rest/organizations/jenkins/pipelines/%s/%s/branches/%s/runs/%s/nodes/%s/steps/?limit=
+ webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}/nodes/{node}/steps").
+ To(projectPipelineHander.GetBranchNodeSteps).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("(MultiBranchesPipeline) Get all artifacts generated from the specified run of the pipeline branch.").
- Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
+ Doc("(MultiBranchesPipeline) Get all steps in the specified node.").
+ Param(webservice.PathParameter("devops", "the name of devops project")).
Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
Param(webservice.PathParameter("branch", "the name of branch, same as repository branch.")).
Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
- Param(webservice.QueryParameter("start", "the item number that the search starts from.").
- Required(false).
- DataFormat("start=%d")).
- Param(webservice.QueryParameter("limit", "the limit item count of the search.").
- Required(false).
- DataFormat("limit=%d")).
- Returns(http.StatusOK, "The filed of \"Url\" in response can download artifacts", []devops.Artifacts{}).
- Writes([]devops.Artifacts{}))
+ Param(webservice.PathParameter("node", "pipeline node ID, the stage in pipeline.")).
+ Returns(http.StatusOK, RespOK, []devops.NodeSteps{}).
+ Writes([]devops.NodeSteps{}))
- // match /blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/runs/{run}/artifacts
- webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/runs/{run}/artifacts").
- To(devopsapi.GetArtifacts).
+ // match Jenkins api "/blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/branches/{branch}/runs/{run}/nodes"
+ webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}/nodes").
+ To(projectPipelineHander.GetBranchPipelineRunNodes).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("Get all artifacts in the specified pipeline.").
+ Doc("(MultiBranchesPipeline) Get run nodes.").
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
- Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
- Param(webservice.QueryParameter("start", "the item number that the search starts from.").
- Required(false).
- DataFormat("start=%d")).
+ Param(webservice.PathParameter("branch", "the name of branch, same as repository branch.")).
+ Param(webservice.PathParameter("run", "pipeline run id, the unique id for a pipeline once build.")).
Param(webservice.QueryParameter("limit", "the limit item count of the search.").
Required(false).
- DataFormat("limit=%d")).
- Returns(http.StatusOK, "The filed of \"Url\" in response can download artifacts", []devops.Artifacts{}).
- Writes([]devops.Artifacts{}))
-
- // match /blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/branches/?filter=&start&limit=
- webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches").
- To(devopsapi.GetPipeBranch).
- Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("(MultiBranchesPipeline) Get all branches in the specified pipeline.").
- Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
- Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
- Param(webservice.QueryParameter("filter", "filter remote scm. e.g. origin").
- Required(false).
- DataFormat("filter=%s")).
- Param(webservice.QueryParameter("start", "the count of branches start.").
- Required(false).
- DataFormat("start=%d").DefaultValue("start=0")).
- Param(webservice.QueryParameter("limit", "the count of branches limit.").
- Required(false).
- DataFormat("limit=%d").DefaultValue("limit=100")).
- Returns(http.StatusOK, RespOK, []devops.PipeBranch{}).
- Writes([]devops.PipeBranch{}))
+ DataFormat("limit=%d").
+ DefaultValue("limit=10000")).
+ Returns(http.StatusOK, RespOK, []devops.BranchPipelineRunNodes{}).
+ Writes([]devops.BranchPipelineRunNodes{}))
// /blue/rest/organizations/jenkins/pipelines/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}/nodes/{node}/steps/{step}
webservice.Route(webservice.POST("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}/nodes/{node}/steps/{step}").
- To(devopsapi.SubmitBranchInputStep).
+ To(projectPipelineHander.SubmitBranchInputStep).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Doc("(MultiBranchesPipeline) Proceed or Break the paused pipeline which waiting for user input.").
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
@@ -569,31 +583,40 @@ The last one is encrypted info, such as the password of the username-password ty
Reads(devops.CheckPlayload{}).
Produces("text/plain; charset=utf-8"))
- // match /blue/rest/organizations/jenkins/pipelines/{devops}/pipelines/{pipeline}/runs/{run}/nodes/{node}/steps/{step}
- webservice.Route(webservice.POST("/devops/{devops}/pipelines/{pipeline}/runs/{run}/nodes/{node}/steps/{step}").
- To(devopsapi.SubmitInputStep).
+ // in scm get all steps in nodes.
+ webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}/nodesdetail").
+ To(projectPipelineHander.GetBranchNodesDetail).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("Proceed or Break the paused pipeline which is waiting for user input.").
- Reads(devops.CheckPlayload{}).
- Produces("text/plain; charset=utf-8").
+ Doc("(MultiBranchesPipeline) Get steps details in an activity node. For a node, the steps which is defined inside the node.").
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
+ Param(webservice.PathParameter("branch", "the name of branch, same as repository branch.")).
Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
- Param(webservice.PathParameter("node", "pipeline node ID, the stage in pipeline.")).
- Param(webservice.PathParameter("step", "pipeline step ID")))
+ Returns(http.StatusOK, RespOK, []devops.NodesDetail{}).
+ Writes(devops.NodesDetail{}))
- // match /job/project-8QnvykoJw4wZ/job/test-1/indexing/consoleText
- webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/consolelog").
- To(devopsapi.GetConsoleLog).
+ // match /blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/branches/?filter=&start&limit=
+ webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches").
+ To(projectPipelineHander.GetPipelineBranch).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("Get scan reponsitory logs in the specified pipeline.").
- Produces("text/plain; charset=utf-8").
+ Doc("(MultiBranchesPipeline) Get all branches in the specified pipeline.").
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
- Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")))
+ Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
+ Param(webservice.QueryParameter("filter", "filter remote scm. e.g. origin").
+ Required(false).
+ DataFormat("filter=%s")).
+ Param(webservice.QueryParameter("start", "the count of branches start.").
+ Required(false).
+ DataFormat("start=%d").DefaultValue("start=0")).
+ Param(webservice.QueryParameter("limit", "the count of branches limit.").
+ Required(false).
+ DataFormat("limit=%d").DefaultValue("limit=100")).
+ Returns(http.StatusOK, RespOK, []devops.PipelineBranch{}).
+ Writes([]devops.PipelineBranch{}))
// match /job/{devops}/job/{pipeline}/build?delay=0
webservice.Route(webservice.POST("/devops/{devops}/pipelines/{pipeline}/scan").
- To(devopsapi.ScanBranch).
+ To(projectPipelineHander.ScanBranch).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Doc("Scan remote Repository, Start a build if have new branch.").
Produces("text/html; charset=utf-8").
@@ -603,39 +626,111 @@ The last one is encrypted info, such as the password of the username-password ty
Required(false).
DataFormat("delay=%d")))
- // match /blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/branches/{}/runs/
- webservice.Route(webservice.POST("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/runs").
- To(devopsapi.RunBranchPipeline).
- Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("(MultiBranchesPipeline) Run the specified pipeline of the DevOps project.").
- Reads(devops.RunPayload{}).
- Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
- Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
- Param(webservice.PathParameter("branch", "the name of branch, same as repository branch.")).
- Returns(http.StatusOK, RespOK, devops.QueuedBlueRun{}).
- Writes(devops.QueuedBlueRun{}))
-
- // match /blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/runs/
- webservice.Route(webservice.POST("/devops/{devops}/pipelines/{pipeline}/runs").
- To(devopsapi.RunPipeline).
+ // match /job/project-8QnvykoJw4wZ/job/test-1/indexing/consoleText
+ webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/consolelog").
+ To(projectPipelineHander.GetConsoleLog).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("Run pipeline.").
- Reads(devops.RunPayload{}).
+ Doc("Get scan reponsitory logs in the specified pipeline.").
+ Produces("text/plain; charset=utf-8").
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
- Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
- Returns(http.StatusOK, RespOK, devops.QueuedBlueRun{}).
- Writes(devops.QueuedBlueRun{}))
+ Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")))
// match /crumbIssuer/api/json/
webservice.Route(webservice.GET("/crumbissuer").
- To(devopsapi.GetCrumb).
+ To(projectPipelineHander.GetCrumb).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Doc("Get crumb issuer. A CrumbIssuer represents an algorithm to generate a nonce value, known as a crumb, to counter cross site request forgery exploits. Crumbs are typically hashes incorporating information that uniquely identifies an agent that sends a request, along with a guarded secret so that the crumb value cannot be forged by a third party.").
Returns(http.StatusOK, RespOK, devops.Crumb{}).
Writes(devops.Crumb{}))
+ // match "/blue/rest/organizations/jenkins/scm/%s/servers/"
+ webservice.Route(webservice.GET("/scms/{scm}/servers").
+ To(projectPipelineHander.GetSCMServers).
+ Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsScmTag}).
+ Doc("List all servers in the jenkins.").
+ Param(webservice.PathParameter("scm", "The ID of the source configuration management (SCM).")).
+ Returns(http.StatusOK, RespOK, []devops.SCMServer{}).
+ Writes([]devops.SCMServer{}))
+
+ // match "/blue/rest/organizations/jenkins/scm/{scm}/organizations/?credentialId=github"
+ webservice.Route(webservice.GET("/scms/{scm}/organizations").
+ To(projectPipelineHander.GetSCMOrg).
+ Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsScmTag}).
+ Doc("List all organizations of the specified source configuration management (SCM) such as Github.").
+ Param(webservice.PathParameter("scm", "the ID of the source configuration management (SCM).")).
+ Param(webservice.QueryParameter("credentialId", "credential ID for source configuration management (SCM).").
+ Required(true).
+ DataFormat("credentialId=%s")).
+ Returns(http.StatusOK, RespOK, []devops.SCMOrg{}).
+ Writes([]devops.SCMOrg{}))
+
+ // match "/blue/rest/organizations/jenkins/scm/{scm}/organizations/{organization}/repositories/?credentialId=&pageNumber&pageSize="
+ webservice.Route(webservice.GET("/scms/{scm}/organizations/{organization}/repositories").
+ To(projectPipelineHander.GetOrgRepo).
+ Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsScmTag}).
+ Doc("List all repositories in the specified organization.").
+ Param(webservice.PathParameter("scm", "The ID of the source configuration management (SCM).")).
+ Param(webservice.PathParameter("organization", "organization ID, such as github username.")).
+ Param(webservice.QueryParameter("credentialId", "credential ID for SCM.").
+ Required(true).
+ DataFormat("credentialId=%s")).
+ Param(webservice.QueryParameter("pageNumber", "page number.").
+ Required(true).
+ DataFormat("pageNumber=%d")).
+ Param(webservice.QueryParameter("pageSize", "the item count of one page.").
+ Required(true).
+ DataFormat("pageSize=%d")).
+ Returns(http.StatusOK, RespOK, []devops.OrgRepo{}).
+ Writes([]devops.OrgRepo{}))
+
+ // match "/blue/rest/organizations/jenkins/scm/%s/servers/" create bitbucket server
+ webservice.Route(webservice.POST("/scms/{scm}/servers").
+ To(projectPipelineHander.CreateSCMServers).
+ Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsScmTag}).
+ Doc("Create scm server in the jenkins.").
+ Param(webservice.PathParameter("scm", "The ID of the source configuration management (SCM).")).
+ Reads(devops.CreateScmServerReq{}).
+ Returns(http.StatusOK, RespOK, devops.SCMServer{}).
+ Writes(devops.SCMServer{}))
+
+ // match "/blue/rest/organizations/jenkins/scm/github/validate/"
+ webservice.Route(webservice.POST("/scms/{scm}/verify").
+ To(projectPipelineHander.Validate).
+ Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsScmTag}).
+ Doc("Validate the access token of the specified source configuration management (SCM) such as Github").
+ Param(webservice.PathParameter("scm", "the ID of the source configuration management (SCM).")).
+ Returns(http.StatusOK, RespOK, devops.Validates{}).
+ Writes(devops.Validates{}))
+
+ // match /git/notifyCommit/?url=
+ webservice.Route(webservice.GET("/webhook/git").
+ To(projectPipelineHander.GetNotifyCommit).
+ Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsWebhookTag}).
+ Doc("Get commit notification by HTTP GET method. Git webhook will request here.").
+ Produces("text/plain; charset=utf-8").
+ Param(webservice.QueryParameter("url", "Git url").
+ Required(true).
+ DataFormat("url=%s")))
+
+ // Gitlab or some other scm managers can only use HTTP method. match /git/notifyCommit/?url=
+ webservice.Route(webservice.POST("/webhook/git").
+ To(projectPipelineHander.PostNotifyCommit).
+ Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsWebhookTag}).
+ Doc("Get commit notification by HTTP POST method. Git webhook will request here.").
+ Consumes("application/json").
+ Produces("text/plain; charset=utf-8").
+ Param(webservice.QueryParameter("url", "Git url").
+ Required(true).
+ DataFormat("url=%s")))
+
+ webservice.Route(webservice.POST("/webhook/github").
+ To(projectPipelineHander.GithubWebhook).
+ Consumes("application/x-www-form-urlencoded", "application/json").
+ Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsWebhookTag}).
+ Doc("Get commit notification. Github webhook will request here."))
+
webservice.Route(webservice.PUT("/namespaces/{namespace}/s2ibinaries/{s2ibinary}/file").
- To(devopsapi.UploadS2iBinary).
+ To(s2iHandler.UploadS2iBinaryHandler).
Consumes("multipart/form-data").
Produces(restful.MIME_JSON).
Doc("Upload S2iBinary file").
@@ -646,7 +741,7 @@ The last one is encrypted info, such as the password of the username-password ty
Returns(http.StatusOK, RespOK, devopsv1alpha1.S2iBinary{}))
webservice.Route(webservice.GET("/namespaces/{namespace}/s2ibinaries/{s2ibinary}/file/{file}").
- To(devopsapi.DownloadS2iBinary).
+ To(s2iHandler.DownloadS2iBinaryHandler).
Produces(restful.MIME_OCTET).
Doc("Download S2iBinary file").
Param(webservice.PathParameter("namespace", "the name of namespaces")).
@@ -655,7 +750,7 @@ The last one is encrypted info, such as the password of the username-password ty
Returns(http.StatusOK, RespOK, nil))
webservice.Route(webservice.POST("/devops/{devops}/pipelines/{pipeline}/checkScriptCompile").
- To(devopsapi.CheckScriptCompile).
+ To(projectPipelineHander.CheckScriptCompile).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.QueryParameter("pipeline", "the name of the CI/CD pipeline").
@@ -669,7 +764,7 @@ The last one is encrypted info, such as the password of the username-password ty
Writes(devops.CheckScript{}))
webservice.Route(webservice.POST("/devops/{devops}/checkCron").
- To(devopsapi.CheckCron).
+ To(projectPipelineHander.CheckCron).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
@@ -679,67 +774,9 @@ The last one is encrypted info, such as the password of the username-password ty
Returns(http.StatusOK, RespOK, devops.CheckCronRes{}).
Writes(devops.CheckCronRes{}))
- // match /blue/rest/organizations/jenkins/pipelines/{devops}/{pipeline}/runs/{run}/
- webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/runs/{run}").
- To(devopsapi.GetPipelineRun).
- Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("Get all activities in the specified pipeline.").
- Param(webservice.PathParameter("devops", "the name of devops project")).
- Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
- Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
- Returns(http.StatusOK, RespOK, devops.PipelineRun{}).
- Writes(devops.PipelineRun{}))
-
- // match /blue/rest/organizations/jenkins/pipelines/{devops}/pipelines/{pipeline}/branches/{branch}
- webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches/{branch}").
- To(devopsapi.GetBranchPipeline).
- Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("(MultiBranchesPipeline) Get all activities in the specified pipeline.").
- Param(webservice.PathParameter("devops", "the name of devops project")).
- Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
- Param(webservice.PathParameter("branch", "the name of branch, same as repository branch")).
- Returns(http.StatusOK, RespOK, devops.BranchPipeline{}).
- Writes(devops.BranchPipeline{}))
-
- // match /blue/rest/organizations/jenkins/pipelines/{devops}/pipelines/{pipeline}/runs/{run}/nodes/?limit=10000
- webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/runs/{run}/nodes").
- To(devopsapi.GetPipelineRunNodes).
- Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("Get all nodes in the specified activity. node is the stage in the pipeline task").
- Param(webservice.PathParameter("devops", "the name of devops project")).
- Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
- Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build")).
- Returns(http.StatusOK, RespOK, []devops.PipelineRunNodes{}).
- Writes([]devops.PipelineRunNodes{}))
-
- // match /blue/rest/organizations/jenkins/pipelines/%s/%s/branches/%s/runs/%s/nodes/%s/steps/?limit=
- webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}/nodes/{node}/steps").
- To(devopsapi.GetBranchNodeSteps).
- Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("(MultiBranchesPipeline) Get all steps in the specified node.").
- Param(webservice.PathParameter("devops", "the name of devops project")).
- Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
- Param(webservice.PathParameter("branch", "the name of branch, same as repository branch.")).
- Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
- Param(webservice.PathParameter("node", "pipeline node ID, the stage in pipeline.")).
- Returns(http.StatusOK, RespOK, []devops.NodeSteps{}).
- Writes([]devops.NodeSteps{}))
-
- // match /blue/rest/organizations/jenkins/pipelines/%s/%s/runs/%s/nodes/%s/steps/?limit=
- webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/runs/{run}/nodes/{node}/steps").
- To(devopsapi.GetNodeSteps).
- Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("Get all steps in the specified node.").
- Param(webservice.PathParameter("devops", "the name of devops project")).
- Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
- Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build")).
- Param(webservice.PathParameter("node", "pipeline node ID, the stage in pipeline.")).
- Returns(http.StatusOK, RespOK, []devops.NodeSteps{}).
- Writes([]devops.NodeSteps{}))
-
// match /pipeline-model-converter/toJenkinsfile
webservice.Route(webservice.POST("/tojenkinsfile").
- To(devopsapi.ToJenkinsfile).
+ To(projectPipelineHander.ToJenkinsfile).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsJenkinsfileTag}).
Consumes("application/x-www-form-urlencoded").
Produces("application/json", "charset=utf-8").
@@ -750,7 +787,7 @@ The last one is encrypted info, such as the password of the username-password ty
// match /pipeline-model-converter/toJson
webservice.Route(webservice.POST("/tojson").
- To(devopsapi.ToJson).
+ To(projectPipelineHander.ToJson).
Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsJenkinsfileTag}).
Consumes("application/x-www-form-urlencoded").
Produces("application/json", "charset=utf-8").
@@ -759,57 +796,6 @@ The last one is encrypted info, such as the password of the username-password ty
Returns(http.StatusOK, RespOK, devops.ResJson{}).
Writes(devops.ResJson{}))
- // match /git/notifyCommit/?url=
- webservice.Route(webservice.GET("/webhook/git").
- To(devopsapi.GetNotifyCommit).
- Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsWebhookTag}).
- Doc("Get commit notification by HTTP GET method. Git webhook will request here.").
- Produces("text/plain; charset=utf-8").
- Param(webservice.QueryParameter("url", "Git url").
- Required(true).
- DataFormat("url=%s")))
-
- // Gitlab or some other scm managers can only use HTTP method. match /git/notifyCommit/?url=
- webservice.Route(webservice.POST("/webhook/git").
- To(devopsapi.PostNotifyCommit).
- Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsWebhookTag}).
- Doc("Get commit notification by HTTP POST method. Git webhook will request here.").
- Consumes("application/json").
- Produces("text/plain; charset=utf-8").
- Param(webservice.QueryParameter("url", "Git url").
- Required(true).
- DataFormat("url=%s")))
-
- webservice.Route(webservice.POST("/webhook/github").
- To(devopsapi.GithubWebhook).
- Consumes("application/x-www-form-urlencoded", "application/json").
- Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsWebhookTag}).
- Doc("Get commit notification. Github webhook will request here."))
-
- // in scm get all steps in nodes.
- webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/branches/{branch}/runs/{run}/nodesdetail").
- To(devopsapi.GetBranchNodesDetail).
- Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("(MultiBranchesPipeline) Get steps details in an activity node. For a node, the steps which is defined inside the node.").
- Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
- Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
- Param(webservice.PathParameter("branch", "the name of branch, same as repository branch.")).
- Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
- Returns(http.StatusOK, RespOK, []devops.NodesDetail{}).
- Writes(devops.NodesDetail{}))
-
- // out of scm get all steps in nodes.
- webservice.Route(webservice.GET("/devops/{devops}/pipelines/{pipeline}/runs/{run}/nodesdetail").
- To(devopsapi.GetNodesDetail).
- Metadata(restfulspec.KeyOpenAPITags, []string{constants.DevOpsPipelineTag}).
- Doc("Get steps details inside a activity node. For a node, the steps which defined inside the node.").
- Param(webservice.PathParameter("devops", "DevOps project's ID, e.g. project-RRRRAzLBlLEm")).
- Param(webservice.PathParameter("pipeline", "the name of the CI/CD pipeline")).
- Param(webservice.PathParameter("branch", "the name of branch, same as repository branch.")).
- Param(webservice.PathParameter("run", "pipeline run ID, the unique ID for a pipeline once build.")).
- Returns(http.StatusOK, RespOK, []devops.NodesDetail{}).
- Writes(devops.NodesDetail{}))
-
c.Add(webservice)
return nil
diff --git a/pkg/apiserver/devops/s2ibinary.go b/pkg/kapis/devops/v1alpha2/s2ibinary.go
similarity index 82%
rename from pkg/apiserver/devops/s2ibinary.go
rename to pkg/kapis/devops/v1alpha2/s2ibinary.go
index bf4eeee5c0394b6d08a79297d694926efe243c95..0ce781f5a2a93dddd0521fa3a9122e8e7050ae7f 100644
--- a/pkg/apiserver/devops/s2ibinary.go
+++ b/pkg/kapis/devops/v1alpha2/s2ibinary.go
@@ -1,4 +1,4 @@
-package devops
+package v1alpha2
import (
"code.cloudfoundry.org/bytefmt"
@@ -11,7 +11,11 @@ import (
"net/http"
)
-func UploadS2iBinary(req *restful.Request, resp *restful.Response) {
+type S2iBinaryHandler struct {
+ s2iUploader devops.S2iBinaryUploader
+}
+
+func (h S2iBinaryHandler) UploadS2iBinaryHandler(req *restful.Request, resp *restful.Response) {
ns := req.PathParameter("namespace")
name := req.PathParameter("s2ibinary")
@@ -62,7 +66,7 @@ func UploadS2iBinary(req *restful.Request, resp *restful.Response) {
}
}
- s2ibin, err := devops.UploadS2iBinary(ns, name, filemd5, req.Request.MultipartForm.File["s2ibinary"][0])
+ s2ibin, err := h.s2iUploader.UploadS2iBinary(ns, name, filemd5, req.Request.MultipartForm.File["s2ibinary"][0])
if err != nil {
klog.Errorf("%+v", err)
errors.ParseSvcErr(err, resp)
@@ -72,11 +76,11 @@ func UploadS2iBinary(req *restful.Request, resp *restful.Response) {
}
-func DownloadS2iBinary(req *restful.Request, resp *restful.Response) {
+func (h S2iBinaryHandler) DownloadS2iBinaryHandler(req *restful.Request, resp *restful.Response) {
ns := req.PathParameter("namespace")
name := req.PathParameter("s2ibinary")
fileName := req.PathParameter("file")
- url, err := devops.DownloadS2iBinary(ns, name, fileName)
+ url, err := h.s2iUploader.DownloadS2iBinary(ns, name, fileName)
if err != nil {
klog.Errorf("%+v", err)
errors.ParseSvcErr(err, resp)
diff --git a/pkg/kapis/tenant/v1alpha2/devops.go b/pkg/kapis/tenant/v1alpha2/devops.go
new file mode 100644
index 0000000000000000000000000000000000000000..1295f42b8fdbf663a98b118aeb80f4f1cf0051fb
--- /dev/null
+++ b/pkg/kapis/tenant/v1alpha2/devops.go
@@ -0,0 +1,154 @@
+/*
+
+ Copyright 2019 The KubeSphere Authors.
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+*/
+package v1alpha2
+
+import (
+ "github.com/emicklei/go-restful"
+ "k8s.io/klog"
+ "kubesphere.io/kubesphere/pkg/api"
+ devopsv1alpha2 "kubesphere.io/kubesphere/pkg/api/devops/v1alpha2"
+ "kubesphere.io/kubesphere/pkg/constants"
+ "kubesphere.io/kubesphere/pkg/server/errors"
+ "kubesphere.io/kubesphere/pkg/server/params"
+ "net/http"
+)
+
+func (h *tenantHandler) DeleteDevOpsProjectHandler(req *restful.Request, resp *restful.Response) {
+ projectId := req.PathParameter("devops")
+ workspaceName := req.PathParameter("workspace")
+ username := req.HeaderParameter(constants.UserNameHeader)
+
+ _, err := h.tenant.GetWorkspace(workspaceName)
+
+ if err != nil {
+ klog.Errorf("%+v", err)
+ errors.ParseSvcErr(restful.NewError(http.StatusBadRequest, err.Error()), resp)
+ return
+ }
+
+ err = h.tenant.DeleteDevOpsProject(projectId, username)
+
+ if err != nil {
+ klog.Errorf("%+v", err)
+ errors.ParseSvcErr(err, resp)
+ return
+ }
+
+ resp.WriteAsJson(errors.None)
+}
+
+func (h *tenantHandler) CreateDevOpsProjectHandler(req *restful.Request, resp *restful.Response) {
+
+ workspaceName := req.PathParameter("workspace")
+ username := req.HeaderParameter(constants.UserNameHeader)
+
+ var devops devopsv1alpha2.DevOpsProject
+
+ err := req.ReadEntity(&devops)
+
+ if err != nil {
+ klog.Infof("%+v", err)
+ errors.ParseSvcErr(restful.NewError(http.StatusBadRequest, err.Error()), resp)
+ return
+ }
+
+ klog.Infoln("create workspace", username, workspaceName, devops)
+ project, err := h.tenant.CreateDevOpsProject(username, workspaceName, &devops)
+
+ if err != nil {
+ klog.Errorf("%+v", err)
+ errors.ParseSvcErr(err, resp)
+ return
+ }
+
+ resp.WriteAsJson(project)
+}
+
+func (h *tenantHandler) GetDevOpsProjectsCountHandler(req *restful.Request, resp *restful.Response) {
+ username := req.HeaderParameter(constants.UserNameHeader)
+
+ result, err := h.tenant.GetDevOpsProjectsCount(username)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ errors.ParseSvcErr(err, resp)
+ return
+ }
+ resp.WriteAsJson(struct {
+ Count uint32 `json:"count"`
+ }{Count: result})
+}
+
+func (h *tenantHandler) ListDevOpsProjectsHandler(req *restful.Request, resp *restful.Response) {
+
+ workspace := req.PathParameter("workspace")
+ username := req.PathParameter("member")
+ if username == "" {
+ username = req.HeaderParameter(constants.UserNameHeader)
+ }
+ orderBy := req.QueryParameter(params.OrderByParam)
+ reverse := params.GetBoolValueWithDefault(req, params.ReverseParam, false)
+ limit, offset := params.ParsePaging(req)
+ conditions, err := params.ParseConditions(req)
+
+ if err != nil {
+ klog.Errorf("%+v", err)
+ errors.ParseSvcErr(restful.NewError(http.StatusBadRequest, err.Error()), resp)
+ return
+ }
+
+ result, err := h.tenant.ListDevOpsProjects(workspace, username, conditions, orderBy, reverse, limit, offset)
+
+ if err != nil {
+ klog.Errorf("%+v", err)
+ errors.ParseSvcErr(err, resp)
+ return
+ }
+
+ resp.WriteAsJson(result)
+}
+
+func (h *tenantHandler) ListDevOpsRules(req *restful.Request, resp *restful.Response) {
+
+ devops := req.PathParameter("devops")
+ username := req.HeaderParameter(constants.UserNameHeader)
+
+ rules, err := h.tenant.GetUserDevOpsSimpleRules(username, devops)
+
+ if err != nil {
+ klog.Errorf("%+v", err)
+ errors.ParseSvcErr(err, resp)
+ return
+ }
+
+ resp.WriteAsJson(rules)
+}
+
+func (h *tenantHandler) ListDevopsRules(req *restful.Request, resp *restful.Response) {
+
+ devops := req.PathParameter("devops")
+ username := req.HeaderParameter(constants.UserNameHeader)
+
+ rules, err := h.tenant.GetUserDevOpsSimpleRules(username, devops)
+
+ if err != nil {
+ api.HandleInternalError(resp, err)
+ return
+ }
+
+ resp.WriteAsJson(rules)
+}
diff --git a/pkg/kapis/tenant/v1alpha2/handler.go b/pkg/kapis/tenant/v1alpha2/handler.go
index e068fb14671d846f1adaa1e2770d3f0c728ca0fb..b4a70208a85c01724ebb120f8ab2b1e57e59c4b6 100644
--- a/pkg/kapis/tenant/v1alpha2/handler.go
+++ b/pkg/kapis/tenant/v1alpha2/handler.go
@@ -8,7 +8,6 @@ import (
"k8s.io/apimachinery/pkg/util/net"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/api"
- devopsv1alpha2 "kubesphere.io/kubesphere/pkg/api/devops/v1alpha2"
loggingv1alpha2 "kubesphere.io/kubesphere/pkg/api/logging/v1alpha2"
"kubesphere.io/kubesphere/pkg/apiserver/logging"
"kubesphere.io/kubesphere/pkg/constants"
@@ -184,45 +183,6 @@ func (h *tenantHandler) DeleteNamespace(req *restful.Request, resp *restful.Resp
resp.WriteAsJson(errors.None)
}
-func (h *tenantHandler) ListDevopsProjects(req *restful.Request, resp *restful.Response) {
-
- workspace := req.PathParameter("workspace")
- username := req.PathParameter("member")
- if username == "" {
- username = req.HeaderParameter(constants.UserNameHeader)
- }
- orderBy := params.GetStringValueWithDefault(req, params.OrderByParam, v1alpha2.CreateTime)
- limit, offset := params.ParsePaging(req)
- reverse := params.GetBoolValueWithDefault(req, params.ReverseParam, true)
- conditions, err := params.ParseConditions(req)
-
- if err != nil {
- api.HandleBadRequest(resp, err)
- return
- }
-
- result, err := tenant.ListDevopsProjects(workspace, username, conditions, orderBy, reverse, limit, offset)
-
- if err != nil {
- api.HandleInternalError(resp, err)
- return
- }
-
- resp.WriteAsJson(result)
-}
-
-func (h *tenantHandler) GetDevOpsProjectsCount(req *restful.Request, resp *restful.Response) {
- username := req.HeaderParameter(constants.UserNameHeader)
-
- result, err := tenant.GetDevOpsProjectsCount(username)
- if err != nil {
- api.HandleInternalError(resp, err)
- return
- }
- resp.WriteAsJson(struct {
- Count uint32 `json:"count"`
- }{Count: result})
-}
func (h *tenantHandler) DeleteDevopsProject(req *restful.Request, resp *restful.Response) {
projectId := req.PathParameter("devops")
workspace := req.PathParameter("workspace")
@@ -235,7 +195,7 @@ func (h *tenantHandler) DeleteDevopsProject(req *restful.Request, resp *restful.
return
}
- err = tenant.DeleteDevOpsProject(projectId, username)
+ err = h.tenant.DeleteDevOpsProject(projectId, username)
if err != nil {
api.HandleInternalError(resp, err)
@@ -245,30 +205,6 @@ func (h *tenantHandler) DeleteDevopsProject(req *restful.Request, resp *restful.
resp.WriteAsJson(errors.None)
}
-func (h *tenantHandler) CreateDevopsProject(req *restful.Request, resp *restful.Response) {
-
- workspaceName := req.PathParameter("workspace")
- username := req.HeaderParameter(constants.UserNameHeader)
-
- var devops devopsv1alpha2.DevOpsProject
-
- err := req.ReadEntity(&devops)
-
- if err != nil {
- api.HandleInternalError(resp, err)
- return
- }
-
- project, err := tenant.CreateDevopsProject(username, workspaceName, &devops)
-
- if err != nil {
- api.HandleInternalError(resp, err)
- return
- }
-
- resp.WriteAsJson(project)
-}
-
func (h *tenantHandler) ListNamespaceRules(req *restful.Request, resp *restful.Response) {
namespace := req.PathParameter("namespace")
username := req.HeaderParameter(constants.UserNameHeader)
@@ -283,21 +219,6 @@ func (h *tenantHandler) ListNamespaceRules(req *restful.Request, resp *restful.R
resp.WriteAsJson(rules)
}
-func (h *tenantHandler) ListDevopsRules(req *restful.Request, resp *restful.Response) {
-
- devops := req.PathParameter("devops")
- username := req.HeaderParameter(constants.UserNameHeader)
-
- rules, err := tenant.GetUserDevopsSimpleRules(username, devops)
-
- if err != nil {
- api.HandleInternalError(resp, err)
- return
- }
-
- resp.WriteAsJson(rules)
-}
-
func (h *tenantHandler) LogQuery(req *restful.Request, resp *restful.Response) {
operation := req.QueryParameter("operation")
req, err := h.regenerateLoggingRequest(req)
diff --git a/pkg/kapis/tenant/v1alpha2/register.go b/pkg/kapis/tenant/v1alpha2/register.go
index bca9d087c117f4904f635558451b3dbe3651b8a9..cc1d61c72ddcf90860ba7e657f240c7f0afad3fe 100644
--- a/pkg/kapis/tenant/v1alpha2/register.go
+++ b/pkg/kapis/tenant/v1alpha2/register.go
@@ -103,7 +103,7 @@ func AddToContainer(c *restful.Container) error {
Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag}))
ws.Route(ws.GET("/workspaces/{workspace}/devops").
- To(handler.ListDevopsProjects).
+ To(handler.ListDevOpsProjectsHandler).
Param(ws.PathParameter("workspace", "workspace name")).
Param(ws.QueryParameter(params.PagingParam, "page").
Required(false).
@@ -115,7 +115,7 @@ func AddToContainer(c *restful.Container) error {
Doc("List devops projects for the current user").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag}))
ws.Route(ws.GET("/workspaces/{workspace}/members/{member}/devops").
- To(handler.ListDevopsProjects).
+ To(handler.ListDevOpsProjectsHandler).
Param(ws.PathParameter("workspace", "workspace name")).
Param(ws.PathParameter("member", "workspace member's username")).
Param(ws.QueryParameter(params.PagingParam, "page").
@@ -129,14 +129,14 @@ func AddToContainer(c *restful.Container) error {
Doc("List the devops projects for the workspace member").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag}))
ws.Route(ws.GET("/devopscount").
- To(handler.GetDevOpsProjectsCount).
+ To(handler.GetDevOpsProjectsCountHandler).
Returns(http.StatusOK, api.StatusOK, struct {
Count uint32 `json:"count"`
}{}).
Doc("Get the devops projects count for the member").
Metadata(restfulspec.KeyOpenAPITags, []string{constants.TenantResourcesTag}))
ws.Route(ws.POST("/workspaces/{workspace}/devops").
- To(handler.CreateDevopsProject).
+ To(handler.CreateDevOpsProjectHandler).
Param(ws.PathParameter("workspace", "workspace name")).
Doc("Create a devops project in the specified workspace").
Reads(devopsv1alpha2.DevOpsProject{}).
diff --git a/pkg/kapis/terminal/v1alpha2/handler.go b/pkg/kapis/terminal/v1alpha2/handler.go
index af39e58c5b18c8c57df597d9be7dd0ac9024a728..c8e6ea553f006d8586ee5fdd261ea854631b7477 100644
--- a/pkg/kapis/terminal/v1alpha2/handler.go
+++ b/pkg/kapis/terminal/v1alpha2/handler.go
@@ -1,43 +1,43 @@
package v1alpha2
import (
- "github.com/emicklei/go-restful"
- "github.com/gorilla/websocket"
- "k8s.io/client-go/kubernetes"
- "k8s.io/client-go/rest"
- "k8s.io/klog"
- "kubesphere.io/kubesphere/pkg/models/terminal"
- "net/http"
+ "github.com/emicklei/go-restful"
+ "github.com/gorilla/websocket"
+ "k8s.io/client-go/kubernetes"
+ "k8s.io/client-go/rest"
+ "k8s.io/klog"
+ "kubesphere.io/kubesphere/pkg/models/terminal"
+ "net/http"
)
var upgrader = websocket.Upgrader{
- ReadBufferSize: 1024,
- WriteBufferSize: 1024,
- // Allow connections from any Origin
- CheckOrigin: func(r *http.Request) bool { return true },
+ ReadBufferSize: 1024,
+ WriteBufferSize: 1024,
+ // Allow connections from any Origin
+ CheckOrigin: func(r *http.Request) bool { return true },
}
type terminalHandler struct {
- terminaler terminal.Interface
+ terminaler terminal.Interface
}
func newTerminalHandler(client kubernetes.Interface, config *rest.Config) *terminalHandler {
- return &terminalHandler{
- terminaler: terminal.NewTerminaler(client, config),
- }
+ return &terminalHandler{
+ terminaler: terminal.NewTerminaler(client, config),
+ }
}
func (t *terminalHandler) handleTerminalSession(request *restful.Request, response *restful.Response) {
- namespace := request.PathParameter("namespace")
- podName := request.PathParameter("pod")
- containerName := request.QueryParameter("container")
- shell := request.QueryParameter("shell")
+ namespace := request.PathParameter("namespace")
+ podName := request.PathParameter("pod")
+ containerName := request.QueryParameter("container")
+ shell := request.QueryParameter("shell")
- conn, err := upgrader.Upgrade(response.ResponseWriter, request.Request, nil)
- if err != nil {
- klog.Warning(err)
- return
- }
+ conn, err := upgrader.Upgrade(response.ResponseWriter, request.Request, nil)
+ if err != nil {
+ klog.Warning(err)
+ return
+ }
- t.terminaler.HandleSession(shell, namespace, podName, containerName, conn)
-}
\ No newline at end of file
+ t.terminaler.HandleSession(shell, namespace, podName, containerName, conn)
+}
diff --git a/pkg/models/devops/common.go b/pkg/models/devops/common.go
index 7d0af83850c11336a3156a0895495aa9b6bc4eb3..c23288c493f3e000b64982b394717f2032e39758 100644
--- a/pkg/models/devops/common.go
+++ b/pkg/models/devops/common.go
@@ -14,13 +14,7 @@ limitations under the License.
package devops
import (
- "fmt"
"github.com/fatih/structs"
- "k8s.io/klog"
- "kubesphere.io/kubesphere/pkg/db"
- "kubesphere.io/kubesphere/pkg/gojenkins"
- "kubesphere.io/kubesphere/pkg/simple/client"
- "kubesphere.io/kubesphere/pkg/utils/reflectutils"
"kubesphere.io/kubesphere/pkg/utils/stringutils"
)
@@ -67,298 +61,3 @@ const (
const (
KS_ADMIN = "admin"
)
-
-const (
- ProjectOwner = "owner"
- ProjectMaintainer = "maintainer"
- ProjectDeveloper = "developer"
- ProjectReporter = "reporter"
-)
-
-const (
- JenkinsAllUserRoleName = "kubesphere-user"
-)
-
-type Role struct {
- Name string `json:"name" description:"role's name e.g. owner'"`
- Description string `json:"description" description:"role 's description'"`
-}
-
-var DefaultRoles = []*Role{
- {
- Name: ProjectOwner,
- Description: "Owner have access to do all the operations of a DevOps project and own the highest permissions as well.",
- },
- {
- Name: ProjectMaintainer,
- Description: "Maintainer have access to manage pipeline and credential configuration in a DevOps project.",
- },
- {
- Name: ProjectDeveloper,
- Description: "Developer is able to view and trigger the pipeline.",
- },
- {
- Name: ProjectReporter,
- Description: "Reporter is only allowed to view the status of the pipeline.",
- },
-}
-
-var AllRoleSlice = []string{ProjectDeveloper, ProjectReporter, ProjectMaintainer, ProjectOwner}
-
-var JenkinsOwnerProjectPermissionIds = &gojenkins.ProjectPermissionIds{
- CredentialCreate: true,
- CredentialDelete: true,
- CredentialManageDomains: true,
- CredentialUpdate: true,
- CredentialView: true,
- ItemBuild: true,
- ItemCancel: true,
- ItemConfigure: true,
- ItemCreate: true,
- ItemDelete: true,
- ItemDiscover: true,
- ItemMove: true,
- ItemRead: true,
- ItemWorkspace: true,
- RunDelete: true,
- RunReplay: true,
- RunUpdate: true,
- SCMTag: true,
-}
-
-var JenkinsProjectPermissionMap = map[string]gojenkins.ProjectPermissionIds{
- ProjectOwner: {
- CredentialCreate: true,
- CredentialDelete: true,
- CredentialManageDomains: true,
- CredentialUpdate: true,
- CredentialView: true,
- ItemBuild: true,
- ItemCancel: true,
- ItemConfigure: true,
- ItemCreate: true,
- ItemDelete: true,
- ItemDiscover: true,
- ItemMove: true,
- ItemRead: true,
- ItemWorkspace: true,
- RunDelete: true,
- RunReplay: true,
- RunUpdate: true,
- SCMTag: true,
- },
- ProjectMaintainer: {
- CredentialCreate: true,
- CredentialDelete: true,
- CredentialManageDomains: true,
- CredentialUpdate: true,
- CredentialView: true,
- ItemBuild: true,
- ItemCancel: true,
- ItemConfigure: false,
- ItemCreate: true,
- ItemDelete: false,
- ItemDiscover: true,
- ItemMove: false,
- ItemRead: true,
- ItemWorkspace: true,
- RunDelete: true,
- RunReplay: true,
- RunUpdate: true,
- SCMTag: true,
- },
- ProjectDeveloper: {
- CredentialCreate: false,
- CredentialDelete: false,
- CredentialManageDomains: false,
- CredentialUpdate: false,
- CredentialView: false,
- ItemBuild: true,
- ItemCancel: true,
- ItemConfigure: false,
- ItemCreate: false,
- ItemDelete: false,
- ItemDiscover: true,
- ItemMove: false,
- ItemRead: true,
- ItemWorkspace: true,
- RunDelete: true,
- RunReplay: true,
- RunUpdate: true,
- SCMTag: false,
- },
- ProjectReporter: {
- CredentialCreate: false,
- CredentialDelete: false,
- CredentialManageDomains: false,
- CredentialUpdate: false,
- CredentialView: false,
- ItemBuild: false,
- ItemCancel: false,
- ItemConfigure: false,
- ItemCreate: false,
- ItemDelete: false,
- ItemDiscover: true,
- ItemMove: false,
- ItemRead: true,
- ItemWorkspace: false,
- RunDelete: false,
- RunReplay: false,
- RunUpdate: false,
- SCMTag: false,
- },
-}
-
-var JenkinsPipelinePermissionMap = map[string]gojenkins.ProjectPermissionIds{
- ProjectOwner: {
- CredentialCreate: true,
- CredentialDelete: true,
- CredentialManageDomains: true,
- CredentialUpdate: true,
- CredentialView: true,
- ItemBuild: true,
- ItemCancel: true,
- ItemConfigure: true,
- ItemCreate: true,
- ItemDelete: true,
- ItemDiscover: true,
- ItemMove: true,
- ItemRead: true,
- ItemWorkspace: true,
- RunDelete: true,
- RunReplay: true,
- RunUpdate: true,
- SCMTag: true,
- },
- ProjectMaintainer: {
- CredentialCreate: true,
- CredentialDelete: true,
- CredentialManageDomains: true,
- CredentialUpdate: true,
- CredentialView: true,
- ItemBuild: true,
- ItemCancel: true,
- ItemConfigure: true,
- ItemCreate: true,
- ItemDelete: true,
- ItemDiscover: true,
- ItemMove: true,
- ItemRead: true,
- ItemWorkspace: true,
- RunDelete: true,
- RunReplay: true,
- RunUpdate: true,
- SCMTag: true,
- },
- ProjectDeveloper: {
- CredentialCreate: false,
- CredentialDelete: false,
- CredentialManageDomains: false,
- CredentialUpdate: false,
- CredentialView: false,
- ItemBuild: true,
- ItemCancel: true,
- ItemConfigure: false,
- ItemCreate: false,
- ItemDelete: false,
- ItemDiscover: true,
- ItemMove: false,
- ItemRead: true,
- ItemWorkspace: true,
- RunDelete: true,
- RunReplay: true,
- RunUpdate: true,
- SCMTag: false,
- },
- ProjectReporter: {
- CredentialCreate: false,
- CredentialDelete: false,
- CredentialManageDomains: false,
- CredentialUpdate: false,
- CredentialView: false,
- ItemBuild: false,
- ItemCancel: false,
- ItemConfigure: false,
- ItemCreate: false,
- ItemDelete: false,
- ItemDiscover: true,
- ItemMove: false,
- ItemRead: true,
- ItemWorkspace: false,
- RunDelete: false,
- RunReplay: false,
- RunUpdate: false,
- SCMTag: false,
- },
-}
-
-func GetProjectRoleName(projectId, role string) string {
- return fmt.Sprintf("%s-%s-project", projectId, role)
-}
-
-func GetPipelineRoleName(projectId, role string) string {
- return fmt.Sprintf("%s-%s-pipeline", projectId, role)
-}
-
-func GetProjectRolePattern(projectId string) string {
- return fmt.Sprintf("^%s$", projectId)
-}
-
-func GetPipelineRolePattern(projectId string) string {
- return fmt.Sprintf("^%s/.*", projectId)
-}
-
-func CheckProjectUserInRole(username, projectId string, roles []string) error {
- if username == KS_ADMIN {
- return nil
- }
- dbconn, err := client.ClientSets().MySQL()
- if err != nil {
- if _, ok := err.(client.ClientSetNotEnabledError); ok {
- klog.Error("mysql is not enabled")
- } else {
- klog.Error("error creating mysql client", err)
- }
- return nil
- }
-
- membership := &DevOpsProjectMembership{}
- err = dbconn.Select(DevOpsProjectMembershipColumns...).
- From(DevOpsProjectMembershipTableName).
- Where(db.And(
- db.Eq(DevOpsProjectMembershipUsernameColumn, username),
- db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId))).LoadOne(membership)
- if err != nil {
- return err
- }
- if !reflectutils.In(membership.Role, roles) {
- return fmt.Errorf("user [%s] in project [%s] role is not in %s", username, projectId, roles)
- }
- return nil
-}
-
-func GetProjectUserRole(username, projectId string) (string, error) {
- if username == KS_ADMIN {
- return ProjectOwner, nil
- }
- dbconn, err := client.ClientSets().MySQL()
- if err != nil {
- if _, ok := err.(client.ClientSetNotEnabledError); ok {
- klog.Error("mysql is not enabled")
- } else {
- klog.Error("error creating mysql client", err)
- }
- return "", err
- }
- membership := &DevOpsProjectMembership{}
- err = dbconn.Select(DevOpsProjectMembershipColumns...).
- From(DevOpsProjectMembershipTableName).
- Where(db.And(
- db.Eq(DevOpsProjectMembershipUsernameColumn, username),
- db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId))).LoadOne(membership)
- if err != nil {
- return "", err
- }
-
- return membership.Role, nil
-}
diff --git a/pkg/models/devops/devops.go b/pkg/models/devops/devops.go
index 6b032ddac68215ebe3ce2b0dc51393259f9582b8..94298915b987416f1ff1efda969b2900658df9f5 100644
--- a/pkg/models/devops/devops.go
+++ b/pkg/models/devops/devops.go
@@ -19,182 +19,153 @@ package devops
import (
"bytes"
- "compress/gzip"
"encoding/json"
"fmt"
- "github.com/PuerkitoBio/goquery"
- "github.com/emicklei/go-restful"
"io"
"io/ioutil"
- "kubesphere.io/kubesphere/pkg/models"
-
"k8s.io/klog"
- cs "kubesphere.io/kubesphere/pkg/simple/client"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
"net/http"
- "net/url"
- "strings"
"sync"
- "time"
)
const (
channelMaxCapacity = 100
- cronJobLayout = "Monday, January 2, 2006 15:04:05 PM"
)
type DevopsOperator interface {
+ GetPipeline(projectName, pipelineName string, req *http.Request) (*devops.Pipeline, error)
+ ListPipelines(req *http.Request) (*devops.PipelineList, error)
+ GetPipelineRun(projectName, pipelineName, runId string, req *http.Request) (*devops.PipelineRun, error)
+ ListPipelineRuns(projectName, pipelineName string, req *http.Request) (*devops.PipelineRunList, error)
+ StopPipeline(projectName, pipelineName, runId string, req *http.Request) (*devops.StopPipeline, error)
+ ReplayPipeline(projectName, pipelineName, runId string, req *http.Request) (*devops.ReplayPipeline, error)
+ RunPipeline(projectName, pipelineName string, req *http.Request) (*devops.RunPipeline, error)
+ GetArtifacts(projectName, pipelineName, runId string, req *http.Request) ([]devops.Artifacts, error)
+ GetRunLog(projectName, pipelineName, runId string, req *http.Request) ([]byte, error)
+ GetStepLog(projectName, pipelineName, runId, nodeId, stepId string, req *http.Request) ([]byte, http.Header, error)
+ GetNodeSteps(projectName, pipelineName, runId, nodeId string, req *http.Request) ([]devops.NodeSteps, error)
+ GetPipelineRunNodes(projectName, pipelineName, runId string, req *http.Request) ([]devops.PipelineRunNodes, error)
+ SubmitInputStep(projectName, pipelineName, runId, nodeId, stepId string, req *http.Request) ([]byte, error)
+ GetNodesDetail(projectName, pipelineName, runId string, req *http.Request) ([]devops.NodesDetail, error)
+
+ GetBranchPipeline(projectName, pipelineName, branchName string, req *http.Request) (*devops.BranchPipeline, error)
+ GetBranchPipelineRun(projectName, pipelineName, branchName, runId string, req *http.Request) (*devops.PipelineRun, error)
+ StopBranchPipeline(projectName, pipelineName, branchName, runId string, req *http.Request) (*devops.StopPipeline, error)
+ ReplayBranchPipeline(projectName, pipelineName, branchName, runId string, req *http.Request) (*devops.ReplayPipeline, error)
+ RunBranchPipeline(projectName, pipelineName, branchName string, req *http.Request) (*devops.RunPipeline, error)
+ GetBranchArtifacts(projectName, pipelineName, branchName, runId string, req *http.Request) ([]devops.Artifacts, error)
+ GetBranchRunLog(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error)
+ GetBranchStepLog(projectName, pipelineName, branchName, runId, nodeId, stepId string, req *http.Request) ([]byte, http.Header, error)
+ GetBranchNodeSteps(projectName, pipelineName, branchName, runId, nodeId string, req *http.Request) ([]devops.NodeSteps, error)
+ GetBranchPipelineRunNodes(projectName, pipelineName, branchName, runId string, req *http.Request) ([]devops.BranchPipelineRunNodes, error)
+ SubmitBranchInputStep(projectName, pipelineName, branchName, runId, nodeId, stepId string, req *http.Request) ([]byte, error)
+ GetBranchNodesDetail(projectName, pipelineName, branchName, runId string, req *http.Request) ([]devops.NodesDetail, error)
+ GetPipelineBranch(projectName, pipelineName string, req *http.Request) (*devops.PipelineBranch, error)
+ ScanBranch(projectName, pipelineName string, req *http.Request) ([]byte, error)
+
+ GetConsoleLog(projectName, pipelineName string, req *http.Request) ([]byte, error)
+ GetCrumb(req *http.Request) (*devops.Crumb, error)
+
+ GetSCMServers(scmId string, req *http.Request) ([]devops.SCMServer, error)
+ GetSCMOrg(scmId string, req *http.Request) ([]devops.SCMOrg, error)
+ GetOrgRepo(scmId, organizationId string, req *http.Request) ([]devops.OrgRepo, error)
+ CreateSCMServers(scmId string, req *http.Request) (*devops.SCMServer, error)
+ Validate(scmId string, req *http.Request) (*devops.Validates, error)
+
+ GetNotifyCommit(req *http.Request) ([]byte, error)
+ GithubWebhook(req *http.Request) ([]byte, error)
+
+ CheckScriptCompile(projectName, pipelineName string, req *http.Request) (*devops.CheckScript, error)
+ CheckCron(projectName string, req *http.Request) (*devops.CheckCronRes, error)
+
+ ToJenkinsfile(req *http.Request) (*devops.ResJenkinsfile, error)
+ ToJson(req *http.Request) (*devops.ResJson, error)
}
type devopsOperator struct {
+ devopsClient devops.Interface
}
-func GetPipeline(projectName, pipelineName string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
+func NewDevopsOperator(client devops.Interface) DevopsOperator {
+ return &devopsOperator{devopsClient: client}
+}
+
+func convertToHttpParameters(req *http.Request) *devops.HttpParameters {
+ httpParameters := devops.HttpParameters{
+ Method: req.Method,
+ Header: req.Header,
+ Body: req.Body,
+ Form: req.Form,
+ PostForm: req.PostForm,
+ Url: req.URL,
}
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetPipelineUrl, projectName, pipelineName)
+ return &httpParameters
+}
+
+func (d devopsOperator) GetPipeline(projectName, pipelineName string, req *http.Request) (*devops.Pipeline, error) {
- res, err := sendJenkinsRequest(baseUrl, req)
+ res, err := d.devopsClient.GetPipeline(projectName, pipelineName, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
- return nil, err
}
-
return res, err
}
-func SearchPipelines(req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
+func (d devopsOperator) ListPipelines(req *http.Request) (*devops.PipelineList, error) {
- baseUrl := devops.Jenkins().Server + SearchPipelineUrl + req.URL.RawQuery
-
- res, err := sendJenkinsRequest(baseUrl, req)
- if err != nil {
- klog.Error(err)
- return nil, err
- }
- count, err := searchPipelineCount(req)
- if err != nil {
- klog.Error(err)
- return nil, err
- }
- responseStruct := models.PageableResponse{TotalCount: count}
- err = json.Unmarshal(res, &responseStruct.Items)
+ res, err := d.devopsClient.ListPipelines(convertToHttpParameters(req))
if err != nil {
klog.Error(err)
- return nil, err
- }
- res, err = json.Marshal(responseStruct)
- if err != nil {
- klog.Error(err)
- return nil, err
}
return res, err
}
-func searchPipelineCount(req *http.Request) (int, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return 0, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- query, _ := parseJenkinsQuery(req.URL.RawQuery)
- query.Set("start", "0")
- query.Set("limit", "1000")
- query.Set("depth", "-1")
-
- baseUrl := devops.Jenkins().Server + SearchPipelineUrl + query.Encode()
- klog.V(4).Info("Jenkins-url: " + baseUrl)
+func (d devopsOperator) GetPipelineRun(projectName, pipelineName, runId string, req *http.Request) (*devops.PipelineRun, error) {
- res, err := sendJenkinsRequest(baseUrl, req)
- if err != nil {
- klog.Error(err)
- return 0, err
- }
- var pipelines []Pipeline
- err = json.Unmarshal(res, &pipelines)
+ res, err := d.devopsClient.GetPipelineRun(projectName, pipelineName, runId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
- return 0, err
}
- return len(pipelines), nil
+ return res, err
}
-func searchPipelineRunsCount(projectName, pipelineName string, req *http.Request) (int, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return 0, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
- query, _ := parseJenkinsQuery(req.URL.RawQuery)
- query.Set("start", "0")
- query.Set("limit", "1000")
- query.Set("depth", "-1")
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+SearchPipelineRunUrl, projectName, pipelineName)
-
- klog.V(4).Info("Jenkins-url: " + baseUrl)
+func (d devopsOperator) ListPipelineRuns(projectName, pipelineName string, req *http.Request) (*devops.PipelineRunList, error) {
- res, err := sendJenkinsRequest(baseUrl+query.Encode(), req)
- if err != nil {
- klog.Error(err)
- return 0, err
- }
- var runs []PipelineRun
- err = json.Unmarshal(res, &runs)
+ res, err := d.devopsClient.ListPipelineRuns(projectName, pipelineName, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
- return 0, err
}
- return len(runs), nil
+ return res, err
}
-func SearchPipelineRuns(projectName, pipelineName string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+SearchPipelineRunUrl, projectName, pipelineName)
+func (d devopsOperator) StopPipeline(projectName, pipelineName, runId string, req *http.Request) (*devops.StopPipeline, error) {
- klog.V(4).Info("Jenkins-url: " + baseUrl)
-
- res, err := sendJenkinsRequest(baseUrl+req.URL.RawQuery, req)
- if err != nil {
- klog.Error(err)
- return nil, err
- }
- count, err := searchPipelineRunsCount(projectName, pipelineName, req)
- if err != nil {
- klog.Error(err)
- return nil, err
- }
- responseStruct := models.PageableResponse{TotalCount: count}
- err = json.Unmarshal(res, &responseStruct.Items)
+ req.Method = http.MethodPut
+ res, err := d.devopsClient.StopPipeline(projectName, pipelineName, runId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
}
- res, err = json.Marshal(responseStruct)
+
+ return res, err
+}
+
+func (d devopsOperator) ReplayPipeline(projectName, pipelineName, runId string, req *http.Request) (*devops.ReplayPipeline, error) {
+
+ res, err := d.devopsClient.ReplayPipeline(projectName, pipelineName, runId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
}
+
return res, err
}
-func GetBranchPipelineRun(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
+func (d devopsOperator) RunPipeline(projectName, pipelineName string, req *http.Request) (*devops.RunPipeline, error) {
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetPipeBranchRunUrl, projectName, pipelineName, branchName, runId)
-
- res, err := sendJenkinsRequest(baseUrl, req)
+ res, err := d.devopsClient.RunPipeline(projectName, pipelineName, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
@@ -203,16 +174,9 @@ func GetBranchPipelineRun(projectName, pipelineName, branchName, runId string, r
return res, err
}
-func GetPipelineRunNodesbyBranch(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetBranchPipeRunNodesUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
- klog.V(4).Info("Jenkins-url: " + baseUrl)
+func (d devopsOperator) GetArtifacts(projectName, pipelineName, runId string, req *http.Request) ([]devops.Artifacts, error) {
- res, err := sendJenkinsRequest(baseUrl, req)
+ res, err := d.devopsClient.GetArtifacts(projectName, pipelineName, runId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
@@ -221,32 +185,20 @@ func GetPipelineRunNodesbyBranch(projectName, pipelineName, branchName, runId st
return res, err
}
-func GetBranchStepLog(projectName, pipelineName, branchName, runId, nodeId, stepId string, req *http.Request) ([]byte, http.Header, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetBranchStepLogUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId, stepId)
+func (d devopsOperator) GetRunLog(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) {
- resBody, header, err := jenkinsClient(baseUrl, req)
+ res, err := d.devopsClient.GetRunLog(projectName, pipelineName, runId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
- return nil, nil, err
+ return nil, err
}
- return resBody, header, err
+ return res, err
}
-func GetStepLog(projectName, pipelineName, runId, nodeId, stepId string, req *http.Request) ([]byte, http.Header, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetStepLogUrl+req.URL.RawQuery, projectName, pipelineName, runId, nodeId, stepId)
+func (d devopsOperator) GetStepLog(projectName, pipelineName, runId, nodeId, stepId string, req *http.Request) ([]byte, http.Header, error) {
- resBody, header, err := jenkinsClient(baseUrl, req)
+ resBody, header, err := d.devopsClient.GetStepLog(projectName, pipelineName, runId, nodeId, stepId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, nil, err
@@ -255,110 +207,95 @@ func GetStepLog(projectName, pipelineName, runId, nodeId, stepId string, req *ht
return resBody, header, err
}
-func GetSCMServers(scmId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetSCMServersUrl, scmId)
- req.Method = http.MethodGet
- resBody, err := sendJenkinsRequest(baseUrl, req)
+func (d devopsOperator) GetNodeSteps(projectName, pipelineName, runId, nodeId string, req *http.Request) ([]devops.NodeSteps, error) {
+ res, err := d.devopsClient.GetNodeSteps(projectName, pipelineName, runId, nodeId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
}
- return resBody, err
+
+ return res, err
}
-func CreateSCMServers(scmId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
+func (d devopsOperator) GetPipelineRunNodes(projectName, pipelineName, runId string, req *http.Request) ([]devops.PipelineRunNodes, error) {
- requestBody, err := ioutil.ReadAll(req.Body)
+ res, err := d.devopsClient.GetPipelineRunNodes(projectName, pipelineName, runId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
}
- createReq := &CreateScmServerReq{}
- err = json.Unmarshal(requestBody, createReq)
+
+ fmt.Println()
+
+ return res, err
+}
+
+func (d devopsOperator) SubmitInputStep(projectName, pipelineName, runId, nodeId, stepId string, req *http.Request) ([]byte, error) {
+
+ newBody, err := getInputReqBody(req.Body)
if err != nil {
klog.Error(err)
return nil, err
}
- req.Body = nil
- byteServers, err := GetSCMServers(scmId, req)
+ req.Body = newBody
+
+ resBody, err := d.devopsClient.SubmitInputStep(projectName, pipelineName, runId, nodeId, stepId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
}
- var servers []*SCMServer
- _ = json.Unmarshal(byteServers, &servers)
- for _, server := range servers {
- if server.ApiURL == createReq.ApiURL {
- return json.Marshal(server)
- }
- }
- req.Body = ioutil.NopCloser(bytes.NewReader(requestBody))
+ return resBody, err
+}
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+CreateSCMServersUrl, scmId)
+func (d devopsOperator) GetNodesDetail(projectName, pipelineName, runId string, req *http.Request) ([]devops.NodesDetail, error) {
+ var wg sync.WaitGroup
+ var nodesDetails []devops.NodesDetail
+ stepChan := make(chan *devops.NodesStepsIndex, channelMaxCapacity)
- req.Method = http.MethodPost
- resBody, err := sendJenkinsRequest(baseUrl, req)
+ respNodes, err := d.GetPipelineRunNodes(projectName, pipelineName, runId, req)
if err != nil {
klog.Error(err)
return nil, err
}
- return resBody, err
-}
-func Validate(scmId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+ValidateUrl, scmId)
-
- req.Method = http.MethodPut
- resBody, err := sendJenkinsRequest(baseUrl, req)
+ Nodes, err := json.Marshal(respNodes)
+ err = json.Unmarshal(Nodes, &nodesDetails)
if err != nil {
klog.Error(err)
return nil, err
}
- return resBody, err
-}
+ // get all steps in nodes.
+ for i, v := range respNodes {
+ wg.Add(1)
+ go func(nodeId string, index int) {
+ Steps, err := d.GetNodeSteps(projectName, pipelineName, runId, nodeId, req)
+ if err != nil {
+ klog.Error(err)
+ return
+ }
-func GetSCMOrg(scmId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
+ stepChan <- &devops.NodesStepsIndex{Id: index, Steps: Steps}
+ wg.Done()
+ }(v.ID, i)
}
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetSCMOrgUrl+req.URL.RawQuery, scmId)
+ wg.Wait()
+ close(stepChan)
- res, err := sendJenkinsRequest(baseUrl, req)
- if err != nil {
- klog.Error(err)
- return nil, err
+ for oneNodeSteps := range stepChan {
+ if oneNodeSteps != nil {
+ nodesDetails[oneNodeSteps.Id].Steps = append(nodesDetails[oneNodeSteps.Id].Steps, oneNodeSteps.Steps...)
+ }
}
- return res, err
+ return nodesDetails, err
}
-func GetOrgRepo(scmId, organizationId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetOrgRepoUrl+req.URL.RawQuery, scmId, organizationId)
+func (d devopsOperator) GetBranchPipeline(projectName, pipelineName, branchName string, req *http.Request) (*devops.BranchPipeline, error) {
- res, err := sendJenkinsRequest(baseUrl, req)
+ res, err := d.devopsClient.GetBranchPipeline(projectName, pipelineName, branchName, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
@@ -367,16 +304,9 @@ func GetOrgRepo(scmId, organizationId string, req *http.Request) ([]byte, error)
return res, err
}
-func StopBranchPipeline(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+StopBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
+func (d devopsOperator) GetBranchPipelineRun(projectName, pipelineName, branchName, runId string, req *http.Request) (*devops.PipelineRun, error) {
- req.Method = http.MethodPut
- res, err := sendJenkinsRequest(baseUrl, req)
+ res, err := d.devopsClient.GetBranchPipelineRun(projectName, pipelineName, branchName, runId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
@@ -385,16 +315,10 @@ func StopBranchPipeline(projectName, pipelineName, branchName, runId string, req
return res, err
}
-func StopPipeline(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+StopPipelineUrl+req.URL.RawQuery, projectName, pipelineName, runId)
+func (d devopsOperator) StopBranchPipeline(projectName, pipelineName, branchName, runId string, req *http.Request) (*devops.StopPipeline, error) {
req.Method = http.MethodPut
- res, err := sendJenkinsRequest(baseUrl, req)
+ res, err := d.devopsClient.StopBranchPipeline(projectName, pipelineName, branchName, runId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
@@ -403,15 +327,9 @@ func StopPipeline(projectName, pipelineName, runId string, req *http.Request) ([
return res, err
}
-func ReplayBranchPipeline(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+ReplayBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
+func (d devopsOperator) ReplayBranchPipeline(projectName, pipelineName, branchName, runId string, req *http.Request) (*devops.ReplayPipeline, error) {
- res, err := sendJenkinsRequest(baseUrl, req)
+ res, err := d.devopsClient.ReplayBranchPipeline(projectName, pipelineName, branchName, runId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
@@ -420,15 +338,9 @@ func ReplayBranchPipeline(projectName, pipelineName, branchName, runId string, r
return res, err
}
-func ReplayPipeline(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
+func (d devopsOperator) RunBranchPipeline(projectName, pipelineName, branchName string, req *http.Request) (*devops.RunPipeline, error) {
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+ReplayPipelineUrl+req.URL.RawQuery, projectName, pipelineName, runId)
-
- res, err := sendJenkinsRequest(baseUrl, req)
+ res, err := d.devopsClient.RunBranchPipeline(projectName, pipelineName, branchName, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
@@ -437,15 +349,9 @@ func ReplayPipeline(projectName, pipelineName, runId string, req *http.Request)
return res, err
}
-func GetBranchRunLog(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetBranchRunLogUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
+func (d devopsOperator) GetBranchArtifacts(projectName, pipelineName, branchName, runId string, req *http.Request) ([]devops.Artifacts, error) {
- res, err := sendJenkinsRequest(baseUrl, req)
+ res, err := d.devopsClient.GetBranchArtifacts(projectName, pipelineName, branchName, runId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
@@ -454,15 +360,9 @@ func GetBranchRunLog(projectName, pipelineName, branchName, runId string, req *h
return res, err
}
-func GetRunLog(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetRunLogUrl+req.URL.RawQuery, projectName, pipelineName, runId)
+func (d devopsOperator) GetBranchRunLog(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) {
- res, err := sendJenkinsRequest(baseUrl, req)
+ res, err := d.devopsClient.GetBranchRunLog(projectName, pipelineName, branchName, runId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
@@ -471,32 +371,20 @@ func GetRunLog(projectName, pipelineName, runId string, req *http.Request) ([]by
return res, err
}
-func GetBranchArtifacts(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetBranchArtifactsUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
+func (d devopsOperator) GetBranchStepLog(projectName, pipelineName, branchName, runId, nodeId, stepId string, req *http.Request) ([]byte, http.Header, error) {
- res, err := sendJenkinsRequest(baseUrl, req)
+ resBody, header, err := d.devopsClient.GetBranchStepLog(projectName, pipelineName, branchName, runId, nodeId, stepId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
- return nil, err
+ return nil, nil, err
}
- return res, err
+ return resBody, header, err
}
-func GetArtifacts(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetArtifactsUrl+req.URL.RawQuery, projectName, pipelineName, runId)
+func (d devopsOperator) GetBranchNodeSteps(projectName, pipelineName, branchName, runId, nodeId string, req *http.Request) ([]devops.NodeSteps, error) {
- res, err := sendJenkinsRequest(baseUrl, req)
+ res, err := d.devopsClient.GetBranchNodeSteps(projectName, pipelineName, branchName, runId, nodeId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
@@ -505,15 +393,9 @@ func GetArtifacts(projectName, pipelineName, runId string, req *http.Request) ([
return res, err
}
-func GetPipeBranch(projectName, pipelineName string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
+func (d devopsOperator) GetBranchPipelineRunNodes(projectName, pipelineName, branchName, runId string, req *http.Request) ([]devops.BranchPipelineRunNodes, error) {
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetPipeBranchUrl, projectName, pipelineName)
-
- res, err := sendJenkinsRequest(baseUrl+req.URL.RawQuery, req)
+ res, err := d.devopsClient.GetBranchPipelineRunNodes(projectName, pipelineName, branchName, runId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
@@ -522,13 +404,7 @@ func GetPipeBranch(projectName, pipelineName string, req *http.Request) ([]byte,
return res, err
}
-func SubmitBranchInputStep(projectName, pipelineName, branchName, runId, nodeId, stepId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+CheckBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId, stepId)
+func (d devopsOperator) SubmitBranchInputStep(projectName, pipelineName, branchName, runId, nodeId, stepId string, req *http.Request) ([]byte, error) {
newBody, err := getInputReqBody(req.Body)
if err != nil {
@@ -536,7 +412,7 @@ func SubmitBranchInputStep(projectName, pipelineName, branchName, runId, nodeId,
return nil, err
}
req.Body = newBody
- resBody, err := sendJenkinsRequest(baseUrl, req)
+ resBody, err := d.devopsClient.SubmitBranchInputStep(projectName, pipelineName, branchName, runId, nodeId, stepId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
@@ -545,94 +421,65 @@ func SubmitBranchInputStep(projectName, pipelineName, branchName, runId, nodeId,
return resBody, err
}
-func SubmitInputStep(projectName, pipelineName, runId, nodeId, stepId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+CheckPipelineUrl+req.URL.RawQuery, projectName, pipelineName, runId, nodeId, stepId)
+func (d devopsOperator) GetBranchNodesDetail(projectName, pipelineName, branchName, runId string, req *http.Request) ([]devops.NodesDetail, error) {
+ var wg sync.WaitGroup
+ var nodesDetails []devops.NodesDetail
+ stepChan := make(chan *devops.NodesStepsIndex, channelMaxCapacity)
- newBody, err := getInputReqBody(req.Body)
+ respNodes, err := d.GetBranchPipelineRunNodes(projectName, pipelineName, branchName, runId, req)
if err != nil {
klog.Error(err)
return nil, err
}
- req.Body = newBody
- resBody, err := sendJenkinsRequest(baseUrl, req)
+ Nodes, err := json.Marshal(respNodes)
+ err = json.Unmarshal(Nodes, &nodesDetails)
if err != nil {
klog.Error(err)
return nil, err
}
- return resBody, err
-}
-
-func getInputReqBody(reqBody io.ReadCloser) (newReqBody io.ReadCloser, err error) {
- var checkBody CheckPlayload
- var jsonBody []byte
- var workRound struct {
- ID string `json:"id,omitempty" description:"id"`
- Parameters []CheckPlayloadParameters `json:"parameters"`
- Abort bool `json:"abort,omitempty" description:"abort or not"`
- }
+ // get all steps in nodes.
+ for i, v := range nodesDetails {
+ wg.Add(1)
+ go func(nodeId string, index int) {
+ Steps, err := d.GetBranchNodeSteps(projectName, pipelineName, branchName, runId, nodeId, req)
+ if err != nil {
+ klog.Error(err)
+ return
+ }
- Body, err := ioutil.ReadAll(reqBody)
- if err != nil {
- klog.Error(err)
- return nil, err
+ stepChan <- &devops.NodesStepsIndex{Id: index, Steps: Steps}
+ wg.Done()
+ }(v.ID, i)
}
- err = json.Unmarshal(Body, &checkBody)
+ wg.Wait()
+ close(stepChan)
- if checkBody.Abort != true && checkBody.Parameters == nil {
- workRound.Parameters = []CheckPlayloadParameters{}
- workRound.ID = checkBody.ID
- jsonBody, _ = json.Marshal(workRound)
- } else {
- jsonBody, _ = json.Marshal(checkBody)
+ for oneNodeSteps := range stepChan {
+ if oneNodeSteps != nil {
+ nodesDetails[oneNodeSteps.Id].Steps = append(nodesDetails[oneNodeSteps.Id].Steps, oneNodeSteps.Steps...)
+ }
}
- newReqBody = parseBody(bytes.NewBuffer(jsonBody))
-
- return newReqBody, nil
-
-}
-
-func parseBody(body io.Reader) (newReqBody io.ReadCloser) {
- rc, ok := body.(io.ReadCloser)
- if !ok && body != nil {
- rc = ioutil.NopCloser(body)
- }
- return rc
+ return nodesDetails, err
}
-func GetConsoleLog(projectName, pipelineName string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetConsoleLogUrl+req.URL.RawQuery, projectName, pipelineName)
+func (d devopsOperator) GetPipelineBranch(projectName, pipelineName string, req *http.Request) (*devops.PipelineBranch, error) {
- resBody, err := sendJenkinsRequest(baseUrl, req)
+ res, err := d.devopsClient.GetPipelineBranch(projectName, pipelineName, convertToHttpParameters(req))
+ //baseUrl+req.URL.RawQuery, req)
if err != nil {
klog.Error(err)
return nil, err
}
- return resBody, err
+ return res, err
}
-func ScanBranch(projectName, pipelineName string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+ScanBranchUrl+req.URL.RawQuery, projectName, pipelineName)
+func (d devopsOperator) ScanBranch(projectName, pipelineName string, req *http.Request) ([]byte, error) {
- resBody, err := sendJenkinsRequest(baseUrl, req)
+ resBody, err := d.devopsClient.ScanBranch(projectName, pipelineName, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
@@ -641,31 +488,20 @@ func ScanBranch(projectName, pipelineName string, req *http.Request) ([]byte, er
return resBody, err
}
-func RunBranchPipeline(projectName, pipelineName, branchName string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
+func (d devopsOperator) GetConsoleLog(projectName, pipelineName string, req *http.Request) ([]byte, error) {
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+RunBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName)
-
- res, err := sendJenkinsRequest(baseUrl, req)
+ resBody, err := d.devopsClient.GetConsoleLog(projectName, pipelineName, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
}
- return res, err
+ return resBody, err
}
-func RunPipeline(projectName, pipelineName string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+RunPipelineUrl+req.URL.RawQuery, projectName, pipelineName)
+func (d devopsOperator) GetCrumb(req *http.Request) (*devops.Crumb, error) {
- res, err := sendJenkinsRequest(baseUrl, req)
+ res, err := d.devopsClient.GetCrumb(convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
@@ -674,202 +510,91 @@ func RunPipeline(projectName, pipelineName string, req *http.Request) ([]byte, e
return res, err
}
-func GetCrumb(req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server + GetCrumbUrl)
-
- res, err := sendJenkinsRequest(baseUrl, req)
- if err != nil {
- klog.Error(err)
- return nil, err
- }
-
- return res, err
-}
+func (d devopsOperator) GetSCMServers(scmId string, req *http.Request) ([]devops.SCMServer, error) {
-func CheckScriptCompile(projectName, pipelineName string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+CheckScriptCompileUrl, projectName, pipelineName)
-
- resBody, err := sendJenkinsRequest(baseUrl, req)
+ req.Method = http.MethodGet
+ resBody, err := d.devopsClient.GetSCMServers(scmId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
- return nil, err
}
-
return resBody, err
}
-func CheckCron(projectName string, req *http.Request) (*CheckCronRes, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- jenkins := devops.Jenkins()
-
- var res = new(CheckCronRes)
- var cron = new(CronData)
- var reader io.ReadCloser
- var baseUrl string
-
- reader = req.Body
- cronData, err := ioutil.ReadAll(reader)
- json.Unmarshal(cronData, cron)
-
- if cron.PipelineName != "" {
- baseUrl = fmt.Sprintf(jenkins.Server+CheckPipelienCronUrl, projectName, cron.PipelineName, cron.Cron)
- } else {
- baseUrl = fmt.Sprintf(jenkins.Server+CheckCronUrl, projectName, cron.Cron)
- }
+func (d devopsOperator) GetSCMOrg(scmId string, req *http.Request) ([]devops.SCMOrg, error) {
- newUrl, err := url.Parse(baseUrl)
+ res, err := d.devopsClient.GetSCMOrg(scmId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
}
- newUrl.RawQuery = newUrl.Query().Encode()
- reqJenkins := &http.Request{
- Method: http.MethodGet,
- URL: newUrl,
- Header: req.Header,
- }
-
- client := &http.Client{Timeout: 30 * time.Second}
-
- resp, err := client.Do(reqJenkins)
+ return res, err
+}
- if resp != nil && resp.StatusCode != http.StatusOK {
- resBody, _ := getRespBody(resp)
- return &CheckCronRes{
- Result: "error",
- Message: string(resBody),
- }, err
- }
- if err != nil {
- klog.Error(err)
- return nil, err
- }
- defer resp.Body.Close()
+func (d devopsOperator) GetOrgRepo(scmId, organizationId string, req *http.Request) ([]devops.OrgRepo, error) {
- doc, err := goquery.NewDocumentFromReader(resp.Body)
+ res, err := d.devopsClient.GetOrgRepo(scmId, organizationId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
}
- doc.Find("div").Each(func(i int, selection *goquery.Selection) {
- res.Message = selection.Text()
- res.Result, _ = selection.Attr("class")
- })
- if res.Result == "ok" {
- res.LastTime, res.NextTime, err = parseCronJobTime(res.Message)
- if err != nil {
- klog.Error(err)
- return nil, err
- }
- }
return res, err
}
-func parseCronJobTime(msg string) (string, string, error) {
-
- times := strings.Split(msg, ";")
+func (d devopsOperator) CreateSCMServers(scmId string, req *http.Request) (*devops.SCMServer, error) {
- lastTmp := strings.Split(times[0], " ")
- lastCount := len(lastTmp)
- lastTmp = lastTmp[lastCount-7 : lastCount-1]
- lastTime := strings.Join(lastTmp, " ")
- lastUinx, err := time.Parse(cronJobLayout, lastTime)
+ requestBody, err := ioutil.ReadAll(req.Body)
if err != nil {
klog.Error(err)
- return "", "", err
+ return nil, err
}
- last := lastUinx.Format(time.RFC3339)
-
- nextTmp := strings.Split(times[1], " ")
- nextCount := len(nextTmp)
- nextTmp = nextTmp[nextCount-7 : nextCount-1]
- nextTime := strings.Join(nextTmp, " ")
- nextUinx, err := time.Parse(cronJobLayout, nextTime)
+ createReq := &devops.CreateScmServerReq{}
+ err = json.Unmarshal(requestBody, createReq)
if err != nil {
klog.Error(err)
- return "", "", err
- }
- next := nextUinx.Format(time.RFC3339)
-
- return last, next, nil
-}
-
-func GetPipelineRun(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
+ return nil, err
}
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetPipelineRunUrl, projectName, pipelineName, runId)
-
- res, err := sendJenkinsRequest(baseUrl, req)
+ req.Body = nil
+ servers, err := d.GetSCMServers(scmId, req)
if err != nil {
klog.Error(err)
return nil, err
}
- return res, err
-}
-
-func GetBranchPipeline(projectName, pipelineName, branchName string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
+ for _, server := range servers {
+ if server.ApiURL == createReq.ApiURL {
+ return &server, nil
+ }
}
+ req.Body = ioutil.NopCloser(bytes.NewReader(requestBody))
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetBranchPipeUrl, projectName, pipelineName, branchName)
-
- res, err := sendJenkinsRequest(baseUrl, req)
+ req.Method = http.MethodPost
+ resBody, err := d.devopsClient.CreateSCMServers(scmId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
}
-
- return res, err
+ return resBody, err
}
-func GetPipelineRunNodes(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetPipeRunNodesUrl+req.URL.RawQuery, projectName, pipelineName, runId)
+func (d devopsOperator) Validate(scmId string, req *http.Request) (*devops.Validates, error) {
- res, err := sendJenkinsRequest(baseUrl, req)
+ req.Method = http.MethodPut
+ resBody, err := d.devopsClient.Validate(scmId, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
}
- return res, err
+ return resBody, err
}
-func GetBranchNodeSteps(projectName, pipelineName, branchName, runId, nodeId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
+func (d devopsOperator) GetNotifyCommit(req *http.Request) ([]byte, error) {
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetBranchNodeStepsUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId)
+ req.Method = http.MethodGet
- res, err := sendJenkinsRequest(baseUrl, req)
+ res, err := d.devopsClient.GetNotifyCommit(convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
@@ -878,15 +603,9 @@ func GetBranchNodeSteps(projectName, pipelineName, branchName, runId, nodeId str
return res, err
}
-func GetNodeSteps(projectName, pipelineName, runId, nodeId string, req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetNodeStepsUrl+req.URL.RawQuery, projectName, pipelineName, runId, nodeId)
+func (d devopsOperator) GithubWebhook(req *http.Request) ([]byte, error) {
- res, err := sendJenkinsRequest(baseUrl, req)
+ res, err := d.devopsClient.GithubWebhook(convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
@@ -895,32 +614,21 @@ func GetNodeSteps(projectName, pipelineName, runId, nodeId string, req *http.Req
return res, err
}
-func ToJenkinsfile(req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
+func (d devopsOperator) CheckScriptCompile(projectName, pipelineName string, req *http.Request) (*devops.CheckScript, error) {
- baseUrl := fmt.Sprintf(devops.Jenkins().Server + ToJenkinsfileUrl)
-
- res, err := sendJenkinsRequest(baseUrl, req)
+ resBody, err := d.devopsClient.CheckScriptCompile(projectName, pipelineName, convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
}
- return res, err
+ return resBody, err
}
-func ToJson(req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
+func (d devopsOperator) CheckCron(projectName string, req *http.Request) (*devops.CheckCronRes, error) {
- baseUrl := fmt.Sprintf(devops.Jenkins().Server + ToJsonUrl)
+ res, err := d.devopsClient.CheckCron(projectName, convertToHttpParameters(req))
- res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
klog.Error(err)
return nil, err
@@ -929,16 +637,9 @@ func ToJson(req *http.Request) ([]byte, error) {
return res, err
}
-func GetNotifyCommit(req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
+func (d devopsOperator) ToJenkinsfile(req *http.Request) (*devops.ResJenkinsfile, error) {
- baseUrl := fmt.Sprint(devops.Jenkins().Server, GetNotifyCommitUrl, req.URL.RawQuery)
- req.Method = "GET"
-
- res, err := sendJenkinsRequest(baseUrl, req)
+ res, err := d.devopsClient.ToJenkinsfile(convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
@@ -947,15 +648,9 @@ func GetNotifyCommit(req *http.Request) ([]byte, error) {
return res, err
}
-func GithubWebhook(req *http.Request) ([]byte, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- baseUrl := fmt.Sprint(devops.Jenkins().Server, GithubWebhookUrl, req.URL.RawQuery)
+func (d devopsOperator) ToJson(req *http.Request) (*devops.ResJson, error) {
- res, err := sendJenkinsRequest(baseUrl, req)
+ res, err := d.devopsClient.ToJson(convertToHttpParameters(req))
if err != nil {
klog.Error(err)
return nil, err
@@ -964,192 +659,41 @@ func GithubWebhook(req *http.Request) ([]byte, error) {
return res, err
}
-func GetBranchNodesDetail(projectName, pipelineName, branchName, runId string, req *http.Request) ([]NodesDetail, error) {
- var wg sync.WaitGroup
- var nodesDetails []NodesDetail
- stepChan := make(chan *NodesStepsIndex, channelMaxCapacity)
-
- respNodes, err := GetPipelineRunNodesbyBranch(projectName, pipelineName, branchName, runId, req)
- if err != nil {
- klog.Error(err)
- return nil, err
- }
- err = json.Unmarshal(respNodes, &nodesDetails)
- if err != nil {
- klog.Error(err)
- return nil, err
- }
-
- // get all steps in nodes.
- for i, v := range nodesDetails {
- wg.Add(1)
- go func(nodeId string, index int) {
- var steps []NodeSteps
- respSteps, err := GetBranchNodeSteps(projectName, pipelineName, branchName, runId, nodeId, req)
- if err != nil {
- klog.Error(err)
- return
- }
- err = json.Unmarshal(respSteps, &steps)
-
- stepChan <- &NodesStepsIndex{index, steps}
- wg.Done()
- }(v.ID, i)
- }
-
- wg.Wait()
- close(stepChan)
-
- for oneNodeSteps := range stepChan {
- if oneNodeSteps != nil {
- nodesDetails[oneNodeSteps.Id].Steps = append(nodesDetails[oneNodeSteps.Id].Steps, oneNodeSteps.Steps...)
- }
+func getInputReqBody(reqBody io.ReadCloser) (newReqBody io.ReadCloser, err error) {
+ var checkBody devops.CheckPlayload
+ var jsonBody []byte
+ var workRound struct {
+ ID string `json:"id,omitempty" description:"id"`
+ Parameters []devops.CheckPlayloadParameters `json:"parameters"`
+ Abort bool `json:"abort,omitempty" description:"abort or not"`
}
- return nodesDetails, err
-}
-
-func GetNodesDetail(projectName, pipelineName, runId string, req *http.Request) ([]NodesDetail, error) {
- var wg sync.WaitGroup
- var nodesDetails []NodesDetail
- stepChan := make(chan *NodesStepsIndex, channelMaxCapacity)
-
- respNodes, err := GetPipelineRunNodes(projectName, pipelineName, runId, req)
- if err != nil {
- klog.Error(err)
- return nil, err
- }
- err = json.Unmarshal(respNodes, &nodesDetails)
+ Body, err := ioutil.ReadAll(reqBody)
if err != nil {
klog.Error(err)
return nil, err
}
- // get all steps in nodes.
- for i, v := range nodesDetails {
- wg.Add(1)
- go func(nodeId string, index int) {
- var steps []NodeSteps
- respSteps, err := GetNodeSteps(projectName, pipelineName, runId, nodeId, req)
- if err != nil {
- klog.Error(err)
- return
- }
- err = json.Unmarshal(respSteps, &steps)
-
- stepChan <- &NodesStepsIndex{index, steps}
- wg.Done()
- }(v.ID, i)
- }
-
- wg.Wait()
- close(stepChan)
-
- for oneNodeSteps := range stepChan {
- if oneNodeSteps != nil {
- nodesDetails[oneNodeSteps.Id].Steps = append(nodesDetails[oneNodeSteps.Id].Steps, oneNodeSteps.Steps...)
- }
- }
-
- return nodesDetails, err
-}
-
-// create jenkins request
-func sendJenkinsRequest(baseUrl string, req *http.Request) ([]byte, error) {
- resBody, _, err := jenkinsClient(baseUrl, req)
- return resBody, err
-}
-
-func jenkinsClient(baseUrl string, req *http.Request) ([]byte, http.Header, error) {
- newReqUrl, err := url.Parse(baseUrl)
- if err != nil {
- klog.Error(err)
- return nil, nil, err
- }
-
- client := &http.Client{Timeout: 30 * time.Second}
-
- newRequest := &http.Request{
- Method: req.Method,
- URL: newReqUrl,
- Header: req.Header,
- Body: req.Body,
- Form: req.Form,
- PostForm: req.PostForm,
- }
-
- resp, err := client.Do(newRequest)
- if err != nil {
- klog.Error(err)
- return nil, nil, err
- }
-
- resBody, _ := getRespBody(resp)
- defer resp.Body.Close()
+ err = json.Unmarshal(Body, &checkBody)
- if resp.StatusCode >= http.StatusBadRequest {
- klog.Errorf("%+v", string(resBody))
- jkerr := new(JkError)
- jkerr.Code = resp.StatusCode
- jkerr.Message = string(resBody)
- return nil, nil, jkerr
+ if checkBody.Abort != true && checkBody.Parameters == nil {
+ workRound.Parameters = []devops.CheckPlayloadParameters{}
+ workRound.ID = checkBody.ID
+ jsonBody, _ = json.Marshal(workRound)
+ } else {
+ jsonBody, _ = json.Marshal(checkBody)
}
- return resBody, resp.Header, nil
-
-}
+ newReqBody = parseBody(bytes.NewBuffer(jsonBody))
-// Decompress response.body of JenkinsAPIResponse
-func getRespBody(resp *http.Response) ([]byte, error) {
- var reader io.ReadCloser
- if resp.Header.Get("Content-Encoding") == "gzip" {
- reader, _ = gzip.NewReader(resp.Body)
- } else {
- reader = resp.Body
- }
- resBody, err := ioutil.ReadAll(reader)
- if err != nil {
- klog.Error(err)
- return nil, err
- }
- return resBody, err
+ return newReqBody, nil
}
-// parseJenkinsQuery Parse the special query of jenkins.
-// ParseQuery in the standard library makes the query not re-encode
-func parseJenkinsQuery(query string) (url.Values, error) {
- m := make(url.Values)
- err := error(nil)
- for query != "" {
- key := query
- if i := strings.IndexAny(key, "&"); i >= 0 {
- key, query = key[:i], key[i+1:]
- } else {
- query = ""
- }
- if key == "" {
- continue
- }
- value := ""
- if i := strings.Index(key, "="); i >= 0 {
- key, value = key[:i], key[i+1:]
- }
- key, err1 := url.QueryUnescape(key)
- if err1 != nil {
- if err == nil {
- err = err1
- }
- continue
- }
- value, err1 = url.QueryUnescape(value)
- if err1 != nil {
- if err == nil {
- err = err1
- }
- continue
- }
- m[key] = append(m[key], value)
+func parseBody(body io.Reader) (newReqBody io.ReadCloser) {
+ rc, ok := body.(io.ReadCloser)
+ if !ok && body != nil {
+ rc = ioutil.NopCloser(body)
}
- return m, err
+ return rc
}
diff --git a/pkg/models/devops/devops_test.go b/pkg/models/devops/devops_test.go
index 3749d604173f02e570a2d39b90332840c25270a1..4d82e5b4112d453d3da4078165210b3f1af88124 100644
--- a/pkg/models/devops/devops_test.go
+++ b/pkg/models/devops/devops_test.go
@@ -1,40 +1,113 @@
package devops
import (
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops/fake"
+ "net/http"
"testing"
)
-func Test_parseCronJobTime(t *testing.T) {
- type Except struct {
- Last string
- Next string
+const baseUrl = "http://127.0.0.1/kapis/devops.kubesphere.io/v1alpha2/"
+
+func TestGetNodesDetail(t *testing.T) {
+ fakeData := make(map[string]interface{})
+ PipelineRunNodes := []devops.PipelineRunNodes{
+ {
+ DisplayName: "Deploy to Kubernetes",
+ ID: "1",
+ Result: "SUCCESS",
+ },
+ {
+ DisplayName: "Deploy to Kubernetes",
+ ID: "2",
+ Result: "SUCCESS",
+ },
+ {
+ DisplayName: "Deploy to Kubernetes",
+ ID: "3",
+ Result: "SUCCESS",
+ },
}
- Items := []struct {
- Input string
- Expected Except
- }{
- {"上次运行的时间 Tuesday, September 10, 2019 8:59:09 AM UTC; 下次运行的时间 Tuesday, September 10, 2019 9:14:09 AM UTC.", Except{Last: "2019-09-10T08:59:09Z", Next: "2019-09-10T09:14:09Z"}},
- {"上次运行的时间 Thursday, January 3, 2019 11:56:30 PM UTC; 下次运行的时间 Friday, January 3, 2020 12:11:30 AM UTC.", Except{Last: "2019-01-03T23:56:30Z", Next: "2020-01-03T00:11:30Z"}},
- {"上次运行的时间 Tuesday, September 10, 2019 8:41:34 AM UTC; 下次运行的时间 Tuesday, September 10, 2019 9:41:34 AM UTC.", Except{Last: "2019-09-10T08:41:34Z", Next: "2019-09-10T09:41:34Z"}},
- {"上次运行的时间 Tuesday, September 10, 2019 9:15:26 AM UTC; 下次运行的时间 Tuesday, September 10, 2019 10:03:26 AM UTC.", Except{Last: "2019-09-10T09:15:26Z", Next: "2019-09-10T10:03:26Z"}},
- {"Would last have run at Tuesday, September 10, 2019 9:15:26 AM UTC; would next run at Tuesday, September 10, 2019 10:03:26 AM UTC.", Except{Last: "2019-09-10T09:15:26Z", Next: "2019-09-10T10:03:26Z"}},
- {"Would last have run at Tuesday, September 10, 2019 8:41:34 AM UTC; would next run at Tuesday, September 10, 2019 9:41:34 AM UTC.", Except{Last: "2019-09-10T08:41:34Z", Next: "2019-09-10T09:41:34Z"}},
+ NodeSteps := []devops.NodeSteps{
+ {
+ DisplayName: "Deploy to Kubernetes",
+ ID: "1",
+ Result: "SUCCESS",
+ },
}
- for _, item := range Items {
- last, next, err := parseCronJobTime(item.Input)
- if err != nil {
- t.Fatalf("should not get error %+v", err)
- }
+ fakeData["project1-pipeline1-run1"] = PipelineRunNodes
+ fakeData["project1-pipeline1-run1-1"] = NodeSteps
+ fakeData["project1-pipeline1-run1-2"] = NodeSteps
+ fakeData["project1-pipeline1-run1-3"] = NodeSteps
- if last != item.Expected.Last {
- t.Errorf("got %#v, expected %#v", last, item.Expected.Last)
- }
+ devopsClient := fake.NewFakeDevops(fakeData)
- if next != item.Expected.Next {
- t.Errorf("got %#v, expected %#v", next, item.Expected.Next)
+ devopsOperator := NewDevopsOperator(devopsClient)
+
+ httpReq, _ := http.NewRequest(http.MethodGet, baseUrl+"devops/project1/pipelines/pipeline1/runs/run1/nodesdetail/?limit=10000", nil)
+
+ nodesDetails, err := devopsOperator.GetNodesDetail("project1", "pipeline1", "run1", httpReq)
+ if err != nil || nodesDetails == nil {
+ t.Fatalf("should not get error %+v", err)
+ }
+
+ for _, v := range nodesDetails {
+ if v.Steps[0].ID == "" {
+ t.Fatalf("Can not get any step.")
}
+ }
+}
+func TestGetBranchNodesDetail(t *testing.T) {
+ fakeData := make(map[string]interface{})
+
+ BranchPipelineRunNodes := []devops.BranchPipelineRunNodes{
+ {
+ DisplayName: "Deploy to Kubernetes",
+ ID: "1",
+ Result: "SUCCESS",
+ },
+ {
+ DisplayName: "Deploy to Kubernetes",
+ ID: "2",
+ Result: "SUCCESS",
+ },
+ {
+ DisplayName: "Deploy to Kubernetes",
+ ID: "3",
+ Result: "SUCCESS",
+ },
+ }
+
+ BranchNodeSteps := []devops.NodeSteps{
+ {
+ DisplayName: "Deploy to Kubernetes",
+ ID: "1",
+ Result: "SUCCESS",
+ },
+ }
+
+ fakeData["project1-pipeline1-branch1-run1"] = BranchPipelineRunNodes
+ fakeData["project1-pipeline1-branch1-run1-1"] = BranchNodeSteps
+ fakeData["project1-pipeline1-branch1-run1-2"] = BranchNodeSteps
+ fakeData["project1-pipeline1-branch1-run1-3"] = BranchNodeSteps
+
+ devopsClient := fake.NewFakeDevops(fakeData)
+
+ devopsOperator := NewDevopsOperator(devopsClient)
+
+ httpReq, _ := http.NewRequest(http.MethodGet, baseUrl+"devops/project1/pipelines/pipeline1/branchs/branch1/runs/run1/nodesdetail/?limit=10000", nil)
+
+ nodesDetails, err := devopsOperator.GetBranchNodesDetail("project1", "pipeline1", "branch1", "run1", httpReq)
+ if err != nil || nodesDetails == nil {
+ t.Fatalf("should not get error %+v", err)
+ }
+
+ for _, v := range nodesDetails {
+ if v.Steps[0].ID == "" {
+ t.Fatalf("Can not get any step.")
+ }
}
}
diff --git a/pkg/models/devops/membership.go b/pkg/models/devops/membership.go
index 57cf46284955d2a68588dc3932a8161e17d3e009..0d4336e25f6676a3ff4c92b4d83b94a2d4dd2327 100644
--- a/pkg/models/devops/membership.go
+++ b/pkg/models/devops/membership.go
@@ -13,25 +13,19 @@ limitations under the License.
package devops
+import "kubesphere.io/kubesphere/pkg/simple/client/devops"
+
const (
- DevOpsProjectMembershipTableName = "project_membership"
- DevOpsProjectMembershipUsernameColumn = "project_membership.username"
- DevOpsProjectMembershipProjectIdColumn = "project_membership.project_id"
- DevOpsProjectMembershipRoleColumn = "project_membership.role"
+ ProjectMembershipTableName = "project_membership"
+ ProjectMembershipUsernameColumn = "project_membership.username"
+ ProjectMembershipProjectIdColumn = "project_membership.project_id"
+ ProjectMembershipRoleColumn = "project_membership.role"
)
-type DevOpsProjectMembership struct {
- Username string `json:"username" description:"Member's username,username can uniquely identify a user"`
- ProjectId string `json:"project_id" db:"project_id" description:"the DevOps Projects which project membership belongs to"`
- Role string `json:"role" description:"DevOps Project membership's role type. e.g. owner '"`
- Status string `json:"status" description:"Deprecated, Status of project membership. e.g. active "`
- GrantBy string `json:"grand_by,omitempty" description:"Username of the user who assigned the role"`
-}
-
-var DevOpsProjectMembershipColumns = GetColumnsFromStruct(&DevOpsProjectMembership{})
+var ProjectMembershipColumns = GetColumnsFromStruct(&devops.ProjectMembership{})
-func NewDevOpsProjectMemberShip(username, projectId, role, grantBy string) *DevOpsProjectMembership {
- return &DevOpsProjectMembership{
+func NewDevOpsProjectMemberShip(username, projectId, role, grantBy string) *devops.ProjectMembership {
+ return &devops.ProjectMembership{
Username: username,
ProjectId: projectId,
Role: role,
diff --git a/pkg/models/devops/project_credential.go b/pkg/models/devops/project_credential.go
index 7f64a13dde2bc341c68cdbded612a801f0e0489b..9fc22870e509e387e2ab6c21cac80ba25f2bf697 100644
--- a/pkg/models/devops/project_credential.go
+++ b/pkg/models/devops/project_credential.go
@@ -18,59 +18,6 @@ import (
"time"
)
-const (
- CredentialTypeUsernamePassword = "username_password"
- CredentialTypeSsh = "ssh"
- CredentialTypeSecretText = "secret_text"
- CredentialTypeKubeConfig = "kubeconfig"
-)
-
-type JenkinsCredential struct {
- Id string `json:"id" description:"Id of Credential, e.g. dockerhub-id"`
- Type string `json:"type" description:"Type of Credential, e.g. ssh/kubeconfig"`
- DisplayName string `json:"display_name,omitempty" description:"Credential's display name"`
- Fingerprint *struct {
- FileName string `json:"file_name,omitempty" description:"Credential's display name and description"`
- Hash string `json:"hash,omitempty" description:"Credential's hash"`
- Usage []*struct {
- Name string `json:"name,omitempty" description:"Jenkins pipeline full name"`
- Ranges struct {
- Ranges []*struct {
- Start int `json:"start,omitempty" description:"Start build number"`
- End int `json:"end,omitempty" description:"End build number"`
- } `json:"ranges,omitempty"`
- } `json:"ranges,omitempty" description:"The build number of all pipelines that use this credential"`
- } `json:"usage,omitempty" description:"all usage of Credential"`
- } `json:"fingerprint,omitempty" description:"usage of the Credential"`
- Description string `json:"description,omitempty" description:"Credential's description'"`
- Domain string `json:"domain,omitempty" description:"Credential's domain,In ks we only use the default domain, default '_''"`
- CreateTime *time.Time `json:"create_time,omitempty" description:"Credential's create_time'"`
- Creator string `json:"creator,omitempty" description:"Creator's username"`
- UsernamePasswordCredential *UsernamePasswordCredential `json:"username_password,omitempty" description:"username password Credential struct"`
- SshCredential *SshCredential `json:"ssh,omitempty" description:"ssh Credential struct"`
- SecretTextCredential *SecretTextCredential `json:"secret_text,omitempty" description:"secret_text Credential struct"`
- KubeconfigCredential *KubeconfigCredential `json:"kubeconfig,omitempty" description:"kubeconfig Credential struct"`
-}
-
-type UsernamePasswordCredential struct {
- Username string `json:"username,omitempty" description:"username of username_password credential"`
- Password string `json:"password,omitempty" description:"password of username_password credential"`
-}
-
-type SshCredential struct {
- Username string `json:"username,omitempty" description:"username of ssh credential"`
- Passphrase string `json:"passphrase,omitempty" description:"passphrase of ssh credential, password of ssh credential"`
- PrivateKey string `json:"private_key,omitempty" mapstructure:"private_key" description:"private key of ssh credential"`
-}
-
-type SecretTextCredential struct {
- Secret string `json:"secret,omitempty" description:"secret content of credential"`
-}
-
-type KubeconfigCredential struct {
- Content string `json:"content,omitempty" description:"content of kubeconfig"`
-}
-
const (
ProjectCredentialTableName = "project_credential"
ProjectCredentialIdColumn = "credential_id"
@@ -78,13 +25,6 @@ const (
ProjectCredentialProjectIdColumn = "project_id"
)
-var CredentialTypeMap = map[string]string{
- "SSH Username with private key": CredentialTypeSsh,
- "Username with password": CredentialTypeUsernamePassword,
- "Secret text": CredentialTypeSecretText,
- "Kubernetes configuration (kubeconfig)": CredentialTypeKubeConfig,
-}
-
type ProjectCredential struct {
ProjectId string `json:"project_id"`
CredentialId string `json:"credential_id"`
diff --git a/pkg/models/devops/project_credential_handler.go b/pkg/models/devops/project_credential_handler.go
index de0e0f8efeb17ab0ef3c94913de97e78026e1926..5640b3fec3a1da7b1fd9c5079185249fb8be9ce6 100644
--- a/pkg/models/devops/project_credential_handler.go
+++ b/pkg/models/devops/project_credential_handler.go
@@ -15,389 +15,209 @@ package devops
import (
"fmt"
- "github.com/PuerkitoBio/goquery"
- "github.com/asaskevich/govalidator"
"github.com/emicklei/go-restful"
"github.com/gocraft/dbr"
"k8s.io/klog"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "kubesphere.io/kubesphere/pkg/simple/client/mysql"
"kubesphere.io/kubesphere/pkg/db"
- "kubesphere.io/kubesphere/pkg/gojenkins"
- "kubesphere.io/kubesphere/pkg/gojenkins/utils"
- cs "kubesphere.io/kubesphere/pkg/simple/client"
"net/http"
- "strings"
)
-func CreateProjectCredential(projectId, username string, credentialRequest *JenkinsCredential) (string, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
+type ProjectCredentialOperator interface {
+ CreateProjectCredential(projectId, username string, credentialRequest *devops.Credential) (string, error)
+ UpdateProjectCredential(projectId, credentialId string, credentialRequest *devops.Credential) (string, error)
+ DeleteProjectCredential(projectId, credentialId string) (string, error)
+ GetProjectCredential(projectId, credentialId, getContent string) (*devops.Credential, error)
+ GetProjectCredentials(projectId string) ([]*devops.Credential, error)
+}
- jenkinsClient := devops.Jenkins()
+type projectCredentialOperator struct {
+ devopsClient devops.Interface
+ db *mysql.Database
+}
- err = checkJenkinsCredentialExists(projectId, credentialRequest.Domain, credentialRequest.Id)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", err
- }
+func NewProjectCredentialOperator(devopsClient devops.Interface, dbClient *mysql.Database) ProjectCredentialOperator {
+ return &projectCredentialOperator{devopsClient: devopsClient, db: dbClient}
+}
+func (o *projectCredentialOperator) CreateProjectCredential(projectId, username string, credentialRequest *devops.Credential) (string, error) {
switch credentialRequest.Type {
- case CredentialTypeUsernamePassword:
+ case devops.CredentialTypeUsernamePassword:
if credentialRequest.UsernamePasswordCredential == nil {
err := fmt.Errorf("usename_password should not be nil")
klog.Error(err)
return "", restful.NewError(http.StatusBadRequest, err.Error())
}
- credentialId, err := jenkinsClient.CreateUsernamePasswordCredentialInFolder(credentialRequest.Domain,
- credentialRequest.Id,
- credentialRequest.UsernamePasswordCredential.Username,
- credentialRequest.UsernamePasswordCredential.Password,
- credentialRequest.Description,
- projectId)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- err = insertCredentialToDb(projectId, *credentialId, credentialRequest.Domain, username)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", err
- }
- return *credentialId, nil
- case CredentialTypeSsh:
+ case devops.CredentialTypeSsh:
if credentialRequest.SshCredential == nil {
err := fmt.Errorf("ssh should not be nil")
klog.Error(err)
return "", restful.NewError(http.StatusBadRequest, err.Error())
}
- credentialId, err := jenkinsClient.CreateSshCredentialInFolder(credentialRequest.Domain,
- credentialRequest.Id,
- credentialRequest.SshCredential.Username,
- credentialRequest.SshCredential.Passphrase,
- credentialRequest.SshCredential.PrivateKey,
- credentialRequest.Description,
- projectId)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- err = insertCredentialToDb(projectId, *credentialId, credentialRequest.Domain, username)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(http.StatusInternalServerError, err.Error())
- }
- return *credentialId, nil
- case CredentialTypeSecretText:
+ case devops.CredentialTypeSecretText:
if credentialRequest.SecretTextCredential == nil {
err := fmt.Errorf("secret_text should not be nil")
klog.Error(err)
return "", restful.NewError(http.StatusBadRequest, err.Error())
}
-
- credentialId, err := jenkinsClient.CreateSecretTextCredentialInFolder(credentialRequest.Domain,
- credentialRequest.Id,
- credentialRequest.SecretTextCredential.Secret,
- credentialRequest.Description,
- projectId)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- err = insertCredentialToDb(projectId, *credentialId, credentialRequest.Domain, username)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(http.StatusInternalServerError, err.Error())
- }
- return *credentialId, nil
- case CredentialTypeKubeConfig:
+ case devops.CredentialTypeKubeConfig:
if credentialRequest.KubeconfigCredential == nil {
err := fmt.Errorf("kubeconfig should not be nil")
klog.Error(err)
return "", restful.NewError(http.StatusBadRequest, err.Error())
}
- credentialId, err := jenkinsClient.CreateKubeconfigCredentialInFolder(credentialRequest.Domain,
- credentialRequest.Id,
- credentialRequest.KubeconfigCredential.Content,
- credentialRequest.Description,
- projectId)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- err = insertCredentialToDb(projectId, *credentialId, credentialRequest.Domain, username)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(http.StatusInternalServerError, err.Error())
- }
- return *credentialId, nil
default:
err := fmt.Errorf("error unsupport credential type")
klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusBadRequest, err.Error())
}
+ credentialId, err := o.devopsClient.CreateCredentialInProject(projectId, credentialRequest)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ return "", err
+ }
+ err = o.insertCredentialToDb(projectId, *credentialId, credentialRequest.Domain, username)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ return "", err
+ }
+ return *credentialId, nil
}
-func UpdateProjectCredential(projectId, credentialId string, credentialRequest *JenkinsCredential) (string, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
- jenkinsClient := devops.Jenkins()
+func (o *projectCredentialOperator) UpdateProjectCredential(projectId, credentialId string, credentialRequest *devops.Credential) (string, error) {
- jenkinsCredential, err := jenkinsClient.GetCredentialInFolder(credentialRequest.Domain,
- credentialId,
- projectId)
+ credential, err := o.devopsClient.GetCredentialInProject(projectId,
+ credentialId, false)
if err != nil {
klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
+ return "", err
}
- credentialType := CredentialTypeMap[jenkinsCredential.TypeName]
- switch credentialType {
- case CredentialTypeUsernamePassword:
+ switch credential.Type {
+ case devops.CredentialTypeUsernamePassword:
if credentialRequest.UsernamePasswordCredential == nil {
err := fmt.Errorf("usename_password should not be nil")
klog.Error(err)
return "", restful.NewError(http.StatusBadRequest, err.Error())
}
- credentialId, err := jenkinsClient.UpdateUsernamePasswordCredentialInFolder(credentialRequest.Domain,
- credentialId,
- credentialRequest.UsernamePasswordCredential.Username,
- credentialRequest.UsernamePasswordCredential.Password,
- credentialRequest.Description,
- projectId)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- return *credentialId, nil
- case CredentialTypeSsh:
+ case devops.CredentialTypeSsh:
if credentialRequest.SshCredential == nil {
err := fmt.Errorf("ssh should not be nil")
klog.Error(err)
return "", restful.NewError(http.StatusBadRequest, err.Error())
}
- credentialId, err := jenkinsClient.UpdateSshCredentialInFolder(credentialRequest.Domain,
- credentialId,
- credentialRequest.SshCredential.Username,
- credentialRequest.SshCredential.Passphrase,
- credentialRequest.SshCredential.PrivateKey,
- credentialRequest.Description,
- projectId)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- return *credentialId, nil
- case CredentialTypeSecretText:
+ case devops.CredentialTypeSecretText:
if credentialRequest.SecretTextCredential == nil {
err := fmt.Errorf("secret_text should not be nil")
klog.Error(err)
return "", restful.NewError(http.StatusBadRequest, err.Error())
}
- credentialId, err := jenkinsClient.UpdateSecretTextCredentialInFolder(credentialRequest.Domain,
- credentialId,
- credentialRequest.SecretTextCredential.Secret,
- credentialRequest.Description,
- projectId)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- return *credentialId, nil
- case CredentialTypeKubeConfig:
+ case devops.CredentialTypeKubeConfig:
if credentialRequest.KubeconfigCredential == nil {
err := fmt.Errorf("kubeconfig should not be nil")
klog.Error(err)
return "", restful.NewError(http.StatusBadRequest, err.Error())
}
- credentialId, err := jenkinsClient.UpdateKubeconfigCredentialInFolder(credentialRequest.Domain,
- credentialId,
- credentialRequest.KubeconfigCredential.Content,
- credentialRequest.Description,
- projectId)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- return *credentialId, nil
default:
err := fmt.Errorf("error unsupport credential type")
klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusBadRequest, err.Error())
-
}
-
-}
-
-func DeleteProjectCredential(projectId, credentialId string, credentialRequest *JenkinsCredential) (string, error) {
- devops, err := cs.ClientSets().Devops()
+ credentialRequest.Id = credentialId
+ _, err = o.devopsClient.UpdateCredentialInProject(projectId, credentialRequest)
if err != nil {
- return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
+ klog.Errorf("%+v", err)
+ return "", restful.NewError(http.StatusBadRequest, err.Error())
}
- jenkinsClient := devops.Jenkins()
+ return credentialId, nil
- dbClient, err := cs.ClientSets().MySQL()
- if err != nil {
- return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
+}
- _, err = jenkinsClient.GetCredentialInFolder(credentialRequest.Domain,
- credentialId,
- projectId)
+func (o *projectCredentialOperator) DeleteProjectCredential(projectId, credentialId string) (string, error) {
+
+ _, err := o.devopsClient.GetCredentialInProject(projectId,
+ credentialId, false)
if err != nil {
klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
+ return "", err
}
- id, err := jenkinsClient.DeleteCredentialInFolder(credentialRequest.Domain, credentialId, projectId)
+ id, err := o.devopsClient.DeleteCredentialInProject(projectId, credentialId)
if err != nil {
klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
+ return "", err
}
deleteConditions := append(make([]dbr.Builder, 0), db.Eq(ProjectCredentialProjectIdColumn, projectId))
deleteConditions = append(deleteConditions, db.Eq(ProjectCredentialIdColumn, credentialId))
- if !govalidator.IsNull(credentialRequest.Domain) {
- deleteConditions = append(deleteConditions, db.Eq(ProjectCredentialDomainColumn, credentialRequest.Domain))
- } else {
- deleteConditions = append(deleteConditions, db.Eq(ProjectCredentialDomainColumn, "_"))
- }
+ deleteConditions = append(deleteConditions, db.Eq(ProjectCredentialDomainColumn, "_"))
- _, err = dbClient.DeleteFrom(ProjectCredentialTableName).
+ _, err = o.db.DeleteFrom(ProjectCredentialTableName).
Where(db.And(deleteConditions...)).Exec()
if err != nil && err != db.ErrNotFound {
klog.Errorf("%+v", err)
- return "", restful.NewError(http.StatusInternalServerError, err.Error())
+ return "", err
}
return *id, nil
}
-func GetProjectCredential(projectId, credentialId, domain, getContent string) (*JenkinsCredential, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
- jenkinsClient := devops.Jenkins()
+func (o *projectCredentialOperator) GetProjectCredential(projectId, credentialId, getContent string) (*devops.Credential, error) {
- dbClient, err := cs.ClientSets().MySQL()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
+ content := false
+ if getContent != "" {
+ content = true
}
- jenkinsResponse, err := jenkinsClient.GetCredentialInFolder(domain,
+ credential, err := o.devopsClient.GetCredentialInProject(projectId,
credentialId,
- projectId)
+ content)
if err != nil {
klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
+ return nil, err
}
-
projectCredential := &ProjectCredential{}
- err = dbClient.Select(ProjectCredentialColumns...).
+ err = o.db.Select(ProjectCredentialColumns...).
From(ProjectCredentialTableName).Where(
db.And(db.Eq(ProjectCredentialProjectIdColumn, projectId),
db.Eq(ProjectCredentialIdColumn, credentialId),
- db.Eq(ProjectCredentialDomainColumn, jenkinsResponse.Domain))).LoadOne(projectCredential)
+ db.Eq(ProjectCredentialDomainColumn, credential.Domain))).LoadOne(projectCredential)
if err != nil && err != db.ErrNotFound {
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
}
- response := formatCredentialResponse(jenkinsResponse, projectCredential)
- if getContent != "" {
- stringBody, err := jenkinsClient.GetCredentialContentInFolder(jenkinsResponse.Domain, credentialId, projectId)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- stringReader := strings.NewReader(stringBody)
- doc, err := goquery.NewDocumentFromReader(stringReader)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(http.StatusInternalServerError, err.Error())
- }
- switch response.Type {
- case CredentialTypeKubeConfig:
- content := &KubeconfigCredential{}
- doc.Find("textarea[name*=content]").Each(func(i int, selection *goquery.Selection) {
- value := selection.Text()
- content.Content = value
- })
- response.KubeconfigCredential = content
- case CredentialTypeUsernamePassword:
- content := &UsernamePasswordCredential{}
- doc.Find("input[name*=username]").Each(func(i int, selection *goquery.Selection) {
- value, _ := selection.Attr("value")
- content.Username = value
- })
-
- response.UsernamePasswordCredential = content
- case CredentialTypeSsh:
- content := &SshCredential{}
- doc.Find("input[name*=username]").Each(func(i int, selection *goquery.Selection) {
- value, _ := selection.Attr("value")
- content.Username = value
- })
-
- doc.Find("textarea[name*=privateKey]").Each(func(i int, selection *goquery.Selection) {
- value := selection.Text()
- content.PrivateKey = value
- })
- response.SshCredential = content
- }
- }
+ response := formatCredentialResponse(credential, projectCredential)
return response, nil
}
-func GetProjectCredentials(projectId, domain string) ([]*JenkinsCredential, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
- jenkinsClient := devops.Jenkins()
+func (o *projectCredentialOperator) GetProjectCredentials(projectId string) ([]*devops.Credential, error) {
- dbClient, err := cs.ClientSets().MySQL()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
- jenkinsCredentialResponses, err := jenkinsClient.GetCredentialsInFolder(domain, projectId)
+ credentialResponses, err := o.devopsClient.GetCredentialsInProject(projectId)
if err != nil {
klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
+ return nil, err
}
selectCondition := db.Eq(ProjectCredentialProjectIdColumn, projectId)
- if !govalidator.IsNull(domain) {
- selectCondition = db.And(selectCondition, db.Eq(ProjectCredentialDomainColumn, domain))
- }
projectCredentials := make([]*ProjectCredential, 0)
- _, err = dbClient.Select(ProjectCredentialColumns...).
+ _, err = o.db.Select(ProjectCredentialColumns...).
From(ProjectCredentialTableName).Where(selectCondition).Load(&projectCredentials)
if err != nil {
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
}
- response := formatCredentialsResponse(jenkinsCredentialResponses, projectCredentials)
+ response := formatCredentialsResponse(credentialResponses, projectCredentials)
return response, nil
}
-func insertCredentialToDb(projectId, credentialId, domain, username string) error {
- dbClient, err := cs.ClientSets().MySQL()
- if err != nil {
- return err
- }
+func (o *projectCredentialOperator) insertCredentialToDb(projectId, credentialId, domain, username string) error {
projectCredential := NewProjectCredential(projectId, credentialId, domain, username)
- _, err = dbClient.InsertInto(ProjectCredentialTableName).Columns(ProjectCredentialColumns...).
+ _, err := o.db.InsertInto(ProjectCredentialTableName).Columns(ProjectCredentialColumns...).
Record(projectCredential).Exec()
if err != nil {
klog.Errorf("%+v", err)
@@ -406,41 +226,19 @@ func insertCredentialToDb(projectId, credentialId, domain, username string) erro
return nil
}
-func checkJenkinsCredentialExists(projectId, domain, credentialId string) error {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- jenkinsClient := devops.Jenkins()
-
- credential, err := jenkinsClient.GetCredentialInFolder(domain, credentialId, projectId)
- if credential != nil {
- err := fmt.Errorf("credential id [%s] has been used", credential.Id)
- klog.Warning(err.Error())
- return restful.NewError(http.StatusConflict, err.Error())
- }
- if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound {
- klog.Errorf("%+v", err)
-
- return restful.NewError(http.StatusBadRequest, err.Error())
- }
- return nil
-}
-
func formatCredentialResponse(
- jenkinsCredentialResponse *gojenkins.CredentialResponse,
- dbCredentialResponse *ProjectCredential) *JenkinsCredential {
- response := &JenkinsCredential{}
- response.Id = jenkinsCredentialResponse.Id
- response.Description = jenkinsCredentialResponse.Description
- response.DisplayName = jenkinsCredentialResponse.DisplayName
- if jenkinsCredentialResponse.Fingerprint != nil && jenkinsCredentialResponse.Fingerprint.Hash != "" {
+ credentialResponse *devops.Credential,
+ dbCredentialResponse *ProjectCredential) *devops.Credential {
+ response := &devops.Credential{}
+ response.Id = credentialResponse.Id
+ response.Description = credentialResponse.Description
+ response.DisplayName = credentialResponse.DisplayName
+ if credentialResponse.Fingerprint != nil && credentialResponse.Fingerprint.Hash != "" {
response.Fingerprint = &struct {
FileName string `json:"file_name,omitempty" description:"Credential's display name and description"`
Hash string `json:"hash,omitempty" description:"Credential's hash"`
Usage []*struct {
- Name string `json:"name,omitempty" description:"Jenkins pipeline full name"`
+ Name string `json:"name,omitempty" description:"pipeline full name"`
Ranges struct {
Ranges []*struct {
Start int `json:"start,omitempty" description:"Start build number"`
@@ -449,40 +247,40 @@ func formatCredentialResponse(
} `json:"ranges,omitempty" description:"The build number of all pipelines that use this credential"`
} `json:"usage,omitempty" description:"all usage of Credential"`
}{}
- response.Fingerprint.FileName = jenkinsCredentialResponse.Fingerprint.FileName
- response.Fingerprint.Hash = jenkinsCredentialResponse.Fingerprint.Hash
- for _, usage := range jenkinsCredentialResponse.Fingerprint.Usage {
+ response.Fingerprint.FileName = credentialResponse.Fingerprint.FileName
+ response.Fingerprint.Hash = credentialResponse.Fingerprint.Hash
+ for _, usage := range credentialResponse.Fingerprint.Usage {
response.Fingerprint.Usage = append(response.Fingerprint.Usage, usage)
}
}
- response.Domain = jenkinsCredentialResponse.Domain
+ response.Domain = credentialResponse.Domain
if dbCredentialResponse != nil {
response.CreateTime = &dbCredentialResponse.CreateTime
response.Creator = dbCredentialResponse.Creator
}
- credentialType, ok := CredentialTypeMap[jenkinsCredentialResponse.TypeName]
+ credentialType, ok := devops.CredentialTypeMap[credentialResponse.Type]
if ok {
response.Type = credentialType
return response
}
- response.Type = jenkinsCredentialResponse.TypeName
+ response.Type = credentialResponse.Type
return response
}
-func formatCredentialsResponse(jenkinsCredentialsResponse []*gojenkins.CredentialResponse,
- projectCredentials []*ProjectCredential) []*JenkinsCredential {
- responseSlice := make([]*JenkinsCredential, 0)
- for _, jenkinsCredential := range jenkinsCredentialsResponse {
+func formatCredentialsResponse(credentialsResponse []*devops.Credential,
+ projectCredentials []*ProjectCredential) []*devops.Credential {
+ responseSlice := make([]*devops.Credential, 0)
+ for _, credential := range credentialsResponse {
var dbCredential *ProjectCredential = nil
for _, projectCredential := range projectCredentials {
- if projectCredential.CredentialId == jenkinsCredential.Id &&
- projectCredential.Domain == jenkinsCredential.Domain {
+ if projectCredential.CredentialId == credential.Id &&
+ projectCredential.Domain == credential.Domain {
dbCredential = projectCredential
}
}
- responseSlice = append(responseSlice, formatCredentialResponse(jenkinsCredential, dbCredential))
+ responseSlice = append(responseSlice, formatCredentialResponse(credential, dbCredential))
}
return responseSlice
}
diff --git a/pkg/models/devops/project_handler.go b/pkg/models/devops/project_handler.go
index 49537baf09b3f925450a7f0bb55f75b1b7583bd5..76a2546029d30c52a8ea0818f9c2056f45cffb0e 100644
--- a/pkg/models/devops/project_handler.go
+++ b/pkg/models/devops/project_handler.go
@@ -14,23 +14,37 @@ limitations under the License.
package devops
import (
+ "fmt"
"github.com/asaskevich/govalidator"
"github.com/emicklei/go-restful"
"github.com/gocraft/dbr"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/api/devops/v1alpha2"
"kubesphere.io/kubesphere/pkg/db"
- cs "kubesphere.io/kubesphere/pkg/simple/client"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "kubesphere.io/kubesphere/pkg/simple/client/mysql"
+ "kubesphere.io/kubesphere/pkg/utils/reflectutils"
"net/http"
)
-func GetProject(projectId string) (*v1alpha2.DevOpsProject, error) {
- dbconn, err := cs.ClientSets().MySQL()
- if err != nil {
- return nil, err
- }
+type ProjectOperator interface {
+ GetProject(projectId string) (*v1alpha2.DevOpsProject, error)
+ UpdateProject(project *v1alpha2.DevOpsProject) (*v1alpha2.DevOpsProject, error)
+ CheckProjectUserInRole(username, projectId string, roles []string) error
+}
+
+type projectOperator struct {
+ db *mysql.Database
+}
+
+func NewProjectOperator(dbClient *mysql.Database) ProjectOperator {
+ return &projectOperator{db: dbClient}
+}
+
+func (o *projectOperator) GetProject(projectId string) (*v1alpha2.DevOpsProject, error) {
+
project := &v1alpha2.DevOpsProject{}
- err = dbconn.Select(DevOpsProjectColumns...).
+ err := o.db.Select(DevOpsProjectColumns...).
From(DevOpsProjectTableName).
Where(db.Eq(DevOpsProjectIdColumn, projectId)).
LoadOne(project)
@@ -46,13 +60,9 @@ func GetProject(projectId string) (*v1alpha2.DevOpsProject, error) {
return project, nil
}
-func UpdateProject(project *v1alpha2.DevOpsProject) (*v1alpha2.DevOpsProject, error) {
- dbconn, err := cs.ClientSets().MySQL()
- if err != nil {
- return nil, err
- }
+func (o *projectOperator) UpdateProject(project *v1alpha2.DevOpsProject) (*v1alpha2.DevOpsProject, error) {
- query := dbconn.Update(DevOpsProjectTableName)
+ query := o.db.Update(DevOpsProjectTableName)
if !govalidator.IsNull(project.Description) {
query.Set(DevOpsProjectDescriptionColumn, project.Description)
}
@@ -73,7 +83,7 @@ func UpdateProject(project *v1alpha2.DevOpsProject) (*v1alpha2.DevOpsProject, er
}
}
newProject := &v1alpha2.DevOpsProject{}
- err = dbconn.Select(DevOpsProjectColumns...).
+ err := o.db.Select(DevOpsProjectColumns...).
From(DevOpsProjectTableName).
Where(db.Eq(DevOpsProjectIdColumn, project.ProjectId)).
LoadOne(newProject)
@@ -83,3 +93,22 @@ func UpdateProject(project *v1alpha2.DevOpsProject) (*v1alpha2.DevOpsProject, er
}
return newProject, nil
}
+
+func (o *projectOperator) CheckProjectUserInRole(username, projectId string, roles []string) error {
+ if username == KS_ADMIN {
+ return nil
+ }
+ membership := &devops.ProjectMembership{}
+ err := o.db.Select(ProjectMembershipColumns...).
+ From(ProjectMembershipTableName).
+ Where(db.And(
+ db.Eq(ProjectMembershipUsernameColumn, username),
+ db.Eq(ProjectMembershipProjectIdColumn, projectId))).LoadOne(membership)
+ if err != nil {
+ return err
+ }
+ if !reflectutils.In(membership.Role, roles) {
+ return fmt.Errorf("user [%s] in project [%s] role is not in %s", username, projectId, roles)
+ }
+ return nil
+}
diff --git a/pkg/models/devops/project_member_handler.go b/pkg/models/devops/project_member_handler.go
index 856f1d0a8d424301aa9fdb1dba88297e5fa7d6b4..3702c034fcf8989c0884802564d0862833a5840f 100644
--- a/pkg/models/devops/project_member_handler.go
+++ b/pkg/models/devops/project_member_handler.go
@@ -15,43 +15,58 @@ package devops
import (
"fmt"
"k8s.io/klog"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "kubesphere.io/kubesphere/pkg/simple/client/mysql"
"net/http"
"github.com/emicklei/go-restful"
"github.com/gocraft/dbr"
"kubesphere.io/kubesphere/pkg/db"
- "kubesphere.io/kubesphere/pkg/gojenkins"
- "kubesphere.io/kubesphere/pkg/gojenkins/utils"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/server/params"
- cs "kubesphere.io/kubesphere/pkg/simple/client"
)
-func GetProjectMembers(projectId string, conditions *params.Conditions, orderBy string, reverse bool, limit int, offset int) (*models.PageableResponse, error) {
- dbconn, err := cs.ClientSets().MySQL()
- if err != nil {
- return nil, err
+type ProjectMemberOperator interface {
+ GetProjectMembers(projectId string, conditions *params.Conditions, orderBy string, reverse bool, limit int, offset int) (*models.PageableResponse, error)
+ GetProjectMember(projectId, username string) (*devops.ProjectMembership, error)
+ AddProjectMember(projectId string, membership *devops.ProjectMembership) (*devops.ProjectMembership, error)
+ UpdateProjectMember(projectId string, membership *devops.ProjectMembership) (*devops.ProjectMembership, error)
+ DeleteProjectMember(projectId, username string) (string, error)
+}
+type projectMemberOperator struct {
+ db *mysql.Database
+ projectMemberOperator devops.ProjectMemberOperator
+}
+
+func NewProjectMemberOperator(devopsClient devops.ProjectMemberOperator, dbClient *mysql.Database) ProjectMemberOperator {
+ return &projectMemberOperator{
+ db: dbClient,
+ projectMemberOperator: devopsClient,
}
- memberships := make([]*DevOpsProjectMembership, 0)
+}
+
+func (o *projectMemberOperator) GetProjectMembers(projectId string, conditions *params.Conditions, orderBy string, reverse bool, limit int, offset int) (*models.PageableResponse, error) {
+
+ memberships := make([]*devops.ProjectMembership, 0)
var sqconditions []dbr.Builder
- sqconditions = append(sqconditions, db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId))
+ sqconditions = append(sqconditions, db.Eq(ProjectMembershipProjectIdColumn, projectId))
if keyword := conditions.Match["keyword"]; keyword != "" {
- sqconditions = append(sqconditions, db.Like(DevOpsProjectMembershipUsernameColumn, keyword))
+ sqconditions = append(sqconditions, db.Like(ProjectMembershipUsernameColumn, keyword))
}
- query := dbconn.Select(DevOpsProjectMembershipColumns...).
- From(DevOpsProjectMembershipTableName)
+ query := *o.db.Select(ProjectMembershipColumns...).
+ From(ProjectMembershipTableName)
switch orderBy {
case "name":
if reverse {
- query.OrderDesc(DevOpsProjectMembershipUsernameColumn)
+ query.OrderDesc(ProjectMembershipUsernameColumn)
} else {
- query.OrderAsc(DevOpsProjectMembershipUsernameColumn)
+ query.OrderAsc(ProjectMembershipUsernameColumn)
}
default:
if reverse {
- query.OrderDesc(DevOpsProjectMembershipRoleColumn)
+ query.OrderDesc(ProjectMembershipRoleColumn)
} else {
- query.OrderAsc(DevOpsProjectMembershipRoleColumn)
+ query.OrderAsc(ProjectMembershipRoleColumn)
}
}
query.Limit(uint64(limit))
@@ -61,7 +76,7 @@ func GetProjectMembers(projectId string, conditions *params.Conditions, orderBy
} else {
query.Where(sqconditions[0])
}
- _, err = query.Load(&memberships)
+ _, err := query.Load(&memberships)
if err != nil && err != dbr.ErrNotFound {
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
@@ -79,17 +94,13 @@ func GetProjectMembers(projectId string, conditions *params.Conditions, orderBy
return &models.PageableResponse{Items: result, TotalCount: int(count)}, nil
}
-func GetProjectMember(projectId, username string) (*DevOpsProjectMembership, error) {
- dbconn, err := cs.ClientSets().MySQL()
- if err != nil {
- return nil, err
- }
+func (o *projectMemberOperator) GetProjectMember(projectId, username string) (*devops.ProjectMembership, error) {
- member := &DevOpsProjectMembership{}
- err = dbconn.Select(DevOpsProjectMembershipColumns...).
- From(DevOpsProjectMembershipTableName).
- Where(db.And(db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
- db.Eq(DevOpsProjectMembershipUsernameColumn, username))).
+ member := &devops.ProjectMembership{}
+ err := o.db.Select(ProjectMembershipColumns...).
+ From(ProjectMembershipTableName).
+ Where(db.And(db.Eq(ProjectMembershipProjectIdColumn, projectId),
+ db.Eq(ProjectMembershipUsernameColumn, username))).
LoadOne(&member)
if err != nil && err != dbr.ErrNotFound {
klog.Errorf("%+v", err)
@@ -102,31 +113,17 @@ func GetProjectMember(projectId, username string) (*DevOpsProjectMembership, err
return member, nil
}
-func AddProjectMember(projectId, operator string, member *DevOpsProjectMembership) (*DevOpsProjectMembership, error) {
- dbconn, err := cs.ClientSets().MySQL()
- if err != nil {
- return nil, err
- }
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, err
- }
- jenkinsClient := devops.Jenkins()
- if jenkinsClient == nil {
- err := fmt.Errorf("could not connect to jenkins")
- klog.Error(err)
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
+func (o *projectMemberOperator) AddProjectMember(projectId string, membership *devops.ProjectMembership) (*devops.ProjectMembership, error) {
- membership := &DevOpsProjectMembership{}
- err = dbconn.Select(DevOpsProjectMembershipColumns...).
- From(DevOpsProjectMembershipTableName).
+ dbmembership := &devops.ProjectMembership{}
+ err := o.db.Select(ProjectMembershipColumns...).
+ From(ProjectMembershipTableName).
Where(db.And(
- db.Eq(DevOpsProjectMembershipUsernameColumn, member.Username),
- db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId))).LoadOne(membership)
+ db.Eq(ProjectMembershipUsernameColumn, membership.Username),
+ db.Eq(ProjectMembershipProjectIdColumn, projectId))).LoadOne(dbmembership)
// if user could be founded in db, user have been added to project
if err == nil {
- err = fmt.Errorf("user [%s] have been added to project", member.Username)
+ err = fmt.Errorf("user [%s] have been added to project", membership.Username)
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusBadRequest, err.Error())
}
@@ -136,161 +133,65 @@ func AddProjectMember(projectId, operator string, member *DevOpsProjectMembershi
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
}
- globalRole, err := jenkinsClient.GetGlobalRole(JenkinsAllUserRoleName)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- if globalRole == nil {
- _, err := jenkinsClient.AddGlobalRole(JenkinsAllUserRoleName, gojenkins.GlobalPermissionIds{
- GlobalRead: true,
- }, true)
- if err != nil {
- klog.Errorf("failed to create jenkins global role %+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- }
- err = globalRole.AssignRole(member.Username)
+ _, err = o.projectMemberOperator.AddProjectMember(membership)
if err != nil {
klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- projectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, member.Role))
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- err = projectRole.AssignRole(member.Username)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- pipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, member.Role))
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- err = pipelineRole.AssignRole(member.Username)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
+ return nil, err
}
- projectMembership := NewDevOpsProjectMemberShip(member.Username, projectId, member.Role, operator)
- _, err = dbconn.
- InsertInto(DevOpsProjectMembershipTableName).
- Columns(DevOpsProjectMembershipColumns...).
+ projectMembership := NewDevOpsProjectMemberShip(membership.Username, projectId, membership.Role, membership.GrantBy)
+ _, err = o.db.
+ InsertInto(ProjectMembershipTableName).
+ Columns(ProjectMembershipColumns...).
Record(projectMembership).Exec()
if err != nil {
klog.Errorf("%+v", err)
- err = projectRole.UnAssignRole(member.Username)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- err = pipelineRole.UnAssignRole(member.Username)
+ _, err = o.projectMemberOperator.DeleteProjectMember(membership)
if err != nil {
klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
+ return nil, err
}
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
}
return projectMembership, nil
}
-func UpdateProjectMember(projectId, operator string, member *DevOpsProjectMembership) (*DevOpsProjectMembership, error) {
- dbconn, err := cs.ClientSets().MySQL()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, err
- }
-
- jenkinsClient := devops.Jenkins()
- if jenkinsClient == nil {
- err := fmt.Errorf("could not connect to jenkins")
- klog.Error(err)
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
+func (o *projectMemberOperator) UpdateProjectMember(projectId string, membership *devops.ProjectMembership) (*devops.ProjectMembership, error) {
- oldMembership := &DevOpsProjectMembership{}
- err = dbconn.Select(DevOpsProjectMembershipColumns...).
- From(DevOpsProjectMembershipTableName).
+ oldMembership := &devops.ProjectMembership{}
+ err := o.db.Select(ProjectMembershipColumns...).
+ From(ProjectMembershipTableName).
Where(db.And(
- db.Eq(DevOpsProjectMembershipUsernameColumn, member.Username),
- db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
+ db.Eq(ProjectMembershipUsernameColumn, membership.Username),
+ db.Eq(ProjectMembershipProjectIdColumn, projectId),
)).LoadOne(oldMembership)
if err != nil {
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusBadRequest, err.Error())
}
- oldProjectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, oldMembership.Role))
+ _, err = o.projectMemberOperator.UpdateProjectMember(oldMembership, membership)
if err != nil {
klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- err = oldProjectRole.UnAssignRole(member.Username)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- oldPipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, oldMembership.Role))
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- err = oldPipelineRole.UnAssignRole(member.Username)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- projectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, member.Role))
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- err = projectRole.AssignRole(member.Username)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- pipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, member.Role))
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- err = pipelineRole.AssignRole(member.Username)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
+ return nil, err
}
-
- _, err = dbconn.Update(DevOpsProjectMembershipTableName).
- Set(DevOpsProjectMembershipRoleColumn, member.Role).
+ _, err = o.db.Update(ProjectMembershipTableName).
+ Set(ProjectMembershipRoleColumn, membership.Role).
Where(db.And(
- db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
- db.Eq(DevOpsProjectMembershipUsernameColumn, member.Username),
+ db.Eq(ProjectMembershipProjectIdColumn, projectId),
+ db.Eq(ProjectMembershipUsernameColumn, membership.Username),
)).Exec()
+
if err != nil {
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
}
- responseMembership := &DevOpsProjectMembership{}
- err = dbconn.Select(DevOpsProjectMembershipColumns...).
- From(DevOpsProjectMembershipTableName).
+ responseMembership := &devops.ProjectMembership{}
+ err = o.db.Select(ProjectMembershipColumns...).
+ From(ProjectMembershipTableName).
Where(db.And(
- db.Eq(DevOpsProjectMembershipUsernameColumn, member.Username),
- db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
+ db.Eq(ProjectMembershipUsernameColumn, membership.Username),
+ db.Eq(ProjectMembershipProjectIdColumn, projectId),
)).LoadOne(responseMembership)
if err != nil {
klog.Errorf("%+v", err)
@@ -299,25 +200,14 @@ func UpdateProjectMember(projectId, operator string, member *DevOpsProjectMember
return responseMembership, nil
}
-func DeleteProjectMember(projectId, username string) (string, error) {
- dbconn, err := cs.ClientSets().MySQL()
- if err != nil {
- return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- jenkinsClient := devops.Jenkins()
+func (o *projectMemberOperator) DeleteProjectMember(projectId, username string) (string, error) {
- oldMembership := &DevOpsProjectMembership{}
- err = dbconn.Select(DevOpsProjectMembershipColumns...).
- From(DevOpsProjectMembershipTableName).
+ oldMembership := &devops.ProjectMembership{}
+ err := o.db.Select(ProjectMembershipColumns...).
+ From(ProjectMembershipTableName).
Where(db.And(
- db.Eq(DevOpsProjectMembershipUsernameColumn, username),
- db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
+ db.Eq(ProjectMembershipUsernameColumn, username),
+ db.Eq(ProjectMembershipProjectIdColumn, projectId),
)).LoadOne(oldMembership)
if err != nil {
if err != db.ErrNotFound {
@@ -329,12 +219,12 @@ func DeleteProjectMember(projectId, username string) (string, error) {
}
}
- if oldMembership.Role == ProjectOwner {
- count, err := dbconn.Select(DevOpsProjectMembershipProjectIdColumn).
- From(DevOpsProjectMembershipTableName).
+ if oldMembership.Role == devops.ProjectOwner {
+ count, err := o.db.Select(ProjectMembershipProjectIdColumn).
+ From(ProjectMembershipTableName).
Where(db.And(
- db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
- db.Eq(DevOpsProjectMembershipRoleColumn, ProjectOwner))).Count()
+ db.Eq(ProjectMembershipProjectIdColumn, projectId),
+ db.Eq(ProjectMembershipRoleColumn, devops.ProjectOwner))).Count()
if err != nil {
klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusInternalServerError, err.Error())
@@ -346,32 +236,16 @@ func DeleteProjectMember(projectId, username string) (string, error) {
}
}
- oldProjectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, oldMembership.Role))
+ _, err = o.projectMemberOperator.DeleteProjectMember(oldMembership)
if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- err = oldProjectRole.UnAssignRole(username)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- oldPipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, oldMembership.Role))
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- err = oldPipelineRole.UnAssignRole(username)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
+ klog.Error(err)
+ return "", err
}
- _, err = dbconn.DeleteFrom(DevOpsProjectMembershipTableName).
+ _, err = o.db.DeleteFrom(ProjectMembershipTableName).
Where(db.And(
- db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
- db.Eq(DevOpsProjectMembershipUsernameColumn, username),
+ db.Eq(ProjectMembershipProjectIdColumn, projectId),
+ db.Eq(ProjectMembershipUsernameColumn, username),
)).Exec()
if err != nil {
klog.Errorf("%+v", err)
diff --git a/pkg/models/devops/project_pipeline_handler.go b/pkg/models/devops/project_pipeline_handler.go
index 96f6986d9a036a6a70cbe6d30aefc3a1fbedf0d7..c263846e82e325cdc16f5fecc231aa759690611f 100644
--- a/pkg/models/devops/project_pipeline_handler.go
+++ b/pkg/models/devops/project_pipeline_handler.go
@@ -17,295 +17,49 @@ import (
"fmt"
"github.com/emicklei/go-restful"
"k8s.io/klog"
- "kubesphere.io/kubesphere/pkg/gojenkins/utils"
- cs "kubesphere.io/kubesphere/pkg/simple/client"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
"net/http"
)
-func CreateProjectPipeline(projectId string, pipeline *ProjectPipeline) (string, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
- jenkinsClient := devops.Jenkins()
-
- switch pipeline.Type {
- case NoScmPipelineType:
-
- config, err := createPipelineConfigXml(pipeline.Pipeline)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(http.StatusInternalServerError, err.Error())
- }
-
- job, err := jenkinsClient.GetJob(pipeline.Pipeline.Name, projectId)
- if job != nil {
- err := fmt.Errorf("job name [%s] has been used", job.GetName())
- klog.Warning(err.Error())
- return "", restful.NewError(http.StatusConflict, err.Error())
- }
-
- if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- _, err = jenkinsClient.CreateJobInFolder(config, pipeline.Pipeline.Name, projectId)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- return pipeline.Pipeline.Name, nil
- case MultiBranchPipelineType:
- config, err := createMultiBranchPipelineConfigXml(projectId, pipeline.MultiBranchPipeline)
- if err != nil {
- klog.Errorf("%+v", err)
-
- return "", restful.NewError(http.StatusInternalServerError, err.Error())
- }
-
- job, err := jenkinsClient.GetJob(pipeline.MultiBranchPipeline.Name, projectId)
- if job != nil {
- err := fmt.Errorf("job name [%s] has been used", job.GetName())
- klog.Warning(err.Error())
- return "", restful.NewError(http.StatusConflict, err.Error())
- }
-
- if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- _, err = jenkinsClient.CreateJobInFolder(config, pipeline.MultiBranchPipeline.Name, projectId)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- return pipeline.MultiBranchPipeline.Name, nil
+type ProjectPipelineOperator interface {
+ CreateProjectPipeline(projectId string, pipeline *devops.ProjectPipeline) (string, error)
+ DeleteProjectPipeline(projectId string, pipelineId string) (string, error)
+ UpdateProjectPipeline(projectId, pipelineId string, pipeline *devops.ProjectPipeline) (string, error)
+ GetProjectPipelineConfig(projectId, pipelineId string) (*devops.ProjectPipeline, error)
+}
+type projectPipelineOperator struct {
+ pipelineOperator devops.ProjectPipelineOperator
+}
- default:
- err := fmt.Errorf("error unsupport job type")
- klog.Errorf("%+v", err)
- return "", restful.NewError(http.StatusBadRequest, err.Error())
+func NewProjectPipelineOperator(devopsClient devops.ProjectPipelineOperator) ProjectPipelineOperator {
+ return &projectPipelineOperator{
+ pipelineOperator: devopsClient,
}
}
-func DeleteProjectPipeline(projectId string, pipelineId string) (string, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
- jenkinsClient := devops.Jenkins()
+func (o *projectPipelineOperator) CreateProjectPipeline(projectId string, pipeline *devops.ProjectPipeline) (string, error) {
+ return o.pipelineOperator.CreateProjectPipeline(projectId, pipeline)
+}
- _, err = jenkinsClient.DeleteJob(pipelineId, projectId)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- return pipelineId, nil
+func (o *projectPipelineOperator) DeleteProjectPipeline(projectId string, pipelineId string) (string, error) {
+ return o.pipelineOperator.DeleteProjectPipeline(projectId, pipelineId)
}
-func UpdateProjectPipeline(projectId, pipelineId string, pipeline *ProjectPipeline) (string, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
- jenkinsClient := devops.Jenkins()
+func (o *projectPipelineOperator) UpdateProjectPipeline(projectId, pipelineId string, pipeline *devops.ProjectPipeline) (string, error) {
switch pipeline.Type {
- case NoScmPipelineType:
-
- config, err := createPipelineConfigXml(pipeline.Pipeline)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(http.StatusInternalServerError, err.Error())
- }
-
- job, err := jenkinsClient.GetJob(pipelineId, projectId)
-
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- err = job.UpdateConfig(config)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- return pipeline.Pipeline.Name, nil
- case MultiBranchPipelineType:
-
- config, err := createMultiBranchPipelineConfigXml(projectId, pipeline.MultiBranchPipeline)
- if err != nil {
- klog.Errorf("%+v", err)
-
- return "", restful.NewError(http.StatusInternalServerError, err.Error())
- }
-
- job, err := jenkinsClient.GetJob(pipelineId, projectId)
-
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- err = job.UpdateConfig(config)
- if err != nil {
- klog.Errorf("%+v", err)
- return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- return pipeline.MultiBranchPipeline.Name, nil
-
+ case devops.NoScmPipelineType:
+ pipeline.Pipeline.Name = pipelineId
+ case devops.MultiBranchPipelineType:
+ pipeline.MultiBranchPipeline.Name = pipelineId
default:
- err := fmt.Errorf("error unsupport job type")
+ err := fmt.Errorf("error unsupport pipeline type")
klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusBadRequest, err.Error())
}
+ return o.pipelineOperator.UpdateProjectPipeline(projectId, pipeline)
}
-func GetProjectPipeline(projectId, pipelineId string) (*ProjectPipeline, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
- jenkinsClient := devops.Jenkins()
-
- job, err := jenkinsClient.GetJob(pipelineId, projectId)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- switch job.Raw.Class {
- case "org.jenkinsci.plugins.workflow.job.WorkflowJob":
- config, err := job.GetConfig()
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- pipeline, err := parsePipelineConfigXml(config)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- pipeline.Name = pipelineId
- return &ProjectPipeline{
- Type: NoScmPipelineType,
- Pipeline: pipeline,
- }, nil
-
- case "org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject":
- config, err := job.GetConfig()
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- pipeline, err := parseMultiBranchPipelineConfigXml(config)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- pipeline.Name = pipelineId
- return &ProjectPipeline{
- Type: MultiBranchPipelineType,
- MultiBranchPipeline: pipeline,
- }, nil
- default:
- err := fmt.Errorf("error unsupport job type")
- klog.Errorf("%+v", err)
- return nil, restful.NewError(http.StatusBadRequest, err.Error())
-
- }
-}
-
-func GetPipelineSonar(projectId, pipelineId string) ([]*SonarStatus, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
- jenkinsClient := devops.Jenkins()
-
- job, err := jenkinsClient.GetJob(pipelineId, projectId)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- build, err := job.GetLastBuild()
- if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- } else if err != nil {
- klog.Errorf("%+v", err)
- return nil, nil
- }
-
- sonarStatus, err := getBuildSonarResults(build)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(http.StatusBadRequest, err.Error())
- }
- if len(sonarStatus) == 0 {
- build, err := job.GetLastCompletedBuild()
- if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- } else if err != nil {
- klog.Errorf("%+v", err)
- return nil, nil
- }
- sonarStatus, err = getBuildSonarResults(build)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(http.StatusBadRequest, err.Error())
- }
- }
- return sonarStatus, nil
-}
-
-func GetMultiBranchPipelineSonar(projectId, pipelineId, branchId string) ([]*SonarStatus, error) {
- devops, err := cs.ClientSets().Devops()
- if err != nil {
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
- jenkinsClient := devops.Jenkins()
-
- job, err := jenkinsClient.GetJob(branchId, projectId, pipelineId)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- build, err := job.GetLastBuild()
- if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- } else if err != nil {
- klog.Errorf("%+v", err)
- return nil, nil
- }
-
- sonarStatus, err := getBuildSonarResults(build)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(http.StatusBadRequest, err.Error())
- }
- if len(sonarStatus) == 0 {
- build, err := job.GetLastCompletedBuild()
- if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- } else if err != nil {
- klog.Errorf("%+v", err)
- return nil, nil
- }
- sonarStatus, err = getBuildSonarResults(build)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(http.StatusBadRequest, err.Error())
- }
- }
- return sonarStatus, nil
+func (o *projectPipelineOperator) GetProjectPipelineConfig(projectId, pipelineId string) (*devops.ProjectPipeline, error) {
+ return o.pipelineOperator.GetProjectPipelineConfig(projectId, pipelineId)
}
diff --git a/pkg/models/devops/project_pipeline_sonar_handler.go b/pkg/models/devops/project_pipeline_sonar_handler.go
new file mode 100644
index 0000000000000000000000000000000000000000..474729f93666c1ead5240bc8e57408b7c9b1e0f2
--- /dev/null
+++ b/pkg/models/devops/project_pipeline_sonar_handler.go
@@ -0,0 +1,122 @@
+package devops
+
+import (
+ "github.com/emicklei/go-restful"
+ "k8s.io/klog"
+ "kubesphere.io/kubesphere/pkg/server/errors"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "kubesphere.io/kubesphere/pkg/simple/client/sonarqube"
+ "net/http"
+)
+
+type PipelineSonarGetter interface {
+ GetPipelineSonar(projectId, pipelineId string) ([]*sonarqube.SonarStatus, error)
+ GetMultiBranchPipelineSonar(projectId, pipelineId, branchId string) ([]*sonarqube.SonarStatus, error)
+}
+type pipelineSonarGetter struct {
+ devops.BuildGetter
+ sonarqube.SonarInterface
+}
+
+func NewPipelineSonarGetter(devopClient devops.BuildGetter, sonarClient sonarqube.SonarInterface) PipelineSonarGetter {
+ return &pipelineSonarGetter{
+ BuildGetter: devopClient,
+ SonarInterface: sonarClient,
+ }
+}
+
+func (g *pipelineSonarGetter) GetPipelineSonar(projectId, pipelineId string) ([]*sonarqube.SonarStatus, error) {
+
+ build, err := g.GetProjectPipelineBuildByType(projectId, pipelineId, devops.LastBuild)
+ if err != nil && errors.GetServiceErrorCode(err) != http.StatusNotFound {
+ klog.Errorf("%+v", err)
+ return nil, err
+ } else if err != nil {
+ klog.Errorf("%+v", err)
+ return nil, nil
+ }
+ var taskIds []string
+ for _, action := range build.Actions {
+ if action.ClassName == sonarqube.SonarAnalysisActionClass {
+ taskIds = append(taskIds, action.SonarTaskId)
+ }
+ }
+ var sonarStatus []*sonarqube.SonarStatus
+
+ if len(taskIds) != 0 {
+ sonarStatus, err = g.GetSonarResultsByTaskIds(taskIds...)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ return nil, restful.NewError(http.StatusBadRequest, err.Error())
+ }
+ } else if len(taskIds) == 0 {
+ build, err := g.GetProjectPipelineBuildByType(projectId, pipelineId, devops.LastCompletedBuild)
+ if err != nil && errors.GetServiceErrorCode(err) != http.StatusNotFound {
+ klog.Errorf("%+v", err)
+ return nil, restful.NewError(errors.GetServiceErrorCode(err), err.Error())
+ } else if err != nil {
+ klog.Errorf("%+v", err)
+ return nil, nil
+ }
+ for _, action := range build.Actions {
+ if action.ClassName == sonarqube.SonarAnalysisActionClass {
+ taskIds = append(taskIds, action.SonarTaskId)
+ }
+ }
+ sonarStatus, err = g.GetSonarResultsByTaskIds(taskIds...)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ return nil, restful.NewError(http.StatusBadRequest, err.Error())
+ }
+
+ }
+ return sonarStatus, nil
+}
+
+func (g *pipelineSonarGetter) GetMultiBranchPipelineSonar(projectId, pipelineId, branchId string) ([]*sonarqube.SonarStatus, error) {
+
+ build, err := g.GetMultiBranchPipelineBuildByType(projectId, pipelineId, branchId, devops.LastBuild)
+ if err != nil && errors.GetServiceErrorCode(err) != http.StatusNotFound {
+ klog.Errorf("%+v", err)
+ return nil, restful.NewError(errors.GetServiceErrorCode(err), err.Error())
+ } else if err != nil {
+ klog.Errorf("%+v", err)
+ return nil, nil
+ }
+ var taskIds []string
+ for _, action := range build.Actions {
+ if action.ClassName == sonarqube.SonarAnalysisActionClass {
+ taskIds = append(taskIds, action.SonarTaskId)
+ }
+ }
+ var sonarStatus []*sonarqube.SonarStatus
+
+ if len(taskIds) != 0 {
+ sonarStatus, err = g.GetSonarResultsByTaskIds(taskIds...)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ return nil, restful.NewError(http.StatusBadRequest, err.Error())
+ }
+ } else if len(taskIds) == 0 {
+ build, err := g.GetMultiBranchPipelineBuildByType(projectId, pipelineId, branchId, devops.LastCompletedBuild)
+ if err != nil && errors.GetServiceErrorCode(err) != http.StatusNotFound {
+ klog.Errorf("%+v", err)
+ return nil, restful.NewError(errors.GetServiceErrorCode(err), err.Error())
+ } else if err != nil {
+ klog.Errorf("%+v", err)
+ return nil, nil
+ }
+ for _, action := range build.Actions {
+ if action.ClassName == sonarqube.SonarAnalysisActionClass {
+ taskIds = append(taskIds, action.SonarTaskId)
+ }
+ }
+ sonarStatus, err = g.GetSonarResultsByTaskIds(taskIds...)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ return nil, restful.NewError(http.StatusBadRequest, err.Error())
+ }
+
+ }
+ return sonarStatus, nil
+}
diff --git a/pkg/models/devops/s2ibinary_handler.go b/pkg/models/devops/s2ibinary_handler.go
index 71c3c060c95691a6ab82fa8a48ea3c4a73071e20..782ec380447a270e015e8b84ccc5511699ebc4b3 100644
--- a/pkg/models/devops/s2ibinary_handler.go
+++ b/pkg/models/devops/s2ibinary_handler.go
@@ -3,6 +3,8 @@ package devops
import (
"code.cloudfoundry.org/bytefmt"
"fmt"
+ "github.com/aws/aws-sdk-go/aws/awserr"
+ awsS3 "github.com/aws/aws-sdk-go/service/s3"
"github.com/emicklei/go-restful"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/client-go/util/retry"
@@ -10,7 +12,6 @@ import (
"kubesphere.io/kubesphere/pkg/apis/devops/v1alpha1"
"kubesphere.io/kubesphere/pkg/client/clientset/versioned"
"kubesphere.io/kubesphere/pkg/client/informers/externalversions"
- "kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/simple/client/s3"
"mime/multipart"
"net/http"
@@ -22,9 +23,9 @@ const (
)
type S2iBinaryUploader interface {
- UploadBinary(name, namespace, md5 string, header *multipart.FileHeader) (*v1alpha1.S2iBinary, error)
+ UploadS2iBinary(namespace, name, md5 string, header *multipart.FileHeader) (*v1alpha1.S2iBinary, error)
- DownloadBinary(name, namespace, fileName string) (string, error)
+ DownloadS2iBinary(namespace, name, fileName string) (string, error)
}
type s2iBinaryUploader struct {
@@ -33,6 +34,14 @@ type s2iBinaryUploader struct {
s3Client s3.Interface
}
+func NewS2iBinaryUploader(client versioned.Interface, informers externalversions.SharedInformerFactory, s3Client s3.Interface) S2iBinaryUploader {
+ return &s2iBinaryUploader{
+ client: client,
+ informers: informers,
+ s3Client: s3Client,
+ }
+}
+
func (s *s2iBinaryUploader) UploadS2iBinary(namespace, name, md5 string, fileHeader *multipart.FileHeader) (*v1alpha1.S2iBinary, error) {
binFile, err := fileHeader.Open()
if err != nil {
@@ -75,58 +84,35 @@ func (s *s2iBinaryUploader) UploadS2iBinary(namespace, name, md5 string, fileHea
copy.Spec.FileName = fileHeader.Filename
copy.Spec.DownloadURL = fmt.Sprintf(GetS2iBinaryURL, namespace, name, copy.Spec.FileName)
- /*
- TODO: upload binary file use s3.Interface
- s3session := s3Client.Session()
- if s3session == nil {
- err := fmt.Errorf("could not connect to s2i s3")
- klog.Error(err)
- _, serr := SetS2iBinaryStatusWithRetry(copy, origin.Status.Phase)
- if serr != nil {
- klog.Error(serr)
+ err = s.s3Client.Upload(fmt.Sprintf("%s-%s", namespace, name), copy.Spec.FileName, binFile)
+ if err != nil {
+ if aerr, ok := err.(awserr.Error); ok {
+ switch aerr.Code() {
+ case awsS3.ErrCodeNoSuchBucket:
+ klog.Error(err)
+ _, serr := s.SetS2iBinaryStatusWithRetry(copy, origin.Status.Phase)
+ if serr != nil {
+ klog.Error(serr)
+ }
return nil, err
- }
- return nil, err
- }
- uploader := s3manager.NewUploader(s3session, func(uploader *s3manager.Uploader) {
- uploader.PartSize = 5 * bytefmt.MEGABYTE
- uploader.LeavePartsOnError = true
- })
- _, err = uploader.Upload(&s3manager.UploadInput{
- Bucket: s3Client.Bucket(),
- Key: aws.String(fmt.Sprintf("%s-%s", namespace, name)),
- Body: binFile,
- ContentDisposition: aws.String(fmt.Sprintf("attachment; filename=\"%s\"", copy.Spec.FileName)),
- })
-
- if err != nil {
- if aerr, ok := err.(awserr.Error); ok {
- switch aerr.Code() {
- case s3.ErrCodeNoSuchBucket:
- klog.Error(err)
- _, serr := SetS2iBinaryStatusWithRetry(copy, origin.Status.Phase)
- if serr != nil {
- klog.Error(serr)
- }
- return nil, err
- default:
- klog.Error(err)
- _, serr := SetS2iBinaryStatusWithRetry(copy, v1alpha1.StatusUploadFailed)
- if serr != nil {
- klog.Error(serr)
- }
- return nil, err
+ default:
+ klog.Error(err)
+ _, serr := s.SetS2iBinaryStatusWithRetry(copy, v1alpha1.StatusUploadFailed)
+ if serr != nil {
+ klog.Error(serr)
}
+ return nil, err
}
- klog.Error(err)
- return nil, err
}
- */
+ klog.Error(err)
+ return nil, err
+ }
+
if copy.Spec.UploadTimeStamp == nil {
copy.Spec.UploadTimeStamp = new(metav1.Time)
}
*copy.Spec.UploadTimeStamp = metav1.Now()
- copy, err = client.ClientSets().K8s().KubeSphere().DevopsV1alpha1().S2iBinaries(namespace).Update(copy)
+ copy, err = s.client.DevopsV1alpha1().S2iBinaries(namespace).Update(copy)
if err != nil {
klog.Error(err)
return nil, err
@@ -159,22 +145,7 @@ func (s *s2iBinaryUploader) DownloadS2iBinary(namespace, name, fileName string)
klog.Error(err)
return "", err
}
-
- /*
- TODO: get download url of requested binary
- req, _ := s.s3Client.Client().GetObjectRequest(&s3.GetObjectInput{
- Bucket: s3Client.Bucket(),
- Key: aws.String(fmt.Sprintf("%s-%s", namespace, name)),
- ResponseContentDisposition: aws.String(fmt.Sprintf("attachment; filename=\"%s\"", origin.Spec.FileName)),
- })
- url, err := req.Presign(5 * time.Minute)
- if err != nil {
- klog.Error(err)
- return "", err
- }
- */
- return "", nil
-
+ return s.s3Client.GetDownloadURL(fmt.Sprintf("%s-%s", namespace, name), fileName)
}
func (s *s2iBinaryUploader) SetS2iBinaryStatus(s2ibin *v1alpha1.S2iBinary, status string) (*v1alpha1.S2iBinary, error) {
@@ -193,7 +164,7 @@ func (s *s2iBinaryUploader) SetS2iBinaryStatusWithRetry(s2ibin *v1alpha1.S2iBina
var bin *v1alpha1.S2iBinary
var err error
err = retry.RetryOnConflict(retry.DefaultRetry, func() error {
- bin, err = s.informers.Devops().V1alpha1().S2iBinaries().Lister().S2iBinaries(s2ibin.Namespace).Get(s2ibin.Name)
+ bin, err = s.client.DevopsV1alpha1().S2iBinaries(s2ibin.Namespace).Get(s2ibin.Name, metav1.GetOptions{})
if err != nil {
klog.Error(err)
return err
diff --git a/pkg/models/devops/s2ibinary_handler_test.go b/pkg/models/devops/s2ibinary_handler_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..f056cc9358cbb488798d03901b39fc9d11a28d83
--- /dev/null
+++ b/pkg/models/devops/s2ibinary_handler_test.go
@@ -0,0 +1,114 @@
+package devops
+
+import (
+ "code.cloudfoundry.org/bytefmt"
+ "fmt"
+ v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+ "k8s.io/apimachinery/pkg/watch"
+ clientgotesting "k8s.io/client-go/testing"
+ "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha1"
+ "kubesphere.io/kubesphere/pkg/client/clientset/versioned/fake"
+ ksinformers "kubesphere.io/kubesphere/pkg/client/informers/externalversions"
+ fakeS3 "kubesphere.io/kubesphere/pkg/simple/client/s3/fake"
+ "kubesphere.io/kubesphere/pkg/utils/hashutil"
+ "mime/multipart"
+ "reflect"
+ "strings"
+ "testing"
+ "time"
+)
+
+const (
+ fileaContents = "This is a test file."
+ fileaKey = "binary"
+ fileaName = "filea.txt"
+ boundary = `MyBoundary`
+ ns = "testns"
+ s2ibname = "test"
+)
+
+const message = `
+--MyBoundary
+Content-Disposition: form-data; name="binary"; filename="filea.txt"
+Content-Type: text/plain
+
+` + fileaContents + `
+--MyBoundary--
+`
+
+func TestS2iBinaryUploader(t *testing.T) {
+ s2ib := s2ibinary(ns, s2ibname)
+ fakeKubeClient := fake.NewSimpleClientset(s2ib)
+ fakeWatch := watch.NewFake()
+ fakeKubeClient.AddWatchReactor("*", clientgotesting.DefaultWatchReactor(fakeWatch, nil))
+ informerFactory := ksinformers.NewSharedInformerFactory(fakeKubeClient, 0)
+ stopCh := make(chan struct{})
+ s2iInformer := informerFactory.Devops().V1alpha1().S2iBinaries()
+ err := s2iInformer.Informer().GetIndexer().Add(s2ib)
+ defer close(stopCh)
+ informerFactory.Start(stopCh)
+ informerFactory.WaitForCacheSync(stopCh)
+
+ s3 := fakeS3.NewFakeS3()
+ uploader := NewS2iBinaryUploader(fakeKubeClient, informerFactory, s3)
+ header := prepareFileHeader()
+ file, err := header.Open()
+ if err != nil {
+ t.Fatal(err)
+ }
+ md5, err := hashutil.GetMD5(file)
+ if err != nil {
+ t.Fatal(err)
+ }
+ wantSpec := v1alpha1.S2iBinarySpec{
+ FileName: fileaName,
+ MD5: md5,
+ Size: bytefmt.ByteSize(uint64(header.Size)),
+ }
+
+ binary, err := uploader.UploadS2iBinary(ns, s2ibname, md5, header)
+ if err != nil {
+ t.Fatal(err)
+ }
+
+ wantSpec.UploadTimeStamp = binary.Spec.UploadTimeStamp
+ wantSpec.DownloadURL = binary.Spec.DownloadURL
+ if !reflect.DeepEqual(binary.Spec, wantSpec) {
+ t.Fatalf("s2ibinary spec is not same with expected, get: %+v, expected: %+v", binary, wantSpec)
+ }
+
+ _, ok := s3.Storage[fmt.Sprintf("%s-%s", ns, s2ibname)]
+ if !ok {
+ t.Fatalf("should get file in s3")
+ }
+
+ time.Sleep(3 * time.Second)
+ url, err := uploader.DownloadS2iBinary(ns, s2ibname, fileaName)
+ if err != nil {
+ t.Fatal(err)
+ }
+ if url != fmt.Sprintf("http://%s-%s/%s", ns, s2ibname, fileaName) {
+ t.Fatalf("download url is not equal with expected, get: %+v, expected: %+v", url, fmt.Sprintf("http://%s-%s/%s", ns, s2ibname, fileaName))
+ }
+}
+
+func prepareFileHeader() *multipart.FileHeader {
+ reader := strings.NewReader(message)
+ multipartReader := multipart.NewReader(reader, boundary)
+ form, err := multipartReader.ReadForm(25)
+ if err != nil {
+ panic(err)
+ }
+ return form.File["binary"][0]
+}
+
+func s2ibinary(namespace, name string) *v1alpha1.S2iBinary {
+ return &v1alpha1.S2iBinary{
+ ObjectMeta: v1.ObjectMeta{
+ Name: name,
+ Namespace: namespace,
+ },
+ Spec: v1alpha1.S2iBinarySpec{},
+ Status: v1alpha1.S2iBinaryStatus{},
+ }
+}
diff --git a/pkg/models/devops/urlconfig.go b/pkg/models/devops/urlconfig.go
deleted file mode 100644
index 222cc07ab1481d2b30118604c7918d13253f417f..0000000000000000000000000000000000000000
--- a/pkg/models/devops/urlconfig.go
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
-
- Copyright 2019 The KubeSphere Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
-
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
-
-*/
-package devops
-
-// Some apis for Jenkins.
-const (
- GetPipeBranchUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/?"
- GetBranchPipeUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/"
- GetPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/"
- SearchPipelineUrl = "/blue/rest/search/?"
- RunBranchPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/"
- RunPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/"
- GetPipelineRunUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/"
- GetPipeBranchRunUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/"
- SearchPipelineRunUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/?"
- GetBranchPipeRunNodesUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/nodes/?"
- GetPipeRunNodesUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/nodes/?"
- GetBranchRunLogUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/log/?"
- GetRunLogUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/log/?"
- GetBranchStepLogUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/nodes/%s/steps/%s/log/?"
- GetStepLogUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/nodes/%s/steps/%s/log/?"
- StopBranchPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/stop/?"
- StopPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/stop/?"
- ReplayBranchPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/replay/"
- ReplayPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/replay/"
- GetBranchArtifactsUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/artifacts/?"
- GetArtifactsUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/artifacts/?"
- CheckBranchPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/nodes/%s/steps/%s/"
- CheckPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/nodes/%s/steps/%s/"
- GetBranchNodeStepsUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/nodes/%s/steps/?"
- GetNodeStepsUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/nodes/%s/steps/?"
- GetSCMServersUrl = "/blue/rest/organizations/jenkins/scm/%s/servers/"
- CreateSCMServersUrl = "/blue/rest/organizations/jenkins/scm/%s/servers/"
- ValidateUrl = "/blue/rest/organizations/jenkins/scm/%s/validate"
- GetSCMOrgUrl = "/blue/rest/organizations/jenkins/scm/%s/organizations/?"
- GetOrgRepoUrl = "/blue/rest/organizations/jenkins/scm/%s/organizations/%s/repositories/?"
- GetConsoleLogUrl = "/job/%s/job/%s/indexing/consoleText"
- ScanBranchUrl = "/job/%s/job/%s/build?"
- GetCrumbUrl = "/crumbIssuer/api/json/"
- ToJenkinsfileUrl = "/pipeline-model-converter/toJenkinsfile"
- ToJsonUrl = "/pipeline-model-converter/toJson"
- GetNotifyCommitUrl = "/git/notifyCommit/?"
- GithubWebhookUrl = "/github-webhook/"
- CheckScriptCompileUrl = "/job/%s/job/%s/descriptorByName/org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition/checkScriptCompile"
- CheckPipelienCronUrl = "/job/%s/job/%s/descriptorByName/hudson.triggers.TimerTrigger/checkSpec?value=%s"
- CheckCronUrl = "/job/%s/descriptorByName/hudson.triggers.TimerTrigger/checkSpec?value=%s"
-)
diff --git a/pkg/models/iam/im.go b/pkg/models/iam/im.go
index 5aa35a6c233a637f2ca446b9eecdee82dd0e0705..6706d9b18f4548a977fc3af46e86e8b83b8b9429 100644
--- a/pkg/models/iam/im.go
+++ b/pkg/models/iam/im.go
@@ -566,9 +566,9 @@ func (im *imOperator) deleteUserInDevOps(username string) error {
jenkinsClient := dp.Jenkins()
- _, err = devopsDb.DeleteFrom(devops.DevOpsProjectMembershipTableName).
+ _, err = devopsDb.DeleteFrom(devops.ProjectMembershipTableName).
Where(db.And(
- db.Eq(devops.DevOpsProjectMembershipUsernameColumn, username),
+ db.Eq(devops.ProjectMembershipUsernameColumn, username),
)).Exec()
if err != nil {
klog.Errorf("%+v", err)
diff --git a/pkg/models/resources/v1alpha3/interface.go b/pkg/models/resources/v1alpha3/interface.go
index 93cef31a0767ee0c4f8f481422355967e7f48dd1..871a50cd218f5e39328416e59701ae89af655807 100644
--- a/pkg/models/resources/v1alpha3/interface.go
+++ b/pkg/models/resources/v1alpha3/interface.go
@@ -64,4 +64,4 @@ func objectsToInterfaces(objs []runtime.Object) []interface{} {
res = append(res, obj)
}
return res
-}
\ No newline at end of file
+}
diff --git a/pkg/models/resources/v1alpha3/namespace/namespaces.go b/pkg/models/resources/v1alpha3/namespace/namespaces.go
index f41f2a75c9a136a071f00f6b1850610b8eef5ed9..d3b4821ee7dc12cf75cf2e6eda28d44bf6eca7b2 100644
--- a/pkg/models/resources/v1alpha3/namespace/namespaces.go
+++ b/pkg/models/resources/v1alpha3/namespace/namespaces.go
@@ -1,75 +1,75 @@
package namespace
import (
- v1 "k8s.io/api/core/v1"
- "k8s.io/apimachinery/pkg/labels"
- "k8s.io/apimachinery/pkg/runtime"
- "k8s.io/client-go/informers"
- "kubesphere.io/kubesphere/pkg/api"
- "kubesphere.io/kubesphere/pkg/apiserver/query"
- "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
- "strings"
+ v1 "k8s.io/api/core/v1"
+ "k8s.io/apimachinery/pkg/labels"
+ "k8s.io/apimachinery/pkg/runtime"
+ "k8s.io/client-go/informers"
+ "kubesphere.io/kubesphere/pkg/api"
+ "kubesphere.io/kubesphere/pkg/apiserver/query"
+ "kubesphere.io/kubesphere/pkg/models/resources/v1alpha3"
+ "strings"
)
type namespaceGetter struct {
- informers informers.SharedInformerFactory
+ informers informers.SharedInformerFactory
}
func NewNamespaceGetter(informers informers.SharedInformerFactory) v1alpha3.Interface {
- return &namespaceGetter{informers:informers}
+ return &namespaceGetter{informers: informers}
}
func (n namespaceGetter) Get(_, name string) (runtime.Object, error) {
- return n.informers.Core().V1().Namespaces().Lister().Get(name)
+ return n.informers.Core().V1().Namespaces().Lister().Get(name)
}
func (n namespaceGetter) List(_ string, query *query.Query) (*api.ListResult, error) {
- ns, err := n.informers.Core().V1().Namespaces().Lister().List(labels.Everything())
- if err != nil {
- return nil, err
- }
+ ns, err := n.informers.Core().V1().Namespaces().Lister().List(labels.Everything())
+ if err != nil {
+ return nil, err
+ }
- var result []runtime.Object
- for _, item := range ns {
- result = append(result, item)
- }
+ var result []runtime.Object
+ for _, item := range ns {
+ result = append(result, item)
+ }
- return v1alpha3.DefaultList(result, query, n.compare, n.filter), nil
+ return v1alpha3.DefaultList(result, query, n.compare, n.filter), nil
}
func (n namespaceGetter) filter(item runtime.Object, filter query.Filter) bool {
- namespace, ok := item.(*v1.Namespace)
- if !ok {
- return false
- }
+ namespace, ok := item.(*v1.Namespace)
+ if !ok {
+ return false
+ }
- switch filter.Field {
- case query.FieldName:
- return query.ComparableString(namespace.Name).Contains(filter.Value)
- case query.FieldStatus:
- return query.ComparableString(namespace.Status.Phase).Compare(filter.Value) == 0
- default:
- return false
- }
+ switch filter.Field {
+ case query.FieldName:
+ return query.ComparableString(namespace.Name).Contains(filter.Value)
+ case query.FieldStatus:
+ return query.ComparableString(namespace.Status.Phase).Compare(filter.Value) == 0
+ default:
+ return false
+ }
}
func (n namespaceGetter) compare(left runtime.Object, right runtime.Object, field query.Field) bool {
- leftNs, ok := left.(*v1.Namespace)
- if !ok {
- return false
- }
+ leftNs, ok := left.(*v1.Namespace)
+ if !ok {
+ return false
+ }
- rightNs, ok := right.(*v1.Namespace)
- if !ok {
- return true
- }
+ rightNs, ok := right.(*v1.Namespace)
+ if !ok {
+ return true
+ }
- switch field {
- case query.FieldName:
- return strings.Compare(leftNs.Name, rightNs.Name) > 0
- case query.FieldCreationTimeStamp:
- return leftNs.CreationTimestamp.After(rightNs.CreationTimestamp.Time)
- default:
- return false
- }
-}
\ No newline at end of file
+ switch field {
+ case query.FieldName:
+ return strings.Compare(leftNs.Name, rightNs.Name) > 0
+ case query.FieldCreationTimeStamp:
+ return leftNs.CreationTimestamp.After(rightNs.CreationTimestamp.Time)
+ default:
+ return false
+ }
+}
diff --git a/pkg/models/tenant/devops.go b/pkg/models/tenant/devops.go
index f9e36c0179b4ae3417ae70ceb00112185db91190..e9068f60273ae4550ff8f206af5c6098c651eb20 100644
--- a/pkg/models/tenant/devops.go
+++ b/pkg/models/tenant/devops.go
@@ -24,35 +24,40 @@ import (
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/api/devops/v1alpha2"
"kubesphere.io/kubesphere/pkg/db"
- "kubesphere.io/kubesphere/pkg/gojenkins"
- "kubesphere.io/kubesphere/pkg/gojenkins/utils"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/devops"
"kubesphere.io/kubesphere/pkg/models/iam"
"kubesphere.io/kubesphere/pkg/server/params"
- cs "kubesphere.io/kubesphere/pkg/simple/client"
+ dsClient "kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "kubesphere.io/kubesphere/pkg/simple/client/mysql"
"net/http"
- "sync"
)
-type DevOpsProjectRoleResponse struct {
- ProjectRole *gojenkins.ProjectRole
- Err error
+type DevOpsProjectOperator interface {
+ ListDevOpsProjects(workspace, username string, conditions *params.Conditions, orderBy string, reverse bool, limit int, offset int) (*models.PageableResponse, error)
+ CreateDevOpsProject(username string, workspace string, req *v1alpha2.DevOpsProject) (*v1alpha2.DevOpsProject, error)
+ GetDevOpsProjectsCount(username string) (uint32, error)
+ DeleteDevOpsProject(projectId, username string) error
+ GetUserDevOpsSimpleRules(username, projectId string) ([]iam.SimpleRule, error)
}
-func ListDevopsProjects(workspace, username string, conditions *params.Conditions, orderBy string, reverse bool, limit int, offset int) (*models.PageableResponse, error) {
+type devopsProjectOperator struct {
+ ksProjectOperator devops.ProjectOperator
+ db *mysql.Database
+ dsProject dsClient.ProjectOperator
+}
- dbconn, err := cs.ClientSets().MySQL()
- if err != nil {
- if _, ok := err.(cs.ClientSetNotEnabledError); ok {
- klog.V(4).Info("devops client is not enable")
- return nil, err
- }
- klog.Error(err)
- return nil, err
+func newProjectOperator(operator devops.ProjectOperator, db *mysql.Database, client dsClient.ProjectOperator) DevOpsProjectOperator {
+ return &devopsProjectOperator{
+ ksProjectOperator: operator,
+ db: db,
+ dsProject: client,
}
+}
+
+func (o *devopsProjectOperator) ListDevOpsProjects(workspace, username string, conditions *params.Conditions, orderBy string, reverse bool, limit int, offset int) (*models.PageableResponse, error) {
- query := dbconn.Select(devops.GetColumnsFromStructWithPrefix(devops.DevOpsProjectTableName, v1alpha2.DevOpsProject{})...).
+ query := o.db.Select(devops.GetColumnsFromStructWithPrefix(devops.DevOpsProjectTableName, v1alpha2.DevOpsProject{})...).
From(devops.DevOpsProjectTableName)
var sqconditions []dbr.Builder
@@ -61,11 +66,11 @@ func ListDevopsProjects(workspace, username string, conditions *params.Condition
switch username {
case devops.KS_ADMIN:
default:
- onCondition := fmt.Sprintf("%s = %s", devops.DevOpsProjectMembershipProjectIdColumn, devops.DevOpsProjectIdColumn)
- query.Join(devops.DevOpsProjectMembershipTableName, onCondition)
- sqconditions = append(sqconditions, db.Eq(devops.DevOpsProjectMembershipUsernameColumn, username))
+ onCondition := fmt.Sprintf("%s = %s", devops.ProjectMembershipProjectIdColumn, devops.DevOpsProjectIdColumn)
+ query.Join(devops.ProjectMembershipTableName, onCondition)
+ sqconditions = append(sqconditions, db.Eq(devops.ProjectMembershipUsernameColumn, username))
sqconditions = append(sqconditions, db.Eq(
- devops.DevOpsProjectMembershipTableName+"."+devops.StatusColumn, devops.StatusActive))
+ devops.ProjectMembershipTableName+"."+devops.StatusColumn, devops.StatusActive))
}
sqconditions = append(sqconditions, db.Eq(
@@ -95,7 +100,7 @@ func ListDevopsProjects(workspace, username string, conditions *params.Condition
}
query.Limit(uint64(limit))
query.Offset(uint64(offset))
- _, err = query.Load(&projects)
+ _, err := query.Load(&projects)
if err != nil {
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
@@ -114,23 +119,18 @@ func ListDevopsProjects(workspace, username string, conditions *params.Condition
return &models.PageableResponse{Items: result, TotalCount: int(count)}, nil
}
-func GetDevOpsProjectsCount(username string) (uint32, error) {
- dbconn, err := cs.ClientSets().MySQL()
- if err != nil {
- klog.Error(err)
- return 0, err
- }
+func (o *devopsProjectOperator) GetDevOpsProjectsCount(username string) (uint32, error) {
- query := dbconn.Select(devops.GetColumnsFromStructWithPrefix(devops.DevOpsProjectTableName, v1alpha2.DevOpsProject{})...).
+ query := o.db.Select(devops.GetColumnsFromStructWithPrefix(devops.DevOpsProjectTableName, v1alpha2.DevOpsProject{})...).
From(devops.DevOpsProjectTableName)
var sqconditions []dbr.Builder
if username != devops.KS_ADMIN {
- onCondition := fmt.Sprintf("%s = %s", devops.DevOpsProjectMembershipProjectIdColumn, devops.DevOpsProjectIdColumn)
- query.Join(devops.DevOpsProjectMembershipTableName, onCondition)
- sqconditions = append(sqconditions, db.Eq(devops.DevOpsProjectMembershipUsernameColumn, username))
+ onCondition := fmt.Sprintf("%s = %s", devops.ProjectMembershipProjectIdColumn, devops.DevOpsProjectIdColumn)
+ query.Join(devops.ProjectMembershipTableName, onCondition)
+ sqconditions = append(sqconditions, db.Eq(devops.ProjectMembershipUsernameColumn, username))
sqconditions = append(sqconditions, db.Eq(
- devops.DevOpsProjectMembershipTableName+"."+devops.StatusColumn, devops.StatusActive))
+ devops.ProjectMembershipTableName+"."+devops.StatusColumn, devops.StatusActive))
}
sqconditions = append(sqconditions, db.Eq(
@@ -146,171 +146,61 @@ func GetDevOpsProjectsCount(username string) (uint32, error) {
return count, nil
}
-func DeleteDevOpsProject(projectId, username string) error {
- err := devops.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner})
+func (o *devopsProjectOperator) DeleteDevOpsProject(projectId, username string) error {
+ err := o.ksProjectOperator.CheckProjectUserInRole(username, projectId, []string{dsClient.ProjectOwner})
if err != nil {
klog.Errorf("%+v", err)
return restful.NewError(http.StatusForbidden, err.Error())
}
- dp, err := cs.ClientSets().Devops()
- if err != nil {
- klog.Error(err)
- return restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
- jenkins := dp.Jenkins()
-
- devopsdb, err := cs.ClientSets().MySQL()
- if err != nil {
- klog.Error(err)
- return restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
-
- _, err = jenkins.DeleteJob(projectId)
-
- if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound {
- klog.Errorf("%+v", err)
- return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- roleNames := make([]string, 0)
- for role := range devops.JenkinsProjectPermissionMap {
- roleNames = append(roleNames, devops.GetProjectRoleName(projectId, role))
- roleNames = append(roleNames, devops.GetPipelineRoleName(projectId, role))
- }
- err = jenkins.DeleteProjectRoles(roleNames...)
+ err = o.dsProject.DeleteDevOpsProject(projectId)
if err != nil {
klog.Errorf("%+v", err)
- return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
+ return err
}
- _, err = devopsdb.DeleteFrom(devops.DevOpsProjectMembershipTableName).
- Where(db.Eq(devops.DevOpsProjectMembershipProjectIdColumn, projectId)).Exec()
+ _, err = o.db.DeleteFrom(devops.ProjectMembershipTableName).
+ Where(db.Eq(devops.ProjectMembershipProjectIdColumn, projectId)).Exec()
if err != nil {
klog.Errorf("%+v", err)
- return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
+ return err
}
- _, err = devopsdb.Update(devops.DevOpsProjectTableName).
+ _, err = o.db.Update(devops.DevOpsProjectTableName).
Set(devops.StatusColumn, devops.StatusDeleted).
Where(db.Eq(devops.DevOpsProjectIdColumn, projectId)).Exec()
if err != nil {
klog.Errorf("%+v", err)
- return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
+ return err
}
project := &v1alpha2.DevOpsProject{}
- err = devopsdb.Select(devops.DevOpsProjectColumns...).
+ err = o.db.Select(devops.DevOpsProjectColumns...).
From(devops.DevOpsProjectTableName).
Where(db.Eq(devops.DevOpsProjectIdColumn, projectId)).
LoadOne(project)
if err != nil {
klog.Errorf("%+v", err)
- return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
+ return err
}
return nil
}
-func CreateDevopsProject(username string, workspace string, req *v1alpha2.DevOpsProject) (*v1alpha2.DevOpsProject, error) {
-
- dp, err := cs.ClientSets().Devops()
- if err != nil {
- klog.Error(err)
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
-
- }
- jenkinsClient := dp.Jenkins()
-
- devopsdb, err := cs.ClientSets().MySQL()
- if err != nil {
- klog.Error(err)
- return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
- }
+func (o *devopsProjectOperator) CreateDevOpsProject(username string, workspace string, req *v1alpha2.DevOpsProject) (*v1alpha2.DevOpsProject, error) {
project := devops.NewDevOpsProject(req.Name, req.Description, username, req.Extra, workspace)
- _, err = jenkinsClient.CreateFolder(project.ProjectId, project.Description)
+ _, err := o.dsProject.CreateDevOpsProject(username, project)
if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- var addRoleCh = make(chan *DevOpsProjectRoleResponse, 8)
- var addRoleWg sync.WaitGroup
- for role, permission := range devops.JenkinsProjectPermissionMap {
- addRoleWg.Add(1)
- go func(role string, permission gojenkins.ProjectPermissionIds) {
- _, err := jenkinsClient.AddProjectRole(devops.GetProjectRoleName(project.ProjectId, role),
- devops.GetProjectRolePattern(project.ProjectId), permission, true)
- addRoleCh <- &DevOpsProjectRoleResponse{nil, err}
- addRoleWg.Done()
- }(role, permission)
- }
- for role, permission := range devops.JenkinsPipelinePermissionMap {
- addRoleWg.Add(1)
- go func(role string, permission gojenkins.ProjectPermissionIds) {
- _, err := jenkinsClient.AddProjectRole(devops.GetPipelineRoleName(project.ProjectId, role),
- devops.GetPipelineRolePattern(project.ProjectId), permission, true)
- addRoleCh <- &DevOpsProjectRoleResponse{nil, err}
- addRoleWg.Done()
- }(role, permission)
- }
- addRoleWg.Wait()
- close(addRoleCh)
- for addRoleResponse := range addRoleCh {
- if addRoleResponse.Err != nil {
- klog.Errorf("%+v", addRoleResponse.Err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(addRoleResponse.Err), addRoleResponse.Err.Error())
- }
- }
-
- globalRole, err := jenkinsClient.GetGlobalRole(devops.JenkinsAllUserRoleName)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- if globalRole == nil {
- _, err := jenkinsClient.AddGlobalRole(devops.JenkinsAllUserRoleName, gojenkins.GlobalPermissionIds{
- GlobalRead: true,
- }, true)
- if err != nil {
- klog.Error("failed to create jenkins global role")
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- }
- err = globalRole.AssignRole(username)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- projectRole, err := jenkinsClient.GetProjectRole(devops.GetProjectRoleName(project.ProjectId, devops.ProjectOwner))
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- err = projectRole.AssignRole(username)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
-
- pipelineRole, err := jenkinsClient.GetProjectRole(devops.GetPipelineRoleName(project.ProjectId, devops.ProjectOwner))
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
- }
- err = pipelineRole.AssignRole(username)
- if err != nil {
- klog.Errorf("%+v", err)
- return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
+ klog.Error(err)
+ return nil, err
}
- _, err = devopsdb.InsertInto(devops.DevOpsProjectTableName).
+ _, err = o.db.InsertInto(devops.DevOpsProjectTableName).
Columns(devops.DevOpsProjectColumns...).Record(project).Exec()
if err != nil {
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
}
- projectMembership := devops.NewDevOpsProjectMemberShip(username, project.ProjectId, devops.ProjectOwner, username)
- _, err = devopsdb.InsertInto(devops.DevOpsProjectMembershipTableName).
- Columns(devops.DevOpsProjectMembershipColumns...).Record(projectMembership).Exec()
+ projectMembership := devops.NewDevOpsProjectMemberShip(username, project.ProjectId, dsClient.ProjectOwner, username)
+ _, err = o.db.InsertInto(devops.ProjectMembershipTableName).
+ Columns(devops.ProjectMembershipColumns...).Record(projectMembership).Exec()
if err != nil {
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
@@ -318,8 +208,9 @@ func CreateDevopsProject(username string, workspace string, req *v1alpha2.DevOps
return project, nil
}
-func GetUserDevopsSimpleRules(username, projectId string) ([]iam.SimpleRule, error) {
- role, err := devops.GetProjectUserRole(username, projectId)
+func (o *devopsProjectOperator) GetUserDevOpsSimpleRules(username, projectId string) ([]iam.SimpleRule, error) {
+
+ role, err := o.getProjectUserRole(username, projectId)
if err != nil {
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusForbidden, err.Error())
@@ -327,6 +218,24 @@ func GetUserDevopsSimpleRules(username, projectId string) ([]iam.SimpleRule, err
return GetDevopsRoleSimpleRules(role), nil
}
+func (o *devopsProjectOperator) getProjectUserRole(username, projectId string) (string, error) {
+ if username == devops.KS_ADMIN {
+ return dsClient.ProjectOwner, nil
+ }
+
+ membership := &dsClient.ProjectMembership{}
+ err := o.db.Select(devops.ProjectMembershipColumns...).
+ From(devops.ProjectMembershipTableName).
+ Where(db.And(
+ db.Eq(devops.ProjectMembershipUsernameColumn, username),
+ db.Eq(devops.ProjectMembershipProjectIdColumn, projectId))).LoadOne(membership)
+ if err != nil {
+ return "", err
+ }
+
+ return membership.Role, nil
+}
+
func GetDevopsRoleSimpleRules(role string) []iam.SimpleRule {
var rules []iam.SimpleRule
diff --git a/pkg/models/tenant/tenant.go b/pkg/models/tenant/tenant.go
index a68b72c3e2a8c6ed4f0182100cd4a42d90e4710e..14e13bf9a480ade6b8e9678f2e4cc6930e2cd8b4 100644
--- a/pkg/models/tenant/tenant.go
+++ b/pkg/models/tenant/tenant.go
@@ -36,11 +36,14 @@ type Interface interface {
DescribeWorkspace(username, workspace string) (*v1alpha1.Workspace, error)
ListWorkspaces(username string, conditions *params.Conditions, orderBy string, reverse bool, limit, offset int) (*models.PageableResponse, error)
ListNamespaces(username string, conditions *params.Conditions, orderBy string, reverse bool, limit, offset int) (*models.PageableResponse, error)
+ GetWorkspace(workspace string) (*v1alpha1.Workspace, error)
+ DevOpsProjectOperator
}
type tenantOperator struct {
workspaces WorkspaceInterface
namespaces NamespaceInterface
+ DevOpsProjectOperator
}
func (t *tenantOperator) DeleteNamespace(workspace, namespace string) error {
@@ -101,7 +104,7 @@ func (t *tenantOperator) appendAnnotations(username string, workspace *v1alpha1.
if err == nil {
workspace.Annotations["kubesphere.io/namespace-count"] = strconv.Itoa(ns.TotalCount)
}
- devops, err := ListDevopsProjects(workspace.Name, username, ¶ms.Conditions{}, "", false, 1, 0)
+ devops, err := t.ListDevOpsProjects(workspace.Name, username, ¶ms.Conditions{}, "", false, 1, 0)
if err == nil {
workspace.Annotations["kubesphere.io/devops-count"] = strconv.Itoa(devops.TotalCount)
}
@@ -132,3 +135,7 @@ func (t *tenantOperator) ListNamespaces(username string, conditions *params.Cond
return &models.PageableResponse{Items: result, TotalCount: len(namespaces)}, nil
}
+
+func (t *tenantOperator) GetWorkspace(workspace string) (*v1alpha1.Workspace, error) {
+ return t.workspaces.GetWorkspace(workspace)
+}
diff --git a/pkg/models/terminal/terminal.go b/pkg/models/terminal/terminal.go
index c4f88ecfdfaec811a6f97090fb34667e7a058c27..45943252c3562b2ab52f571fba8243bb200e6165 100644
--- a/pkg/models/terminal/terminal.go
+++ b/pkg/models/terminal/terminal.go
@@ -145,12 +145,12 @@ type terminaler struct {
}
func NewTerminaler(client kubernetes.Interface, config *rest.Config) Interface {
- return &terminaler{client:client, config:config}
+ return &terminaler{client: client, config: config}
}
// startProcess is called by handleAttach
// Executed cmd in the container specified in request and connects it up with the ptyHandler (a session)
-func (t *terminaler)startProcess(namespace, podName, containerName string, cmd []string, ptyHandler PtyHandler) error {
+func (t *terminaler) startProcess(namespace, podName, containerName string, cmd []string, ptyHandler PtyHandler) error {
req := t.client.CoreV1().RESTClient().Post().
Resource("pods").
Name(podName).
@@ -194,7 +194,7 @@ func isValidShell(validShells []string, shell string) bool {
return false
}
-func (t *terminaler)HandleSession(shell, namespace, podName, containerName string, conn *websocket.Conn) {
+func (t *terminaler) HandleSession(shell, namespace, podName, containerName string, conn *websocket.Conn) {
var err error
validShells := []string{"sh", "bash"}
diff --git a/pkg/server/config/config.go b/pkg/server/config/config.go
index 4dc1f6a102027683c0ac8666f5982987d85ac726..0db2c2c3eeb0add881042cf7a691729b1957b2bd 100644
--- a/pkg/server/config/config.go
+++ b/pkg/server/config/config.go
@@ -9,7 +9,7 @@ import (
"kubesphere.io/kubesphere/pkg/apiserver/runtime"
"kubesphere.io/kubesphere/pkg/simple/client/alerting"
"kubesphere.io/kubesphere/pkg/simple/client/cache"
- "kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins"
"kubesphere.io/kubesphere/pkg/simple/client/elasticsearch"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/kubesphere"
@@ -159,7 +159,7 @@ var (
type Config struct {
MySQLOptions *mysql.Options `json:"mysql,omitempty" yaml:"mysql,omitempty" mapstructure:"mysql"`
- DevopsOptions *devops.Options `json:"devops,omitempty" yaml:"devops,omitempty" mapstructure:"devops"`
+ DevopsOptions *jenkins.Options `json:"devops,omitempty" yaml:"devops,omitempty" mapstructure:"devops"`
SonarQubeOptions *sonarqube.Options `json:"sonarqube,omitempty" yaml:"sonarQube,omitempty" mapstructure:"sonarqube"`
KubernetesOptions *k8s.KubernetesOptions `json:"kubernetes,omitempty" yaml:"kubernetes,omitempty" mapstructure:"kubernetes"`
ServiceMeshOptions *servicemesh.Options `json:"servicemesh,omitempty" yaml:"servicemesh,omitempty" mapstructure:"servicemesh"`
@@ -182,7 +182,7 @@ type Config struct {
func newConfig() *Config {
return &Config{
MySQLOptions: mysql.NewMySQLOptions(),
- DevopsOptions: devops.NewDevopsOptions(),
+ DevopsOptions: jenkins.NewDevopsOptions(),
SonarQubeOptions: sonarqube.NewSonarQubeOptions(),
KubernetesOptions: k8s.NewKubernetesOptions(),
ServiceMeshOptions: servicemesh.NewServiceMeshOptions(),
diff --git a/pkg/server/config/config_test.go b/pkg/server/config/config_test.go
index af73477b24e48a6a8b3b8f39ca7fd9445bd58116..8f06b65ad0c29e0cc38fc3d66753972b7b0f2815 100644
--- a/pkg/server/config/config_test.go
+++ b/pkg/server/config/config_test.go
@@ -6,7 +6,7 @@ import (
"io/ioutil"
"kubesphere.io/kubesphere/pkg/simple/client/alerting"
"kubesphere.io/kubesphere/pkg/simple/client/cache"
- "kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins"
"kubesphere.io/kubesphere/pkg/simple/client/elasticsearch"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/kubesphere"
@@ -34,7 +34,7 @@ func newTestConfig() *Config {
MaxOpenConnections: 20,
MaxConnectionLifeTime: time.Duration(10) * time.Second,
},
- DevopsOptions: &devops.Options{
+ DevopsOptions: &jenkins.Options{
Host: "http://ks-devops.kubesphere-devops-system.svc",
Username: "jenkins",
Password: "kubesphere",
diff --git a/pkg/server/errors/errors.go b/pkg/server/errors/errors.go
index 80daea63208ae5159c132a6f208376b790560205..b89f315bc041501020bf0d954d0711f92f37cd16 100644
--- a/pkg/server/errors/errors.go
+++ b/pkg/server/errors/errors.go
@@ -47,3 +47,11 @@ func ParseSvcErr(err error, resp *restful.Response) {
resp.WriteHeaderAndEntity(http.StatusInternalServerError, Wrap(err))
}
}
+
+func GetServiceErrorCode(err error) int {
+ if svcErr, ok := err.(restful.ServiceError); ok {
+ return svcErr.Code
+ } else {
+ return http.StatusInternalServerError
+ }
+}
diff --git a/pkg/simple/client/cache/cache.go b/pkg/simple/client/cache/cache.go
index d71f15b9d55232a620faa6b6fda23de818ae7fc6..658b17d398d6a02de7cc3b4602ab2c0e61553a1a 100644
--- a/pkg/simple/client/cache/cache.go
+++ b/pkg/simple/client/cache/cache.go
@@ -20,4 +20,4 @@ type Interface interface {
// Expires updates object's expiration time, return err if key doesn't exist
Expire(key string, duration time.Duration) error
-}
\ No newline at end of file
+}
diff --git a/pkg/simple/client/cache/simple_cache.go b/pkg/simple/client/cache/simple_cache.go
index 67049a601045ce9fd4f93673f18972874991797a..349d416b344adafd9b5b8f165b798564d7b2b40b 100644
--- a/pkg/simple/client/cache/simple_cache.go
+++ b/pkg/simple/client/cache/simple_cache.go
@@ -3,38 +3,38 @@ package cache
import "time"
type simpleObject struct {
- value string
- expire time.Time
+ value string
+ expire time.Time
}
type SimpleCache struct {
- store map[string]simpleObject
+ store map[string]simpleObject
}
func NewSimpleCache() Interface {
- return &SimpleCache{store: make(map[string]simpleObject)}
+ return &SimpleCache{store: make(map[string]simpleObject)}
}
func (s *SimpleCache) Keys(pattern string) ([]string, error) {
- panic("implement me")
+ panic("implement me")
}
func (s *SimpleCache) Set(key string, value string, duration time.Duration) error {
- panic("implement me")
+ panic("implement me")
}
func (s *SimpleCache) Del(key string) error {
- panic("implement me")
+ panic("implement me")
}
func (s *SimpleCache) Get(key string) (string, error) {
- return "", nil
+ return "", nil
}
func (s *SimpleCache) Exists(key string) (bool, error) {
- panic("implement me")
+ panic("implement me")
}
func (s *SimpleCache) Expire(key string, duration time.Duration) error {
- panic("implement me")
+ panic("implement me")
}
diff --git a/pkg/gojenkins/OWNERS b/pkg/simple/client/devops/OWNERS
similarity index 100%
rename from pkg/gojenkins/OWNERS
rename to pkg/simple/client/devops/OWNERS
diff --git a/pkg/simple/client/devops/build.go b/pkg/simple/client/devops/build.go
new file mode 100644
index 0000000000000000000000000000000000000000..d1e3f0adada29943fcb302bc25d44e047918d844
--- /dev/null
+++ b/pkg/simple/client/devops/build.go
@@ -0,0 +1,115 @@
+package devops
+
+const (
+ LastBuild = "lastBuild"
+ LastCompletedBuild = "lastCompletedBuild"
+ LastFailedBuild = "lastFailedBuild"
+ LastStableBuild = "lastStableBuild"
+ LastSuccessfulBuild = "lastSuccessfulBuild"
+ LastUnstableBuild = "lastUnstableBuild"
+ LastUnsuccessfulBuild = "lastUnsuccessfulBuild"
+ FirstBuild = "firstBuild"
+)
+
+type GeneralParameter struct {
+ Name string
+ Value string
+}
+
+type Branch struct {
+ SHA1 string `json:",omitempty"`
+ Name string `json:",omitempty"`
+}
+
+type BuildRevision struct {
+ SHA1 string `json:"SHA1,omitempty"`
+ Branch []Branch `json:"Branch,omitempty"`
+}
+
+type Builds struct {
+ BuildNumber int64 `json:"buildNumber"`
+ BuildResult interface{} `json:"buildResult"`
+ Marked BuildRevision `json:"marked"`
+ Revision BuildRevision `json:"revision"`
+}
+
+type Culprit struct {
+ AbsoluteUrl string
+ FullName string
+}
+
+type GeneralAction struct {
+ Parameters []GeneralParameter `json:"parameters,omitempty"`
+ Causes []map[string]interface{} `json:"causes,omitempty"`
+ BuildsByBranchName map[string]Builds `json:"buildsByBranchName,omitempty"`
+ LastBuiltRevision *BuildRevision `json:"lastBuiltRevision,omitempty"`
+ RemoteUrls []string `json:"remoteUrls,omitempty"`
+ ScmName string `json:"scmName,omitempty"`
+ Subdir interface{} `json:"subdir,omitempty"`
+ ClassName string `json:"_class,omitempty"`
+ SonarTaskId string `json:"ceTaskId,omitempty"`
+ SonarServerUrl string `json:"serverUrl,omitempty"`
+ SonarDashboardUrl string `json:"sonarqubeDashboardUrl,omitempty"`
+ TotalCount int64 `json:",omitempty"`
+ UrlName string `json:",omitempty"`
+}
+
+type Build struct {
+ Actions []GeneralAction
+ Artifacts []struct {
+ DisplayPath string `json:"displayPath"`
+ FileName string `json:"fileName"`
+ RelativePath string `json:"relativePath"`
+ } `json:"artifacts"`
+ Building bool `json:"building"`
+ BuiltOn string `json:"builtOn"`
+ ChangeSet struct {
+ Items []struct {
+ AffectedPaths []string `json:"affectedPaths"`
+ Author struct {
+ AbsoluteUrl string `json:"absoluteUrl"`
+ FullName string `json:"fullName"`
+ } `json:"author"`
+ Comment string `json:"comment"`
+ CommitID string `json:"commitId"`
+ Date string `json:"date"`
+ ID string `json:"id"`
+ Msg string `json:"msg"`
+ Paths []struct {
+ EditType string `json:"editType"`
+ File string `json:"file"`
+ } `json:"paths"`
+ Timestamp int64 `json:"timestamp"`
+ } `json:"items"`
+ Kind string `json:"kind"`
+ Revisions []struct {
+ Module string
+ Revision int
+ } `json:"revision"`
+ } `json:"changeSet"`
+ Culprits []Culprit `json:"culprits"`
+ Description interface{} `json:"description"`
+ Duration int64 `json:"duration"`
+ EstimatedDuration int64 `json:"estimatedDuration"`
+ Executor interface{} `json:"executor"`
+ FullDisplayName string `json:"fullDisplayName"`
+ ID string `json:"id"`
+ KeepLog bool `json:"keepLog"`
+ Number int64 `json:"number"`
+ QueueID int64 `json:"queueId"`
+ Result string `json:"result"`
+ Timestamp int64 `json:"timestamp"`
+ URL string `json:"url"`
+ Runs []struct {
+ Number int64
+ URL string
+ } `json:"runs"`
+}
+
+type BuildGetter interface {
+ // GetProjectPipelineBuildByType get the last build of the pipeline, status can specify the status of the last build.
+ GetProjectPipelineBuildByType(projectId, pipelineId string, status string) (*Build, error)
+
+ // GetMultiBranchPipelineBuildByType get the last build of the pipeline, status can specify the status of the last build.
+ GetMultiBranchPipelineBuildByType(projectId, pipelineId, branch string, status string) (*Build, error)
+}
diff --git a/pkg/simple/client/devops/credential.go b/pkg/simple/client/devops/credential.go
new file mode 100644
index 0000000000000000000000000000000000000000..6a932b70083b611eb943a5964875a5b26847e4cd
--- /dev/null
+++ b/pkg/simple/client/devops/credential.go
@@ -0,0 +1,77 @@
+package devops
+
+import (
+ "time"
+)
+
+type Credential struct {
+ Id string `json:"id" description:"Id of Credential, e.g. dockerhub-id"`
+ Type string `json:"type" description:"Type of Credential, e.g. ssh/kubeconfig"`
+ DisplayName string `json:"display_name,omitempty" description:"Credential's display name"`
+ Fingerprint *struct {
+ FileName string `json:"file_name,omitempty" description:"Credential's display name and description"`
+ Hash string `json:"hash,omitempty" description:"Credential's hash"`
+ Usage []*struct {
+ Name string `json:"name,omitempty" description:"pipeline full name"`
+ Ranges struct {
+ Ranges []*struct {
+ Start int `json:"start,omitempty" description:"Start build number"`
+ End int `json:"end,omitempty" description:"End build number"`
+ } `json:"ranges,omitempty"`
+ } `json:"ranges,omitempty" description:"The build number of all pipelines that use this credential"`
+ } `json:"usage,omitempty" description:"all usage of Credential"`
+ } `json:"fingerprint,omitempty" description:"usage of the Credential"`
+ Description string `json:"description,omitempty" description:"Credential's description'"`
+ Domain string `json:"domain,omitempty" description:"Credential's domain,In ks we only use the default domain, default '_''"`
+ CreateTime *time.Time `json:"create_time,omitempty" description:"Credential's create_time'"`
+ Creator string `json:"creator,omitempty" description:"Creator's username"`
+ UsernamePasswordCredential *UsernamePasswordCredential `json:"username_password,omitempty" description:"username password Credential struct"`
+ SshCredential *SshCredential `json:"ssh,omitempty" description:"ssh Credential struct"`
+ SecretTextCredential *SecretTextCredential `json:"secret_text,omitempty" description:"secret_text Credential struct"`
+ KubeconfigCredential *KubeconfigCredential `json:"kubeconfig,omitempty" description:"kubeconfig Credential struct"`
+}
+
+type UsernamePasswordCredential struct {
+ Username string `json:"username,omitempty" description:"username of username_password credential"`
+ Password string `json:"password,omitempty" description:"password of username_password credential"`
+}
+
+type SshCredential struct {
+ Username string `json:"username,omitempty" description:"username of ssh credential"`
+ Passphrase string `json:"passphrase,omitempty" description:"passphrase of ssh credential, password of ssh credential"`
+ PrivateKey string `json:"private_key,omitempty" mapstructure:"private_key" description:"private key of ssh credential"`
+}
+
+type SecretTextCredential struct {
+ Secret string `json:"secret,omitempty" description:"secret content of credential"`
+}
+
+type KubeconfigCredential struct {
+ Content string `json:"content,omitempty" description:"content of kubeconfig"`
+}
+
+const (
+ CredentialTypeUsernamePassword = "username_password"
+ CredentialTypeSsh = "ssh"
+ CredentialTypeSecretText = "secret_text"
+ CredentialTypeKubeConfig = "kubeconfig"
+)
+
+var CredentialTypeMap = map[string]string{
+ "SSH Username with private key": CredentialTypeSsh,
+ "Username with password": CredentialTypeUsernamePassword,
+ "Secret text": CredentialTypeSecretText,
+ "Kubernetes configuration (kubeconfig)": CredentialTypeKubeConfig,
+}
+
+type CredentialOperator interface {
+ CreateCredentialInProject(projectId string, credential *Credential) (*string, error)
+
+ UpdateCredentialInProject(projectId string, credential *Credential) (*string, error)
+
+ GetCredentialInProject(projectId, id string, content bool) (*Credential, error)
+
+ GetCredentialsInProject(projectId string) ([]*Credential, error)
+
+ DeleteCredentialInProject(projectId, id string) (*string, error)
+}
diff --git a/pkg/simple/client/devops/fake/fakedevops.go b/pkg/simple/client/devops/fake/fakedevops.go
new file mode 100644
index 0000000000000000000000000000000000000000..f35b662290d44daed17d1ec759c5f311dd2b8c47
--- /dev/null
+++ b/pkg/simple/client/devops/fake/fakedevops.go
@@ -0,0 +1,206 @@
+package fake
+
+import (
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "net/http"
+ "strings"
+)
+
+type FakeDevops struct {
+ Data map[string]interface{}
+}
+
+func NewFakeDevops(data map[string]interface{}) *FakeDevops {
+ var fakeData FakeDevops
+ fakeData.Data = data
+ return &fakeData
+}
+
+// Pipelinne operator interface
+func (d *FakeDevops) GetPipeline(projectName, pipelineName string, httpParameters *devops.HttpParameters) (*devops.Pipeline, error) {
+ return nil, nil
+}
+
+func (d *FakeDevops) ListPipelines(httpParameters *devops.HttpParameters) (*devops.PipelineList, error) {
+ return nil, nil
+}
+func (d *FakeDevops) GetPipelineRun(projectName, pipelineName, runId string, httpParameters *devops.HttpParameters) (*devops.PipelineRun, error) {
+ return nil, nil
+}
+func (d *FakeDevops) ListPipelineRuns(projectName, pipelineName string, httpParameters *devops.HttpParameters) (*devops.PipelineRunList, error) {
+ return nil, nil
+}
+func (d *FakeDevops) StopPipeline(projectName, pipelineName, runId string, httpParameters *devops.HttpParameters) (*devops.StopPipeline, error) {
+ return nil, nil
+}
+func (d *FakeDevops) ReplayPipeline(projectName, pipelineName, runId string, httpParameters *devops.HttpParameters) (*devops.ReplayPipeline, error) {
+ return nil, nil
+}
+func (d *FakeDevops) RunPipeline(projectName, pipelineName string, httpParameters *devops.HttpParameters) (*devops.RunPipeline, error) {
+ return nil, nil
+}
+func (d *FakeDevops) GetArtifacts(projectName, pipelineName, runId string, httpParameters *devops.HttpParameters) ([]devops.Artifacts, error) {
+ return nil, nil
+}
+func (d *FakeDevops) GetRunLog(projectName, pipelineName, runId string, httpParameters *devops.HttpParameters) ([]byte, error) {
+ return nil, nil
+}
+func (d *FakeDevops) GetStepLog(projectName, pipelineName, runId, nodeId, stepId string, httpParameters *devops.HttpParameters) ([]byte, http.Header, error) {
+ return nil, nil, nil
+}
+func (d *FakeDevops) GetNodeSteps(projectName, pipelineName, runId, nodeId string, httpParameters *devops.HttpParameters) ([]devops.NodeSteps, error) {
+ s := []string{projectName, pipelineName, runId, nodeId}
+ key := strings.Join(s, "-")
+ res := d.Data[key].([]devops.NodeSteps)
+ return res, nil
+}
+func (d *FakeDevops) GetPipelineRunNodes(projectName, pipelineName, runId string, httpParameters *devops.HttpParameters) ([]devops.PipelineRunNodes, error) {
+ s := []string{projectName, pipelineName, runId}
+ key := strings.Join(s, "-")
+ res := d.Data[key].([]devops.PipelineRunNodes)
+ return res, nil
+}
+func (d *FakeDevops) SubmitInputStep(projectName, pipelineName, runId, nodeId, stepId string, httpParameters *devops.HttpParameters) ([]byte, error) {
+ return nil, nil
+}
+
+//BranchPipelinne operator interface
+func (d *FakeDevops) GetBranchPipeline(projectName, pipelineName, branchName string, httpParameters *devops.HttpParameters) (*devops.BranchPipeline, error) {
+ return nil, nil
+}
+func (d *FakeDevops) GetBranchPipelineRun(projectName, pipelineName, branchName, runId string, httpParameters *devops.HttpParameters) (*devops.PipelineRun, error) {
+ return nil, nil
+}
+func (d *FakeDevops) StopBranchPipeline(projectName, pipelineName, branchName, runId string, httpParameters *devops.HttpParameters) (*devops.StopPipeline, error) {
+ return nil, nil
+}
+func (d *FakeDevops) ReplayBranchPipeline(projectName, pipelineName, branchName, runId string, httpParameters *devops.HttpParameters) (*devops.ReplayPipeline, error) {
+ return nil, nil
+}
+func (d *FakeDevops) RunBranchPipeline(projectName, pipelineName, branchName string, httpParameters *devops.HttpParameters) (*devops.RunPipeline, error) {
+ return nil, nil
+}
+func (d *FakeDevops) GetBranchArtifacts(projectName, pipelineName, branchName, runId string, httpParameters *devops.HttpParameters) ([]devops.Artifacts, error) {
+ return nil, nil
+}
+func (d *FakeDevops) GetBranchRunLog(projectName, pipelineName, branchName, runId string, httpParameters *devops.HttpParameters) ([]byte, error) {
+ return nil, nil
+}
+func (d *FakeDevops) GetBranchStepLog(projectName, pipelineName, branchName, runId, nodeId, stepId string, httpParameters *devops.HttpParameters) ([]byte, http.Header, error) {
+ return nil, nil, nil
+}
+func (d *FakeDevops) GetBranchNodeSteps(projectName, pipelineName, branchName, runId, nodeId string, httpParameters *devops.HttpParameters) ([]devops.NodeSteps, error) {
+ s := []string{projectName, pipelineName, branchName, runId, nodeId}
+ key := strings.Join(s, "-")
+ res := d.Data[key].([]devops.NodeSteps)
+ return res, nil
+}
+func (d *FakeDevops) GetBranchPipelineRunNodes(projectName, pipelineName, branchName, runId string, httpParameters *devops.HttpParameters) ([]devops.BranchPipelineRunNodes, error) {
+ s := []string{projectName, pipelineName, branchName, runId}
+ key := strings.Join(s, "-")
+ res := d.Data[key].([]devops.BranchPipelineRunNodes)
+ return res, nil
+}
+func (d *FakeDevops) SubmitBranchInputStep(projectName, pipelineName, branchName, runId, nodeId, stepId string, httpParameters *devops.HttpParameters) ([]byte, error) {
+ return nil, nil
+}
+func (d *FakeDevops) GetPipelineBranch(projectName, pipelineName string, httpParameters *devops.HttpParameters) (*devops.PipelineBranch, error) {
+ return nil, nil
+}
+func (d *FakeDevops) ScanBranch(projectName, pipelineName string, httpParameters *devops.HttpParameters) ([]byte, error) {
+ return nil, nil
+}
+
+// Common pipeline operator interface
+func (d *FakeDevops) GetConsoleLog(projectName, pipelineName string, httpParameters *devops.HttpParameters) ([]byte, error) {
+ return nil, nil
+}
+func (d *FakeDevops) GetCrumb(httpParameters *devops.HttpParameters) (*devops.Crumb, error) {
+ return nil, nil
+}
+
+// SCM operator interface
+func (d *FakeDevops) GetSCMServers(scmId string, httpParameters *devops.HttpParameters) ([]devops.SCMServer, error) {
+ return nil, nil
+}
+func (d *FakeDevops) GetSCMOrg(scmId string, httpParameters *devops.HttpParameters) ([]devops.SCMOrg, error) {
+ return nil, nil
+}
+func (d *FakeDevops) GetOrgRepo(scmId, organizationId string, httpParameters *devops.HttpParameters) ([]devops.OrgRepo, error) {
+ return nil, nil
+}
+func (d *FakeDevops) CreateSCMServers(scmId string, httpParameters *devops.HttpParameters) (*devops.SCMServer, error) {
+ return nil, nil
+}
+func (d *FakeDevops) Validate(scmId string, httpParameters *devops.HttpParameters) (*devops.Validates, error) {
+ return nil, nil
+}
+
+//Webhook operator interface
+func (d *FakeDevops) GetNotifyCommit(httpParameters *devops.HttpParameters) ([]byte, error) {
+ return nil, nil
+}
+func (d *FakeDevops) GithubWebhook(httpParameters *devops.HttpParameters) ([]byte, error) {
+ return nil, nil
+}
+
+func (d *FakeDevops) CheckScriptCompile(projectName, pipelineName string, httpParameters *devops.HttpParameters) (*devops.CheckScript, error) {
+ return nil, nil
+}
+func (d *FakeDevops) CheckCron(projectName string, httpParameters *devops.HttpParameters) (*devops.CheckCronRes, error) {
+ return nil, nil
+}
+func (d *FakeDevops) ToJenkinsfile(httpParameters *devops.HttpParameters) (*devops.ResJenkinsfile, error) {
+ return nil, nil
+}
+func (d *FakeDevops) ToJson(httpParameters *devops.HttpParameters) (*devops.ResJson, error) {
+ return nil, nil
+}
+
+// CredentialOperator
+func (d *FakeDevops) CreateCredentialInProject(projectId string, credential *devops.Credential) (*string, error) {
+ return nil, nil
+}
+func (d *FakeDevops) UpdateCredentialInProject(projectId string, credential *devops.Credential) (*string, error) {
+ return nil, nil
+}
+func (d *FakeDevops) GetCredentialInProject(projectId, id string, content bool) (*devops.Credential, error) {
+ return nil, nil
+}
+func (d *FakeDevops) GetCredentialsInProject(projectId string) ([]*devops.Credential, error) {
+ return nil, nil
+}
+func (d *FakeDevops) DeleteCredentialInProject(projectId, id string) (*string, error) { return nil, nil }
+
+// BuildGetter
+func (d *FakeDevops) GetProjectPipelineBuildByType(projectId, pipelineId string, status string) (*devops.Build, error) {
+ return nil, nil
+}
+func (d *FakeDevops) GetMultiBranchPipelineBuildByType(projectId, pipelineId, branch string, status string) (*devops.Build, error) {
+ return nil, nil
+}
+
+// ProjectMemberOperator
+func (d *FakeDevops) AddProjectMember(membership *devops.ProjectMembership) (*devops.ProjectMembership, error) {
+ return nil, nil
+}
+func (d *FakeDevops) UpdateProjectMember(oldMembership, newMembership *devops.ProjectMembership) (*devops.ProjectMembership, error) {
+ return nil, nil
+}
+func (d *FakeDevops) DeleteProjectMember(membership *devops.ProjectMembership) (*devops.ProjectMembership, error) {
+ return nil, nil
+}
+
+// ProjectPipelineOperator
+func (d *FakeDevops) CreateProjectPipeline(projectId string, pipeline *devops.ProjectPipeline) (string, error) {
+ return "", nil
+}
+func (d *FakeDevops) DeleteProjectPipeline(projectId string, pipelineId string) (string, error) {
+ return "", nil
+}
+func (d *FakeDevops) UpdateProjectPipeline(projectId string, pipeline *devops.ProjectPipeline) (string, error) {
+ return "", nil
+}
+func (d *FakeDevops) GetProjectPipelineConfig(projectId, pipelineId string) (*devops.ProjectPipeline, error) {
+ return nil, nil
+}
diff --git a/pkg/simple/client/devops/interface.go b/pkg/simple/client/devops/interface.go
index 07ec338e0310eb003e05568017094bed3ee5171a..80b5ec6cf3b0a32b02362f43c83a1868f4e9ae0b 100644
--- a/pkg/simple/client/devops/interface.go
+++ b/pkg/simple/client/devops/interface.go
@@ -1,19 +1,13 @@
package devops
-type Job struct {
-
-}
-
type Interface interface {
- GetJob(projectId, pipelineName string) (*Job, error)
-
- DeleteJob(projectId, pipelineId string) (bool, error)
+ CredentialOperator
- CreateJobInFolder()
+ BuildGetter
- GetGlobalRole(roleName string)
+ PipelineOperator
- AddGlobalRole(roleName string, permission string)
+ ProjectMemberOperator
- GetProjectRole(roleName string)
+ ProjectPipelineOperator
}
diff --git a/pkg/gojenkins/README.md b/pkg/simple/client/devops/jenkins/README.md
similarity index 100%
rename from pkg/gojenkins/README.md
rename to pkg/simple/client/devops/jenkins/README.md
diff --git a/pkg/gojenkins/build.go b/pkg/simple/client/devops/jenkins/build.go
similarity index 74%
rename from pkg/gojenkins/build.go
rename to pkg/simple/client/devops/jenkins/build.go
index 0d8af0a5eb0b1ee6d2449038e8b0acb7bd1783e1..43f81a19c77ba58fadbdf72209df52c8b275689c 100644
--- a/pkg/gojenkins/build.go
+++ b/pkg/simple/client/devops/jenkins/build.go
@@ -12,14 +12,15 @@
// License for the specific language governing permissions and limitations
// under the License.
-package gojenkins
+package jenkins
import (
"bytes"
"errors"
+ "github.com/emicklei/go-restful"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
"net/http"
"net/url"
- "regexp"
"strconv"
"time"
)
@@ -31,26 +32,26 @@ const (
)
type Build struct {
- Raw *BuildResponse
+ Raw *devops.Build
Job *Job
Jenkins *Jenkins
Base string
Depth int
}
-type parameter struct {
+type Parameter struct {
Name string
Value string
}
-type branch struct {
+type Branch struct {
SHA1 string `json:",omitempty"`
Name string `json:",omitempty"`
}
type BuildRevision struct {
SHA1 string `json:"SHA1,omitempty"`
- Branch []branch `json:"branch,omitempty"`
+ Branch []Branch `json:"Branch,omitempty"`
}
type Builds struct {
@@ -66,7 +67,7 @@ type Culprit struct {
}
type GeneralObj struct {
- Parameters []parameter `json:"parameters,omitempty"`
+ Parameters []Parameter `json:"parameters,omitempty"`
Causes []map[string]interface{} `json:"causes,omitempty"`
BuildsByBranchName map[string]Builds `json:"buildsByBranchName,omitempty"`
LastBuiltRevision *BuildRevision `json:"lastBuiltRevision,omitempty"`
@@ -114,7 +115,7 @@ type TestResult struct {
}
type BuildResponse struct {
- Actions []GeneralObj
+ Actions []devops.GeneralAction
Artifacts []struct {
DisplayPath string `json:"displayPath"`
FileName string `json:"fileName"`
@@ -146,22 +147,21 @@ type BuildResponse struct {
Revision int
} `json:"revision"`
} `json:"changeSet"`
- Culprits []Culprit `json:"culprits"`
- Description interface{} `json:"description"`
- Duration int64 `json:"duration"`
- EstimatedDuration int64 `json:"estimatedDuration"`
- Executor interface{} `json:"executor"`
- FullDisplayName string `json:"fullDisplayName"`
- ID string `json:"id"`
- KeepLog bool `json:"keepLog"`
- Number int64 `json:"number"`
- QueueID int64 `json:"queueId"`
- Result string `json:"result"`
- Timestamp int64 `json:"timestamp"`
- URL string `json:"url"`
- MavenArtifacts interface{} `json:"mavenArtifacts"`
- MavenVersionUsed string `json:"mavenVersionUsed"`
- FingerPrint []FingerPrintResponse
+ Culprits []devops.Culprit `json:"culprits"`
+ Description interface{} `json:"description"`
+ Duration int64 `json:"duration"`
+ EstimatedDuration int64 `json:"estimatedDuration"`
+ Executor interface{} `json:"executor"`
+ FullDisplayName string `json:"fullDisplayName"`
+ ID string `json:"id"`
+ KeepLog bool `json:"keepLog"`
+ Number int64 `json:"number"`
+ QueueID int64 `json:"queueId"`
+ Result string `json:"result"`
+ Timestamp int64 `json:"timestamp"`
+ URL string `json:"url"`
+ MavenArtifacts interface{} `json:"mavenArtifacts"`
+ MavenVersionUsed string `json:"mavenVersionUsed"`
Runs []struct {
Number int64
URL string
@@ -169,14 +169,10 @@ type BuildResponse struct {
}
// Builds
-func (b *Build) Info() *BuildResponse {
+func (b *Build) Info() *devops.Build {
return b.Raw
}
-func (b *Build) GetActions() []GeneralObj {
- return b.Raw.Actions
-}
-
func (b *Build) GetUrl() string {
return b.Raw.URL
}
@@ -188,23 +184,6 @@ func (b *Build) GetResult() string {
return b.Raw.Result
}
-func (b *Build) GetArtifacts() []Artifact {
- artifacts := make([]Artifact, len(b.Raw.Artifacts))
- for i, artifact := range b.Raw.Artifacts {
- artifacts[i] = Artifact{
- Jenkins: b.Jenkins,
- Build: b,
- FileName: artifact.FileName,
- Path: b.Base + "/artifact/" + artifact.RelativePath,
- }
- }
- return artifacts
-}
-
-func (b *Build) GetCulprits() []Culprit {
- return b.Raw.Culprits
-}
-
func (b *Build) Stop() (bool, error) {
if b.IsRunning() {
response, err := b.Jenkins.Requester.Post(b.Base+"/stop", nil, nil, nil)
@@ -238,15 +217,6 @@ func (b *Build) GetCauses() ([]map[string]interface{}, error) {
return nil, errors.New("No Causes")
}
-func (b *Build) GetParameters() []parameter {
- for _, a := range b.Raw.Actions {
- if a.Parameters != nil {
- return a.Parameters
- }
- }
- return nil
-}
-
func (b *Build) GetInjectedEnvVars() (map[string]string, error) {
var envVars struct {
EnvMap map[string]string `json:"envMap"`
@@ -286,31 +256,6 @@ func (b *Build) GetDownstreamBuilds() ([]*Build, error) {
return result, nil
}
-func (b *Build) GetDownstreamJobNames() []string {
- result := make([]string, 0)
- downstreamJobs := b.Job.GetDownstreamJobsMetadata()
- fingerprints := b.GetAllFingerPrints()
- for _, fingerprint := range fingerprints {
- for _, usage := range fingerprint.Raw.Usage {
- for _, job := range downstreamJobs {
- if job.Name == usage.Name {
- result = append(result, job.Name)
- }
- }
- }
- }
- return result
-}
-
-func (b *Build) GetAllFingerPrints() []*FingerPrint {
- b.Poll(3)
- result := make([]*FingerPrint, len(b.Raw.FingerPrint))
- for i, f := range b.Raw.FingerPrint {
- result[i] = &FingerPrint{Jenkins: b.Jenkins, Base: "/fingerprint/", Id: f.Hash, Raw: &f}
- }
- return result
-}
-
func (b *Build) GetUpstreamJob() (*Job, error) {
causes, err := b.GetCauses()
if err != nil {
@@ -356,22 +301,6 @@ func (b *Build) GetUpstreamBuild() (*Build, error) {
return nil, errors.New("Build not found")
}
-func (b *Build) GetMatrixRuns() ([]*Build, error) {
- _, err := b.Poll(0)
- if err != nil {
- return nil, err
- }
- runs := b.Raw.Runs
- result := make([]*Build, len(b.Raw.Runs))
- r, _ := regexp.Compile(`job/(.*?)/(.*?)/(\d+)/`)
-
- for i, run := range runs {
- result[i] = &Build{Jenkins: b.Jenkins, Job: b.Job, Raw: new(BuildResponse), Depth: 1, Base: "/" + r.FindString(run.URL)}
- result[i].Poll()
- }
- return result, nil
-}
-
func (b *Build) GetResultSet() (*TestResult, error) {
url := b.Base + "/testReport"
@@ -395,24 +324,6 @@ func (b *Build) GetDuration() int64 {
return b.Raw.Duration
}
-func (b *Build) GetRevision() string {
- vcs := b.Raw.ChangeSet.Kind
-
- if vcs == Git || vcs == Hg {
- for _, a := range b.Raw.Actions {
- if a.LastBuiltRevision.SHA1 != "" {
- return a.LastBuiltRevision.SHA1
- }
- if a.MercurialRevisionNumber != "" {
- return a.MercurialRevisionNumber
- }
- }
- } else if vcs == Svn {
- return strconv.Itoa(b.Raw.ChangeSet.Revisions[0].Revision)
- }
- return ""
-}
-
func (b *Build) GetRevisionBranch() string {
vcs := b.Raw.ChangeSet.Kind
if vcs == Git {
@@ -456,7 +367,7 @@ func (b *Build) PauseToggle() error {
return nil
}
-// Poll for current data. Optional parameter - depth.
+// Poll for current data. Optional Parameter - depth.
// More about depth here: https://wiki.jenkins-ci.org/display/JENKINS/Remote+access+API
func (b *Build) Poll(options ...interface{}) (int, error) {
depth := "-1"
@@ -484,3 +395,20 @@ func (b *Build) Poll(options ...interface{}) (int, error) {
}
return response.StatusCode, nil
}
+
+func (j *Jenkins) GetProjectPipelineBuildByType(projectId, pipelineId string, status string) (*devops.Build, error) {
+ job, err := j.GetJob(pipelineId, projectId)
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ build, err := job.getBuildByType(status)
+ return build.Raw, nil
+}
+func (j *Jenkins) GetMultiBranchPipelineBuildByType(projectId, pipelineId, branch string, status string) (*devops.Build, error) {
+ job, err := j.GetJob(pipelineId, projectId, branch)
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ build, err := job.getBuildByType(status)
+ return build.Raw, nil
+}
diff --git a/pkg/gojenkins/constants.go b/pkg/simple/client/devops/jenkins/constants.go
similarity index 96%
rename from pkg/gojenkins/constants.go
rename to pkg/simple/client/devops/jenkins/constants.go
index 1876fb958f1f3509ae0b0750bae16cf2cd428d98..eee426b08e9d0ef300554287d9869b058153d300 100644
--- a/pkg/gojenkins/constants.go
+++ b/pkg/simple/client/devops/jenkins/constants.go
@@ -1,4 +1,4 @@
-package gojenkins
+package jenkins
const (
STATUS_FAIL = "FAIL"
diff --git a/pkg/simple/client/devops/jenkins/credential.go b/pkg/simple/client/devops/jenkins/credential.go
new file mode 100644
index 0000000000000000000000000000000000000000..e5dff570b0c3480e5926b1545e8fc7b93ad8cd8e
--- /dev/null
+++ b/pkg/simple/client/devops/jenkins/credential.go
@@ -0,0 +1,341 @@
+/*
+Copyright 2018 The KubeSphere Authors.
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+ http://www.apache.org/licenses/LICENSE-2.0
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+package jenkins
+
+import (
+ "errors"
+ "fmt"
+ "github.com/PuerkitoBio/goquery"
+ "github.com/emicklei/go-restful"
+ "k8s.io/klog"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "net/http"
+ "strconv"
+ "strings"
+)
+
+const SSHCrenditalStaplerClass = "com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey"
+const DirectSSHCrenditalStaplerClass = "com.cloudbees.jenkins.plugins.sshcredentials.impl.BasicSSHUserPrivateKey$DirectEntryPrivateKeySource"
+const UsernamePassswordCredentialStaplerClass = "com.cloudbees.plugins.credentials.impl.UsernamePasswordCredentialsImpl"
+const SecretTextCredentialStaplerClass = "org.jenkinsci.plugins.plaincredentials.impl.StringCredentialsImpl"
+const KubeconfigCredentialStaplerClass = "com.microsoft.jenkins.kubernetes.credentials.KubeconfigCredentials"
+const DirectKubeconfigCredentialStaperClass = "com.microsoft.jenkins.kubernetes.credentials.KubeconfigCredentials$DirectEntryKubeconfigSource"
+const GLOBALScope = "GLOBAL"
+
+type UsernamePasswordCredential struct {
+ Scope string `json:"scope"`
+ Id string `json:"id"`
+ Username string `json:"username"`
+ Password string `json:"password"`
+ Description string `json:"description"`
+ StaplerClass string `json:"stapler-class"`
+}
+
+type SshCredential struct {
+ Scope string `json:"scope"`
+ Id string `json:"id"`
+ Username string `json:"username"`
+ Passphrase string `json:"passphrase"`
+ KeySource PrivateKeySource `json:"privateKeySource"`
+ Description string `json:"description"`
+ StaplerClass string `json:"stapler-class"`
+}
+
+type SecretTextCredential struct {
+ Scope string `json:"scope"`
+ Id string `json:"id"`
+ Secret string `json:"secret"`
+ Description string `json:"description"`
+ StaplerClass string `json:"stapler-class"`
+}
+
+type KubeconfigCredential struct {
+ Scope string `json:"scope"`
+ Id string `json:"id"`
+ Description string `json:"description"`
+ KubeconfigSource KubeconfigSource `json:"kubeconfigSource"`
+ StaplerClass string `json:"stapler-class"`
+}
+
+type PrivateKeySource struct {
+ StaplerClass string `json:"stapler-class"`
+ PrivateKey string `json:"privateKey"`
+}
+
+type KubeconfigSource struct {
+ StaplerClass string `json:"stapler-class"`
+ Content string `json:"content"`
+}
+
+type CredentialResponse struct {
+ Id string `json:"id"`
+ TypeName string `json:"typeName"`
+ DisplayName string `json:"displayName"`
+ Fingerprint *struct {
+ FileName string `json:"file_name,omitempty" description:"Credential's display name and description"`
+ Hash string `json:"hash,omitempty" description:"Credential's hash"`
+ Usage []*struct {
+ Name string `json:"name,omitempty" description:"Jenkins pipeline full name"`
+ Ranges struct {
+ Ranges []*struct {
+ Start int `json:"start,omitempty" description:"Start build number"`
+ End int `json:"end,omitempty" description:"End build number"`
+ } `json:"ranges,omitempty"`
+ } `json:"ranges,omitempty" description:"The build number of all pipelines that use this credential"`
+ } `json:"usage,omitempty" description:"all usage of Credential"`
+ } `json:"fingerprint,omitempty" description:"usage of the Credential"`
+ Description string `json:"description,omitempty"`
+ Domain string `json:"domain"`
+}
+
+func NewSshCredential(id, username, passphrase, privateKey, description string) *SshCredential {
+ keySource := PrivateKeySource{
+ StaplerClass: DirectSSHCrenditalStaplerClass,
+ PrivateKey: privateKey,
+ }
+
+ return &SshCredential{
+ Scope: GLOBALScope,
+ Id: id,
+ Username: username,
+ Passphrase: passphrase,
+ KeySource: keySource,
+ Description: description,
+ StaplerClass: SSHCrenditalStaplerClass,
+ }
+}
+
+func NewUsernamePasswordCredential(id, username, password, description string) *UsernamePasswordCredential {
+ return &UsernamePasswordCredential{
+ Scope: GLOBALScope,
+ Id: id,
+ Username: username,
+ Password: password,
+ Description: description,
+ StaplerClass: UsernamePassswordCredentialStaplerClass,
+ }
+}
+
+func NewSecretTextCredential(id, secret, description string) *SecretTextCredential {
+ return &SecretTextCredential{
+ Scope: GLOBALScope,
+ Id: id,
+ Secret: secret,
+ Description: description,
+ StaplerClass: SecretTextCredentialStaplerClass,
+ }
+}
+
+func NewKubeconfigCredential(id, content, description string) *KubeconfigCredential {
+ credentialSource := KubeconfigSource{
+ StaplerClass: DirectKubeconfigCredentialStaperClass,
+ Content: content,
+ }
+
+ return &KubeconfigCredential{
+ Scope: GLOBALScope,
+ Id: id,
+ Description: description,
+ KubeconfigSource: credentialSource,
+ StaplerClass: KubeconfigCredentialStaplerClass,
+ }
+}
+
+func (j *Jenkins) GetCredentialInProject(projectId, id string, content bool) (*devops.Credential, error) {
+ responseStruct := &devops.Credential{}
+
+ domain := "_"
+
+ response, err := j.Requester.GetJSON(
+ fmt.Sprintf("/job/%s/credentials/store/folder/domain/_/credential/%s", projectId, id),
+ responseStruct, map[string]string{
+ "depth": "2",
+ })
+ if err != nil {
+ return nil, err
+ }
+ if response.StatusCode != http.StatusOK {
+ return nil, errors.New(strconv.Itoa(response.StatusCode))
+ }
+ responseStruct.Domain = domain
+ if content {
+
+ }
+ contentString := ""
+ response, err = j.Requester.GetHtml(
+ fmt.Sprintf("/job/%s/credentials/store/folder/domain/%s/credential/%s/update", projectId, domain, id),
+ &contentString, nil)
+ if err != nil {
+ return nil, err
+ }
+ if response.StatusCode != http.StatusOK {
+ return nil, errors.New(strconv.Itoa(response.StatusCode))
+ }
+ stringReader := strings.NewReader(contentString)
+ doc, err := goquery.NewDocumentFromReader(stringReader)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ return nil, restful.NewError(http.StatusInternalServerError, err.Error())
+ }
+ switch responseStruct.Type {
+ case devops.CredentialTypeKubeConfig:
+ content := &devops.KubeconfigCredential{}
+ doc.Find("textarea[name*=content]").Each(func(i int, selection *goquery.Selection) {
+ value := selection.Text()
+ content.Content = value
+ })
+ responseStruct.KubeconfigCredential = content
+ case devops.CredentialTypeUsernamePassword:
+ content := &devops.UsernamePasswordCredential{}
+ doc.Find("input[name*=username]").Each(func(i int, selection *goquery.Selection) {
+ value, _ := selection.Attr("value")
+ content.Username = value
+ })
+
+ responseStruct.UsernamePasswordCredential = content
+ case devops.CredentialTypeSsh:
+ content := &devops.SshCredential{}
+ doc.Find("input[name*=username]").Each(func(i int, selection *goquery.Selection) {
+ value, _ := selection.Attr("value")
+ content.Username = value
+ })
+
+ doc.Find("textarea[name*=privateKey]").Each(func(i int, selection *goquery.Selection) {
+ value := selection.Text()
+ content.PrivateKey = value
+ })
+ responseStruct.SshCredential = content
+ }
+ return responseStruct, nil
+}
+
+func (j *Jenkins) GetCredentialsInProject(projectId string) ([]*devops.Credential, error) {
+ domain := "_"
+ var responseStruct = &struct {
+ Credentials []*devops.Credential `json:"credentials"`
+ }{}
+ response, err := j.Requester.GetJSON(
+ fmt.Sprintf("/job/%s/credentials/store/folder/domain/_", projectId),
+ responseStruct, map[string]string{
+ "depth": "2",
+ })
+ if err != nil {
+ return nil, err
+ }
+ if response.StatusCode != http.StatusOK {
+ return nil, errors.New(strconv.Itoa(response.StatusCode))
+ }
+ for _, credential := range responseStruct.Credentials {
+ credential.Domain = domain
+ }
+ return responseStruct.Credentials, nil
+
+}
+
+func (j *Jenkins) CreateCredentialInProject(projectId string, credential *devops.Credential) (*string, error) {
+
+ var request interface{}
+ responseString := ""
+ switch credential.Type {
+ case devops.CredentialTypeUsernamePassword:
+ request = NewUsernamePasswordCredential(credential.Id,
+ credential.UsernamePasswordCredential.Username, credential.UsernamePasswordCredential.Password,
+ credential.Description)
+
+ case devops.CredentialTypeSsh:
+ request = NewSshCredential(credential.Id,
+ credential.SshCredential.Username, credential.SshCredential.Passphrase,
+ credential.SshCredential.PrivateKey, credential.Description)
+ case devops.CredentialTypeSecretText:
+ request = NewSecretTextCredential(credential.Id,
+ credential.SecretTextCredential.Secret, credential.Description)
+ case devops.CredentialTypeKubeConfig:
+ request = NewKubeconfigCredential(credential.Id,
+ credential.KubeconfigCredential.Content, credential.Description)
+ default:
+ err := fmt.Errorf("error unsupport credential type")
+ klog.Errorf("%+v", err)
+ return nil, restful.NewError(http.StatusBadRequest, err.Error())
+ }
+
+ response, err := j.Requester.Post(
+ fmt.Sprintf("/job/%s/credentials/store/folder/domain/_/createCredentials", projectId),
+ nil, &responseString, map[string]string{
+ "json": makeJson(map[string]interface{}{
+ "credentials": request,
+ }),
+ })
+ if err != nil {
+ return nil, err
+ }
+ if response.StatusCode != http.StatusOK {
+ return nil, errors.New(strconv.Itoa(response.StatusCode))
+ }
+ return &credential.Id, nil
+}
+
+func (j *Jenkins) UpdateCredentialInProject(projectId string, credential *devops.Credential) (*string, error) {
+
+ requestContent := ""
+ switch credential.Type {
+ case devops.CredentialTypeUsernamePassword:
+ requestStruct := NewUsernamePasswordCredential(credential.Id,
+ credential.UsernamePasswordCredential.Username, credential.UsernamePasswordCredential.Password,
+ credential.Description)
+ requestContent = makeJson(requestStruct)
+
+ case devops.CredentialTypeSsh:
+ requestStruct := NewSshCredential(credential.Id,
+ credential.SshCredential.Username, credential.SshCredential.Passphrase,
+ credential.SshCredential.PrivateKey, credential.Description)
+ requestContent = makeJson(requestStruct)
+ case devops.CredentialTypeSecretText:
+ requestStruct := NewSecretTextCredential(credential.Id,
+ credential.SecretTextCredential.Secret, credential.Description)
+ requestContent = makeJson(requestStruct)
+ case devops.CredentialTypeKubeConfig:
+ requestStruct := NewKubeconfigCredential(credential.Id,
+ credential.KubeconfigCredential.Content, credential.Description)
+ requestContent = makeJson(requestStruct)
+ default:
+ err := fmt.Errorf("error unsupport credential type")
+ klog.Errorf("%+v", err)
+ return nil, restful.NewError(http.StatusBadRequest, err.Error())
+ }
+ response, err := j.Requester.Post(
+ fmt.Sprintf("/job/%s/credentials/store/folder/domain/_/credential/%s/updateSubmit", projectId, credential.Id),
+ nil, nil, map[string]string{
+ "json": requestContent,
+ })
+ if err != nil {
+ return nil, err
+ }
+ if response.StatusCode != http.StatusOK {
+ return nil, errors.New(strconv.Itoa(response.StatusCode))
+ }
+ return &credential.Id, nil
+}
+
+func (j *Jenkins) DeleteCredentialInProject(projectId, id string) (*string, error) {
+ response, err := j.Requester.Post(
+ fmt.Sprintf("/job/%s/credentials/store/folder/domain/_/credential/%s/doDelete", projectId, id),
+ nil, nil, nil)
+ if err != nil {
+ return nil, err
+ }
+ if response.StatusCode != http.StatusOK {
+ return nil, errors.New(strconv.Itoa(response.StatusCode))
+ }
+ return &id, nil
+}
diff --git a/pkg/simple/client/devops/devops.go b/pkg/simple/client/devops/jenkins/devops.go
similarity index 81%
rename from pkg/simple/client/devops/devops.go
rename to pkg/simple/client/devops/jenkins/devops.go
index 90c03ae613e21d22804e78f9e5b1f50f52acbb8c..6c439110166cae01b1dfc5d3a3f01d4e35625f64 100644
--- a/pkg/simple/client/devops/devops.go
+++ b/pkg/simple/client/devops/jenkins/devops.go
@@ -11,12 +11,11 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-package devops
+package jenkins
import (
"fmt"
"k8s.io/klog"
- "kubesphere.io/kubesphere/pkg/gojenkins"
"sync"
)
@@ -25,13 +24,13 @@ const (
)
type Client struct {
- jenkinsClient *gojenkins.Jenkins
+ jenkinsClient *Jenkins
}
func NewDevopsClient(options *Options) (*Client, error) {
var d Client
- jenkins := gojenkins.CreateJenkins(nil, options.Host, options.MaxConnections, options.Username, options.Password)
+ jenkins := CreateJenkins(nil, options.Host, options.MaxConnections, options.Username, options.Password)
jenkins, err := jenkins.Init()
if err != nil {
klog.Errorf("failed to connecto to jenkins role, %+v", err)
@@ -49,7 +48,7 @@ func NewDevopsClient(options *Options) (*Client, error) {
return &d, nil
}
-func (c *Client) Jenkins() *gojenkins.Jenkins {
+func (c *Client) Jenkins() *Jenkins {
return c.jenkinsClient
}
@@ -71,14 +70,14 @@ func (c *Client) initializeJenkins() error {
// Jenkins uninitialized, create global role
if globalRole == nil {
- _, err := c.jenkinsClient.AddGlobalRole(jenkinsAllUserRoleName, gojenkins.GlobalPermissionIds{GlobalRead: true}, true)
+ _, err := c.jenkinsClient.AddGlobalRole(jenkinsAllUserRoleName, GlobalPermissionIds{GlobalRead: true}, true)
if err != nil {
klog.Error(err)
return err
}
}
- _, err = c.jenkinsClient.AddProjectRole(jenkinsAllUserRoleName, "\\n\\s*\\r", gojenkins.ProjectPermissionIds{SCMTag: true}, true)
+ _, err = c.jenkinsClient.AddProjectRole(jenkinsAllUserRoleName, "\\n\\s*\\r", ProjectPermissionIds{SCMTag: true}, true)
if err != nil {
klog.Error(err)
return err
diff --git a/pkg/simple/client/devops/jenkins/devops_test.go b/pkg/simple/client/devops/jenkins/devops_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..bd11e5d6469c6d148a25c0c83d28257d6ccaed6b
--- /dev/null
+++ b/pkg/simple/client/devops/jenkins/devops_test.go
@@ -0,0 +1,40 @@
+package jenkins
+
+import (
+ "testing"
+)
+
+func Test_parseCronJobTime(t *testing.T) {
+ type Except struct {
+ Last string
+ Next string
+ }
+
+ Items := []struct {
+ Input string
+ Expected Except
+ }{
+ {"上次运行的时间 Tuesday, September 10, 2019 8:59:09 AM UTC; 下次运行的时间 Tuesday, September 10, 2019 9:14:09 AM UTC.", Except{Last: "2019-09-10T08:59:09Z", Next: "2019-09-10T09:14:09Z"}},
+ {"上次运行的时间 Thursday, January 3, 2019 11:56:30 PM UTC; 下次运行的时间 Friday, January 3, 2020 12:11:30 AM UTC.", Except{Last: "2019-01-03T23:56:30Z", Next: "2020-01-03T00:11:30Z"}},
+ {"上次运行的时间 Tuesday, September 10, 2019 8:41:34 AM UTC; 下次运行的时间 Tuesday, September 10, 2019 9:41:34 AM UTC.", Except{Last: "2019-09-10T08:41:34Z", Next: "2019-09-10T09:41:34Z"}},
+ {"上次运行的时间 Tuesday, September 10, 2019 9:15:26 AM UTC; 下次运行的时间 Tuesday, September 10, 2019 10:03:26 AM UTC.", Except{Last: "2019-09-10T09:15:26Z", Next: "2019-09-10T10:03:26Z"}},
+ {"Would last have run at Tuesday, September 10, 2019 9:15:26 AM UTC; would next run at Tuesday, September 10, 2019 10:03:26 AM UTC.", Except{Last: "2019-09-10T09:15:26Z", Next: "2019-09-10T10:03:26Z"}},
+ {"Would last have run at Tuesday, September 10, 2019 8:41:34 AM UTC; would next run at Tuesday, September 10, 2019 9:41:34 AM UTC.", Except{Last: "2019-09-10T08:41:34Z", Next: "2019-09-10T09:41:34Z"}},
+ }
+
+ for _, item := range Items {
+ last, next, err := parseCronJobTime(item.Input)
+ if err != nil {
+ t.Fatalf("should not get error %+v", err)
+ }
+
+ if last != item.Expected.Last {
+ t.Errorf("got %#v, expected %#v", last, item.Expected.Last)
+ }
+
+ if next != item.Expected.Next {
+ t.Errorf("got %#v, expected %#v", next, item.Expected.Next)
+ }
+
+ }
+}
diff --git a/pkg/gojenkins/folder.go b/pkg/simple/client/devops/jenkins/folder.go
similarity index 94%
rename from pkg/gojenkins/folder.go
rename to pkg/simple/client/devops/jenkins/folder.go
index 053a8ef332882a996e91778a493373b9a2f663f4..1646f6c81bb5c3f34dd73f8f437ce206570cc8ee 100644
--- a/pkg/gojenkins/folder.go
+++ b/pkg/simple/client/devops/jenkins/folder.go
@@ -12,7 +12,7 @@
// License for the specific language governing permissions and limitations
// under the License.
-package gojenkins
+package jenkins
import (
"errors"
@@ -33,8 +33,6 @@ type FolderResponse struct {
Name string `json:"name"`
URL string `json:"url"`
Jobs []InnerJob `json:"jobs"`
- PrimaryView *ViewData `json:"primaryView"`
- Views []ViewData `json:"views"`
}
func (f *Folder) parentBase() string {
diff --git a/pkg/simple/client/devops/jenkins/jenkins.go b/pkg/simple/client/devops/jenkins/jenkins.go
new file mode 100644
index 0000000000000000000000000000000000000000..c8ca746fd129fb86fdd073a4ff0f9e8d7e8d2a81
--- /dev/null
+++ b/pkg/simple/client/devops/jenkins/jenkins.go
@@ -0,0 +1,803 @@
+// Copyright 2015 Vadim Kravcenko
+//
+// Licensed under the Apache License, Version 2.0 (the "License"): you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+// Gojenkins is a Jenkins Client in Go, that exposes the jenkins REST api in a more developer friendly way.
+package jenkins
+
+import (
+ "encoding/json"
+ "errors"
+ "fmt"
+ "io"
+ "io/ioutil"
+ "k8s.io/klog"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "log"
+ "net/http"
+ "os"
+ "reflect"
+ "strconv"
+ "strings"
+)
+
+// Basic Authentication
+type BasicAuth struct {
+ Username string
+ Password string
+}
+
+type Jenkins struct {
+ Server string
+ Version string
+ Requester *Requester
+}
+
+// Loggers
+var (
+ Info *log.Logger
+ Warning *log.Logger
+ Error *log.Logger
+)
+
+// Init Method. Should be called after creating a Jenkins Instance.
+// e.g jenkins := CreateJenkins("url").Init()
+// HTTP Client is set here, Connection to jenkins is tested here.
+func (j *Jenkins) Init() (*Jenkins, error) {
+ j.initLoggers()
+
+ rsp, err := j.Requester.GetJSON("/", nil, nil)
+ if err != nil {
+ return nil, err
+ }
+
+ j.Version = rsp.Header.Get("X-Jenkins")
+ //if j.Raw == nil {
+ // return nil, errors.New("Connection Failed, Please verify that the host and credentials are correct.")
+ //}
+
+ return j, nil
+}
+
+func (j *Jenkins) initLoggers() {
+ Info = log.New(os.Stdout,
+ "INFO: ",
+ log.Ldate|log.Ltime|log.Lshortfile)
+
+ Warning = log.New(os.Stdout,
+ "WARNING: ",
+ log.Ldate|log.Ltime|log.Lshortfile)
+
+ Error = log.New(os.Stderr,
+ "ERROR: ",
+ log.Ldate|log.Ltime|log.Lshortfile)
+}
+
+// Create a new folder
+// This folder can be nested in other parent folders
+// Example: jenkins.CreateFolder("newFolder", "grandparentFolder", "parentFolder")
+func (j *Jenkins) CreateFolder(name, description string, parents ...string) (*Folder, error) {
+ folderObj := &Folder{Jenkins: j, Raw: new(FolderResponse), Base: "/job/" + strings.Join(append(parents, name), "/job/")}
+ folder, err := folderObj.Create(name, description)
+ if err != nil {
+ return nil, err
+ }
+ return folder, nil
+}
+
+// Create a new job in the folder
+// Example: jenkins.CreateJobInFolder("", "newJobName", "myFolder", "parentFolder")
+func (j *Jenkins) CreateJobInFolder(config string, jobName string, parentIDs ...string) (*Job, error) {
+ jobObj := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + strings.Join(append(parentIDs, jobName), "/job/")}
+ qr := map[string]string{
+ "name": jobName,
+ }
+ job, err := jobObj.Create(config, qr)
+ if err != nil {
+ return nil, err
+ }
+ return job, nil
+}
+
+// Create a new job from config File
+// Method takes XML string as first Parameter, and if the name is not specified in the config file
+// takes name as string as second Parameter
+// e.g jenkins.CreateJob("","newJobName")
+func (j *Jenkins) CreateJob(config string, options ...interface{}) (*Job, error) {
+ qr := make(map[string]string)
+ if len(options) > 0 {
+ qr["name"] = options[0].(string)
+ } else {
+ return nil, errors.New("Error Creating Job, job name is missing")
+ }
+ jobObj := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + qr["name"]}
+ job, err := jobObj.Create(config, qr)
+ if err != nil {
+ return nil, err
+ }
+ return job, nil
+}
+
+// Rename a job.
+// First Parameter job old name, Second Parameter job new name.
+func (j *Jenkins) RenameJob(job string, name string) *Job {
+ jobObj := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + job}
+ jobObj.Rename(name)
+ return &jobObj
+}
+
+// Create a copy of a job.
+// First Parameter Name of the job to copy from, Second Parameter new job name.
+func (j *Jenkins) CopyJob(copyFrom string, newName string) (*Job, error) {
+ job := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + copyFrom}
+ _, err := job.Poll()
+ if err != nil {
+ return nil, err
+ }
+ return job.Copy(newName)
+}
+
+// Delete a job.
+func (j *Jenkins) DeleteJob(name string, parentIDs ...string) (bool, error) {
+ job := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + strings.Join(append(parentIDs, name), "/job/")}
+ return job.Delete()
+}
+
+// Invoke a job.
+// First Parameter job name, second Parameter is optional Build parameters.
+func (j *Jenkins) BuildJob(name string, options ...interface{}) (int64, error) {
+ job := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + name}
+ var params map[string]string
+ if len(options) > 0 {
+ params, _ = options[0].(map[string]string)
+ }
+ return job.InvokeSimple(params)
+}
+
+func (j *Jenkins) GetBuild(jobName string, number int64) (*Build, error) {
+ job, err := j.GetJob(jobName)
+ if err != nil {
+ return nil, err
+ }
+ build, err := job.GetBuild(number)
+
+ if err != nil {
+ return nil, err
+ }
+ return build, nil
+}
+
+func (j *Jenkins) GetJob(id string, parentIDs ...string) (*Job, error) {
+ job := Job{Jenkins: j, Raw: new(JobResponse), Base: "/job/" + strings.Join(append(parentIDs, id), "/job/")}
+ status, err := job.Poll()
+ if err != nil {
+ return nil, err
+ }
+ if status == 200 {
+ return &job, nil
+ }
+ return nil, errors.New(strconv.Itoa(status))
+}
+
+func (j *Jenkins) GetFolder(id string, parents ...string) (*Folder, error) {
+ folder := Folder{Jenkins: j, Raw: new(FolderResponse), Base: "/job/" + strings.Join(append(parents, id), "/job/")}
+ status, err := folder.Poll()
+ if err != nil {
+ return nil, fmt.Errorf("trouble polling folder: %v", err)
+ }
+ if status == 200 {
+ return &folder, nil
+ }
+ return nil, errors.New(strconv.Itoa(status))
+}
+
+// Get all builds Numbers and URLS for a specific job.
+// There are only build IDs here,
+// To get all the other info of the build use jenkins.GetBuild(job,buildNumber)
+// or job.GetBuild(buildNumber)
+
+func (j *Jenkins) Poll() (int, error) {
+ resp, err := j.Requester.GetJSON("/", nil, nil)
+ if err != nil {
+ return 0, err
+ }
+ return resp.StatusCode, nil
+}
+
+func (j *Jenkins) GetGlobalRole(roleName string) (*GlobalRole, error) {
+ roleResponse := &GlobalRoleResponse{
+ RoleName: roleName,
+ }
+ stringResponse := ""
+ response, err := j.Requester.Get("/role-strategy/strategy/getRole",
+ &stringResponse,
+ map[string]string{
+ "roleName": roleName,
+ "type": GLOBAL_ROLE,
+ })
+ if err != nil {
+ return nil, err
+ }
+ if response.StatusCode != http.StatusOK {
+ return nil, errors.New(strconv.Itoa(response.StatusCode))
+ }
+ if stringResponse == "{}" {
+ return nil, nil
+ }
+ err = json.Unmarshal([]byte(stringResponse), roleResponse)
+ if err != nil {
+ return nil, err
+ }
+ return &GlobalRole{
+ Jenkins: j,
+ Raw: *roleResponse,
+ }, nil
+}
+
+func (j *Jenkins) GetProjectRole(roleName string) (*ProjectRole, error) {
+ roleResponse := &ProjectRoleResponse{
+ RoleName: roleName,
+ }
+ stringResponse := ""
+ response, err := j.Requester.Get("/role-strategy/strategy/getRole",
+ &stringResponse,
+ map[string]string{
+ "roleName": roleName,
+ "type": PROJECT_ROLE,
+ })
+ if err != nil {
+ return nil, err
+ }
+ if response.StatusCode != http.StatusOK {
+ return nil, errors.New(strconv.Itoa(response.StatusCode))
+ }
+ if stringResponse == "{}" {
+ return nil, nil
+ }
+ err = json.Unmarshal([]byte(stringResponse), roleResponse)
+ if err != nil {
+ return nil, err
+ }
+ return &ProjectRole{
+ Jenkins: j,
+ Raw: *roleResponse,
+ }, nil
+}
+
+func (j *Jenkins) AddGlobalRole(roleName string, ids GlobalPermissionIds, overwrite bool) (*GlobalRole, error) {
+ responseRole := &GlobalRole{
+ Jenkins: j,
+ Raw: GlobalRoleResponse{
+ RoleName: roleName,
+ PermissionIds: ids,
+ }}
+ var idArray []string
+ values := reflect.ValueOf(ids)
+ for i := 0; i < values.NumField(); i++ {
+ field := values.Field(i)
+ if field.Bool() {
+ idArray = append(idArray, values.Type().Field(i).Tag.Get("json"))
+ }
+ }
+ param := map[string]string{
+ "roleName": roleName,
+ "type": GLOBAL_ROLE,
+ "permissionIds": strings.Join(idArray, ","),
+ "overwrite": strconv.FormatBool(overwrite),
+ }
+ responseString := ""
+ response, err := j.Requester.Post("/role-strategy/strategy/addRole", nil, &responseString, param)
+ if err != nil {
+ return nil, err
+ }
+ if response.StatusCode != http.StatusOK {
+ return nil, errors.New(strconv.Itoa(response.StatusCode))
+ }
+ return responseRole, nil
+}
+
+func (j *Jenkins) DeleteProjectRoles(roleName ...string) error {
+ responseString := ""
+
+ response, err := j.Requester.Post("/role-strategy/strategy/removeRoles", nil, &responseString, map[string]string{
+ "type": PROJECT_ROLE,
+ "roleNames": strings.Join(roleName, ","),
+ })
+ if err != nil {
+ return err
+ }
+ if response.StatusCode != http.StatusOK {
+ fmt.Println(responseString)
+ return errors.New(strconv.Itoa(response.StatusCode))
+ }
+ return nil
+}
+
+func (j *Jenkins) AddProjectRole(roleName string, pattern string, ids ProjectPermissionIds, overwrite bool) (*ProjectRole, error) {
+ responseRole := &ProjectRole{
+ Jenkins: j,
+ Raw: ProjectRoleResponse{
+ RoleName: roleName,
+ PermissionIds: ids,
+ Pattern: pattern,
+ }}
+ var idArray []string
+ values := reflect.ValueOf(ids)
+ for i := 0; i < values.NumField(); i++ {
+ field := values.Field(i)
+ if field.Bool() {
+ idArray = append(idArray, values.Type().Field(i).Tag.Get("json"))
+ }
+ }
+ param := map[string]string{
+ "roleName": roleName,
+ "type": PROJECT_ROLE,
+ "permissionIds": strings.Join(idArray, ","),
+ "overwrite": strconv.FormatBool(overwrite),
+ "pattern": pattern,
+ }
+ responseString := ""
+ response, err := j.Requester.Post("/role-strategy/strategy/addRole", nil, &responseString, param)
+ if err != nil {
+ return nil, err
+ }
+ if response.StatusCode != http.StatusOK {
+ return nil, errors.New(strconv.Itoa(response.StatusCode))
+ }
+ return responseRole, nil
+}
+
+func (j *Jenkins) DeleteUserInProject(username string) error {
+ param := map[string]string{
+ "type": PROJECT_ROLE,
+ "sid": username,
+ }
+ responseString := ""
+ response, err := j.Requester.Post("/role-strategy/strategy/deleteSid", nil, &responseString, param)
+ if err != nil {
+ return err
+ }
+ if response.StatusCode != http.StatusOK {
+ return errors.New(strconv.Itoa(response.StatusCode))
+ }
+ return nil
+}
+
+func (j *Jenkins) GetPipeline(projectName, pipelineName string, httpParameters *devops.HttpParameters) (*devops.Pipeline, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(GetPipelineUrl, projectName, pipelineName),
+ }
+ res, err := PipelineOjb.GetPipeline()
+ return res, err
+}
+
+func (j *Jenkins) ListPipelines(httpParameters *devops.HttpParameters) (*devops.PipelineList, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: ListPipelinesUrl + httpParameters.Url.RawQuery,
+ }
+ res, err := PipelineOjb.ListPipelines()
+ return res, err
+}
+
+func (j *Jenkins) GetPipelineRun(projectName, pipelineName, runId string, httpParameters *devops.HttpParameters) (*devops.PipelineRun, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(GetPipelineRunUrl, projectName, pipelineName, runId),
+ }
+ res, err := PipelineOjb.GetPipelineRun()
+ return res, err
+}
+
+func (j *Jenkins) ListPipelineRuns(projectName, pipelineName string, httpParameters *devops.HttpParameters) (*devops.PipelineRunList, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: ListPipelineRunUrl + httpParameters.Url.RawQuery,
+ }
+ res, err := PipelineOjb.ListPipelineRuns()
+ return res, err
+}
+
+func (j *Jenkins) StopPipeline(projectName, pipelineName, runId string, httpParameters *devops.HttpParameters) (*devops.StopPipeline, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(StopPipelineUrl, projectName, pipelineName, runId),
+ }
+ res, err := PipelineOjb.StopPipeline()
+ return res, err
+}
+
+func (j *Jenkins) ReplayPipeline(projectName, pipelineName, runId string, httpParameters *devops.HttpParameters) (*devops.ReplayPipeline, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(ReplayPipelineUrl+httpParameters.Url.RawQuery, projectName, pipelineName, runId),
+ }
+ res, err := PipelineOjb.ReplayPipeline()
+ return res, err
+}
+
+func (j *Jenkins) RunPipeline(projectName, pipelineName string, httpParameters *devops.HttpParameters) (*devops.RunPipeline, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(RunPipelineUrl+httpParameters.Url.RawQuery, projectName, pipelineName),
+ }
+ res, err := PipelineOjb.RunPipeline()
+ return res, err
+}
+
+func (j *Jenkins) GetArtifacts(projectName, pipelineName, runId string, httpParameters *devops.HttpParameters) ([]devops.Artifacts, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(GetArtifactsUrl+httpParameters.Url.RawQuery, projectName, pipelineName, runId),
+ }
+ res, err := PipelineOjb.GetArtifacts()
+ return res, err
+}
+
+func (j *Jenkins) GetRunLog(projectName, pipelineName, runId string, httpParameters *devops.HttpParameters) ([]byte, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(GetRunLogUrl+httpParameters.Url.RawQuery, projectName, pipelineName, runId),
+ }
+ res, err := PipelineOjb.GetRunLog()
+ return res, err
+}
+
+func (j *Jenkins) GetStepLog(projectName, pipelineName, runId, nodeId, stepId string, httpParameters *devops.HttpParameters) ([]byte, http.Header, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(GetStepLogUrl+httpParameters.Url.RawQuery, projectName, pipelineName, runId, nodeId, stepId),
+ }
+ res, header, err := PipelineOjb.GetStepLog()
+ return res, header, err
+}
+
+func (j *Jenkins) GetNodeSteps(projectName, pipelineName, runId, nodeId string, httpParameters *devops.HttpParameters) ([]devops.NodeSteps, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(GetNodeStepsUrl+httpParameters.Url.RawQuery, projectName, pipelineName, runId, nodeId),
+ }
+ res, err := PipelineOjb.GetNodeSteps()
+ return res, err
+}
+
+func (j *Jenkins) GetPipelineRunNodes(projectName, pipelineName, runId string, httpParameters *devops.HttpParameters) ([]devops.PipelineRunNodes, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(GetPipelineRunNodesUrl+httpParameters.Url.RawQuery, projectName, pipelineName, runId),
+ }
+ res, err := PipelineOjb.GetPipelineRunNodes()
+ return res, err
+}
+
+func (j *Jenkins) SubmitInputStep(projectName, pipelineName, runId, nodeId, stepId string, httpParameters *devops.HttpParameters) ([]byte, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(SubmitInputStepUrl+httpParameters.Url.RawQuery, projectName, pipelineName, runId, nodeId, stepId),
+ }
+ res, err := PipelineOjb.SubmitInputStep()
+ return res, err
+}
+
+func (j *Jenkins) GetBranchPipeline(projectName, pipelineName, branchName string, httpParameters *devops.HttpParameters) (*devops.BranchPipeline, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(GetBranchPipelineUrl, projectName, pipelineName, branchName),
+ }
+ res, err := PipelineOjb.GetBranchPipeline()
+ return res, err
+}
+
+func (j *Jenkins) GetBranchPipelineRun(projectName, pipelineName, branchName, runId string, httpParameters *devops.HttpParameters) (*devops.PipelineRun, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(GetBranchPipelineRunUrl, projectName, pipelineName, branchName, runId),
+ }
+ res, err := PipelineOjb.GetBranchPipelineRun()
+ return res, err
+}
+
+func (j *Jenkins) StopBranchPipeline(projectName, pipelineName, branchName, runId string, httpParameters *devops.HttpParameters) (*devops.StopPipeline, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(StopBranchPipelineUrl+httpParameters.Url.RawQuery, projectName, pipelineName, branchName, runId),
+ }
+ res, err := PipelineOjb.StopBranchPipeline()
+ return res, err
+}
+
+func (j *Jenkins) ReplayBranchPipeline(projectName, pipelineName, branchName, runId string, httpParameters *devops.HttpParameters) (*devops.ReplayPipeline, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(ReplayBranchPipelineUrl+httpParameters.Url.RawQuery, projectName, pipelineName, branchName, runId),
+ }
+ res, err := PipelineOjb.ReplayBranchPipeline()
+ return res, err
+}
+
+func (j *Jenkins) RunBranchPipeline(projectName, pipelineName, branchName string, httpParameters *devops.HttpParameters) (*devops.RunPipeline, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(RunBranchPipelineUrl+httpParameters.Url.RawQuery, projectName, pipelineName, branchName),
+ }
+ res, err := PipelineOjb.RunBranchPipeline()
+ return res, err
+}
+
+func (j *Jenkins) GetBranchArtifacts(projectName, pipelineName, branchName, runId string, httpParameters *devops.HttpParameters) ([]devops.Artifacts, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(GetBranchArtifactsUrl+httpParameters.Url.RawQuery, projectName, pipelineName, branchName, runId),
+ }
+ res, err := PipelineOjb.GetBranchArtifacts()
+ return res, err
+}
+
+func (j *Jenkins) GetBranchRunLog(projectName, pipelineName, branchName, runId string, httpParameters *devops.HttpParameters) ([]byte, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(GetBranchRunLogUrl+httpParameters.Url.RawQuery, projectName, pipelineName, branchName, runId),
+ }
+ res, err := PipelineOjb.GetBranchRunLog()
+ return res, err
+}
+
+func (j *Jenkins) GetBranchStepLog(projectName, pipelineName, branchName, runId, nodeId, stepId string, httpParameters *devops.HttpParameters) ([]byte, http.Header, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(GetBranchStepLogUrl+httpParameters.Url.RawQuery, projectName, pipelineName, branchName, runId, nodeId, stepId),
+ }
+ res, header, err := PipelineOjb.GetBranchStepLog()
+ return res, header, err
+}
+
+func (j *Jenkins) GetBranchNodeSteps(projectName, pipelineName, branchName, runId, nodeId string, httpParameters *devops.HttpParameters) ([]devops.NodeSteps, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(GetBranchNodeStepsUrl+httpParameters.Url.RawQuery, projectName, pipelineName, branchName, runId, nodeId),
+ }
+ res, err := PipelineOjb.GetBranchNodeSteps()
+ return res, err
+}
+
+func (j *Jenkins) GetBranchPipelineRunNodes(projectName, pipelineName, branchName, runId string, httpParameters *devops.HttpParameters) ([]devops.BranchPipelineRunNodes, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(GetBranchPipeRunNodesUrl+httpParameters.Url.RawQuery, projectName, pipelineName, branchName, runId),
+ }
+ res, err := PipelineOjb.GetBranchPipelineRunNodes()
+ return res, err
+}
+
+func (j *Jenkins) SubmitBranchInputStep(projectName, pipelineName, branchName, runId, nodeId, stepId string, httpParameters *devops.HttpParameters) ([]byte, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(CheckBranchPipelineUrl+httpParameters.Url.RawQuery, projectName, pipelineName, branchName, runId, nodeId, stepId),
+ }
+ res, err := PipelineOjb.SubmitBranchInputStep()
+ return res, err
+}
+
+func (j *Jenkins) GetPipelineBranch(projectName, pipelineName string, httpParameters *devops.HttpParameters) (*devops.PipelineBranch, error) {
+ path := fmt.Sprintf(GetPipeBranchUrl, projectName, pipelineName) + httpParameters.Url.RawQuery
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: path,
+ }
+ res, err := PipelineOjb.GetPipelineBranch()
+ return res, err
+}
+
+func (j *Jenkins) ScanBranch(projectName, pipelineName string, httpParameters *devops.HttpParameters) ([]byte, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(ScanBranchUrl+httpParameters.Url.RawQuery, projectName, pipelineName),
+ }
+ res, err := PipelineOjb.ScanBranch()
+ return res, err
+}
+
+func (j *Jenkins) GetConsoleLog(projectName, pipelineName string, httpParameters *devops.HttpParameters) ([]byte, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(GetConsoleLogUrl+httpParameters.Url.RawQuery, projectName, pipelineName),
+ }
+ res, err := PipelineOjb.GetConsoleLog()
+ return res, err
+}
+
+func (j *Jenkins) GetCrumb(httpParameters *devops.HttpParameters) (*devops.Crumb, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: GetCrumbUrl,
+ }
+ res, err := PipelineOjb.GetCrumb()
+ return res, err
+}
+
+func (j *Jenkins) GetSCMServers(scmId string, httpParameters *devops.HttpParameters) ([]devops.SCMServer, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: GetSCMServersUrl,
+ }
+ res, err := PipelineOjb.GetSCMServers()
+ return res, err
+}
+
+func (j *Jenkins) GetSCMOrg(scmId string, httpParameters *devops.HttpParameters) ([]devops.SCMOrg, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(GetSCMOrgUrl+httpParameters.Url.RawQuery, scmId),
+ }
+ res, err := PipelineOjb.GetSCMOrg()
+ return res, err
+}
+
+func (j *Jenkins) GetOrgRepo(scmId, organizationId string, httpParameters *devops.HttpParameters) ([]devops.OrgRepo, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(GetOrgRepoUrl+httpParameters.Url.RawQuery, scmId, organizationId),
+ }
+ res, err := PipelineOjb.GetOrgRepo()
+ return res, err
+}
+
+func (j *Jenkins) CreateSCMServers(scmId string, httpParameters *devops.HttpParameters) (*devops.SCMServer, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(CreateSCMServersUrl, scmId),
+ }
+ res, err := PipelineOjb.CreateSCMServers()
+ return res, err
+}
+
+func (j *Jenkins) GetNotifyCommit(httpParameters *devops.HttpParameters) ([]byte, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: GetNotifyCommitUrl + httpParameters.Url.RawQuery,
+ }
+ res, err := PipelineOjb.GetNotifyCommit()
+ return res, err
+}
+
+func (j *Jenkins) GithubWebhook(httpParameters *devops.HttpParameters) ([]byte, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: GithubWebhookUrl + httpParameters.Url.RawQuery,
+ }
+ res, err := PipelineOjb.GithubWebhook()
+ return res, err
+}
+
+func (j *Jenkins) Validate(scmId string, httpParameters *devops.HttpParameters) (*devops.Validates, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(ValidateUrl, scmId),
+ }
+ res, err := PipelineOjb.Validate()
+ return res, err
+}
+
+func (j *Jenkins) CheckScriptCompile(projectName, pipelineName string, httpParameters *devops.HttpParameters) (*devops.CheckScript, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: fmt.Sprintf(CheckScriptCompileUrl, projectName, pipelineName),
+ }
+ res, err := PipelineOjb.CheckScriptCompile()
+ return res, err
+}
+
+func (j *Jenkins) CheckCron(projectName string, httpParameters *devops.HttpParameters) (*devops.CheckCronRes, error) {
+ var cron = new(devops.CronData)
+ var reader io.ReadCloser
+ var path string
+
+ reader = httpParameters.Body
+ cronData, err := ioutil.ReadAll(reader)
+ err = json.Unmarshal(cronData, cron)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ if cron.PipelineName != "" {
+ path = fmt.Sprintf(CheckPipelienCronUrl, projectName, cron.PipelineName, cron.Cron)
+ } else {
+ path = fmt.Sprintf(CheckCronUrl, projectName, cron.Cron)
+ }
+
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: path,
+ }
+
+ res, err := PipelineOjb.CheckCron()
+ return res, err
+}
+
+func (j *Jenkins) ToJenkinsfile(httpParameters *devops.HttpParameters) (*devops.ResJenkinsfile, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: ToJenkinsfileUrl,
+ }
+ res, err := PipelineOjb.ToJenkinsfile()
+ return res, err
+}
+
+func (j *Jenkins) ToJson(httpParameters *devops.HttpParameters) (*devops.ResJson, error) {
+ PipelineOjb := &Pipeline{
+ HttpParameters: httpParameters,
+ Jenkins: j,
+ Path: ToJsonUrl,
+ }
+ res, err := PipelineOjb.ToJson()
+ return res, err
+}
+
+// Creates a new Jenkins Instance
+// Optional parameters are: client, username, password
+// After creating an instance call init method.
+func CreateJenkins(client *http.Client, base string, maxConnection int, auth ...interface{}) *Jenkins {
+ j := &Jenkins{}
+ if strings.HasSuffix(base, "/") {
+ base = base[:len(base)-1]
+ }
+ j.Server = base
+ j.Requester = &Requester{Base: base, SslVerify: true, Client: client, connControl: make(chan struct{}, maxConnection)}
+ if j.Requester.Client == nil {
+ j.Requester.Client = http.DefaultClient
+ }
+ if len(auth) == 2 {
+ j.Requester.BasicAuth = &BasicAuth{Username: auth[0].(string), Password: auth[1].(string)}
+ }
+ return j
+}
diff --git a/pkg/gojenkins/job.go b/pkg/simple/client/devops/jenkins/job.go
similarity index 93%
rename from pkg/gojenkins/job.go
rename to pkg/simple/client/devops/jenkins/job.go
index c075a42e5cfe65309f29f940b8cda865d1a13307..413cd39660723f57b6e74db8eea5892652ca79dd 100644
--- a/pkg/gojenkins/job.go
+++ b/pkg/simple/client/devops/jenkins/job.go
@@ -12,13 +12,14 @@
// License for the specific language governing permissions and limitations
// under the License.
-package gojenkins
+package jenkins
import (
"bytes"
"encoding/json"
"errors"
"fmt"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
"net/url"
"path"
"strconv"
@@ -60,7 +61,7 @@ type ParameterDefinition struct {
type JobResponse struct {
Class string `json:"_class"`
- Actions []GeneralObj
+ Actions []devops.GeneralAction
Buildable bool `json:"buildable"`
Builds []JobBuild
Color string `json:"color"`
@@ -96,8 +97,6 @@ type JobResponse struct {
UpstreamProjects []InnerJob `json:"upstreamProjects"`
URL string `json:"url"`
Jobs []InnerJob `json:"jobs"`
- PrimaryView *ViewData `json:"primaryView"`
- Views []ViewData `json:"views"`
}
func (j *Job) parentBase() string {
@@ -123,7 +122,7 @@ func (j *Job) GetDetails() *JobResponse {
}
func (j *Job) GetBuild(id int64) (*Build, error) {
- build := Build{Jenkins: j.Jenkins, Job: j, Raw: new(BuildResponse), Depth: 1, Base: "/job/" + j.GetName() + "/" + strconv.FormatInt(id, 10)}
+ build := Build{Jenkins: j.Jenkins, Job: j, Raw: new(devops.Build), Depth: 1, Base: "/job/" + j.GetName() + "/" + strconv.FormatInt(id, 10)}
status, err := build.Poll()
if err != nil {
return nil, err
@@ -153,7 +152,7 @@ func (j *Job) getBuildByType(buildType string) (*Build, error) {
Jenkins: j.Jenkins,
Depth: 1,
Job: j,
- Raw: new(BuildResponse),
+ Raw: new(devops.Build),
Base: j.Base + "/" + number}
status, err := build.Poll()
if err != nil {
@@ -212,10 +211,6 @@ func (j *Job) GetAllBuildStatus() ([]JobBuildStatus, error) {
return buildsResp.Builds, nil
}
-func (j *Job) GetSubJobsMetadata() []InnerJob {
- return j.Raw.SubJobs
-}
-
func (j *Job) GetUpstreamJobsMetadata() []InnerJob {
return j.Raw.UpstreamProjects
}
@@ -224,18 +219,6 @@ func (j *Job) GetDownstreamJobsMetadata() []InnerJob {
return j.Raw.DownstreamProjects
}
-func (j *Job) GetSubJobs() ([]*Job, error) {
- jobs := make([]*Job, len(j.Raw.SubJobs))
- for i, job := range j.Raw.SubJobs {
- ji, err := j.Jenkins.GetSubJob(j.GetName(), job.Name)
- if err != nil {
- return nil, err
- }
- jobs[i] = ji
- }
- return jobs, nil
-}
-
func (j *Job) GetInnerJobsMetadata() []InnerJob {
return j.Raw.Jobs
}
@@ -519,11 +502,3 @@ func (j *Job) Poll() (int, error) {
}
return response.StatusCode, nil
}
-
-func (j *Job) History() ([]*History, error) {
- resp, err := j.Jenkins.Requester.Get(j.Base+"/buildHistory/ajax", nil, nil)
- if err != nil {
- return nil, err
- }
- return parseBuildHistory(resp.Body), nil
-}
diff --git a/pkg/simple/client/devops/jenkins/member.go b/pkg/simple/client/devops/jenkins/member.go
new file mode 100644
index 0000000000000000000000000000000000000000..2d9cb47a3be17032f3abfa6343d8271d279e9f3f
--- /dev/null
+++ b/pkg/simple/client/devops/jenkins/member.go
@@ -0,0 +1,322 @@
+package jenkins
+
+import (
+ "fmt"
+ "github.com/emicklei/go-restful"
+ "k8s.io/klog"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
+)
+
+const (
+ JenkinsAllUserRoleName = "kubesphere-user"
+)
+
+func GetProjectRoleName(projectId, role string) string {
+ return fmt.Sprintf("%s-%s-project", projectId, role)
+}
+
+func GetPipelineRoleName(projectId, role string) string {
+ return fmt.Sprintf("%s-%s-pipeline", projectId, role)
+}
+
+func GetProjectRolePattern(projectId string) string {
+ return fmt.Sprintf("^%s$", projectId)
+}
+
+func GetPipelineRolePattern(projectId string) string {
+ return fmt.Sprintf("^%s/.*", projectId)
+}
+
+var JenkinsOwnerProjectPermissionIds = &ProjectPermissionIds{
+ CredentialCreate: true,
+ CredentialDelete: true,
+ CredentialManageDomains: true,
+ CredentialUpdate: true,
+ CredentialView: true,
+ ItemBuild: true,
+ ItemCancel: true,
+ ItemConfigure: true,
+ ItemCreate: true,
+ ItemDelete: true,
+ ItemDiscover: true,
+ ItemMove: true,
+ ItemRead: true,
+ ItemWorkspace: true,
+ RunDelete: true,
+ RunReplay: true,
+ RunUpdate: true,
+ SCMTag: true,
+}
+
+var JenkinsProjectPermissionMap = map[string]ProjectPermissionIds{
+ devops.ProjectOwner: {
+ CredentialCreate: true,
+ CredentialDelete: true,
+ CredentialManageDomains: true,
+ CredentialUpdate: true,
+ CredentialView: true,
+ ItemBuild: true,
+ ItemCancel: true,
+ ItemConfigure: true,
+ ItemCreate: true,
+ ItemDelete: true,
+ ItemDiscover: true,
+ ItemMove: true,
+ ItemRead: true,
+ ItemWorkspace: true,
+ RunDelete: true,
+ RunReplay: true,
+ RunUpdate: true,
+ SCMTag: true,
+ },
+ devops.ProjectMaintainer: {
+ CredentialCreate: true,
+ CredentialDelete: true,
+ CredentialManageDomains: true,
+ CredentialUpdate: true,
+ CredentialView: true,
+ ItemBuild: true,
+ ItemCancel: true,
+ ItemConfigure: false,
+ ItemCreate: true,
+ ItemDelete: false,
+ ItemDiscover: true,
+ ItemMove: false,
+ ItemRead: true,
+ ItemWorkspace: true,
+ RunDelete: true,
+ RunReplay: true,
+ RunUpdate: true,
+ SCMTag: true,
+ },
+ devops.ProjectDeveloper: {
+ CredentialCreate: false,
+ CredentialDelete: false,
+ CredentialManageDomains: false,
+ CredentialUpdate: false,
+ CredentialView: false,
+ ItemBuild: true,
+ ItemCancel: true,
+ ItemConfigure: false,
+ ItemCreate: false,
+ ItemDelete: false,
+ ItemDiscover: true,
+ ItemMove: false,
+ ItemRead: true,
+ ItemWorkspace: true,
+ RunDelete: true,
+ RunReplay: true,
+ RunUpdate: true,
+ SCMTag: false,
+ },
+ devops.ProjectReporter: {
+ CredentialCreate: false,
+ CredentialDelete: false,
+ CredentialManageDomains: false,
+ CredentialUpdate: false,
+ CredentialView: false,
+ ItemBuild: false,
+ ItemCancel: false,
+ ItemConfigure: false,
+ ItemCreate: false,
+ ItemDelete: false,
+ ItemDiscover: true,
+ ItemMove: false,
+ ItemRead: true,
+ ItemWorkspace: false,
+ RunDelete: false,
+ RunReplay: false,
+ RunUpdate: false,
+ SCMTag: false,
+ },
+}
+
+var JenkinsPipelinePermissionMap = map[string]ProjectPermissionIds{
+ devops.ProjectOwner: {
+ CredentialCreate: true,
+ CredentialDelete: true,
+ CredentialManageDomains: true,
+ CredentialUpdate: true,
+ CredentialView: true,
+ ItemBuild: true,
+ ItemCancel: true,
+ ItemConfigure: true,
+ ItemCreate: true,
+ ItemDelete: true,
+ ItemDiscover: true,
+ ItemMove: true,
+ ItemRead: true,
+ ItemWorkspace: true,
+ RunDelete: true,
+ RunReplay: true,
+ RunUpdate: true,
+ SCMTag: true,
+ },
+ devops.ProjectMaintainer: {
+ CredentialCreate: true,
+ CredentialDelete: true,
+ CredentialManageDomains: true,
+ CredentialUpdate: true,
+ CredentialView: true,
+ ItemBuild: true,
+ ItemCancel: true,
+ ItemConfigure: true,
+ ItemCreate: true,
+ ItemDelete: true,
+ ItemDiscover: true,
+ ItemMove: true,
+ ItemRead: true,
+ ItemWorkspace: true,
+ RunDelete: true,
+ RunReplay: true,
+ RunUpdate: true,
+ SCMTag: true,
+ },
+ devops.ProjectDeveloper: {
+ CredentialCreate: false,
+ CredentialDelete: false,
+ CredentialManageDomains: false,
+ CredentialUpdate: false,
+ CredentialView: false,
+ ItemBuild: true,
+ ItemCancel: true,
+ ItemConfigure: false,
+ ItemCreate: false,
+ ItemDelete: false,
+ ItemDiscover: true,
+ ItemMove: false,
+ ItemRead: true,
+ ItemWorkspace: true,
+ RunDelete: true,
+ RunReplay: true,
+ RunUpdate: true,
+ SCMTag: false,
+ },
+ devops.ProjectReporter: {
+ CredentialCreate: false,
+ CredentialDelete: false,
+ CredentialManageDomains: false,
+ CredentialUpdate: false,
+ CredentialView: false,
+ ItemBuild: false,
+ ItemCancel: false,
+ ItemConfigure: false,
+ ItemCreate: false,
+ ItemDelete: false,
+ ItemDiscover: true,
+ ItemMove: false,
+ ItemRead: true,
+ ItemWorkspace: false,
+ RunDelete: false,
+ RunReplay: false,
+ RunUpdate: false,
+ SCMTag: false,
+ },
+}
+
+func (j *Jenkins) AddProjectMember(membership *devops.ProjectMembership) (*devops.ProjectMembership, error) {
+ globalRole, err := j.GetGlobalRole(JenkinsAllUserRoleName)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ if globalRole == nil {
+ _, err := j.AddGlobalRole(JenkinsAllUserRoleName, GlobalPermissionIds{
+ GlobalRead: true,
+ }, true)
+ if err != nil {
+ klog.Errorf("failed to create jenkins global role %+v", err)
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ }
+ err = globalRole.AssignRole(membership.Username)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ projectRole, err := j.GetProjectRole(GetProjectRoleName(membership.ProjectId, membership.Role))
+ if err != nil {
+ klog.Errorf("%+v", err)
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ err = projectRole.AssignRole(membership.Username)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ pipelineRole, err := j.GetProjectRole(GetPipelineRoleName(membership.ProjectId, membership.Role))
+ if err != nil {
+ klog.Errorf("%+v", err)
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ err = pipelineRole.AssignRole(membership.Username)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ return membership, nil
+}
+
+func (j *Jenkins) UpdateProjectMember(oldMembership, newMembership *devops.ProjectMembership) (*devops.ProjectMembership, error) {
+ oldProjectRole, err := j.GetProjectRole(GetProjectRoleName(oldMembership.ProjectId, oldMembership.Role))
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ err = oldProjectRole.UnAssignRole(newMembership.Username)
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ oldPipelineRole, err := j.GetProjectRole(GetPipelineRoleName(oldMembership.ProjectId, oldMembership.Role))
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ err = oldPipelineRole.UnAssignRole(newMembership.Username)
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ projectRole, err := j.GetProjectRole(GetProjectRoleName(oldMembership.ProjectId, newMembership.Role))
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ err = projectRole.AssignRole(newMembership.Username)
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ pipelineRole, err := j.GetProjectRole(GetPipelineRoleName(oldMembership.ProjectId, newMembership.Role))
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ err = pipelineRole.AssignRole(newMembership.Username)
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ return newMembership, nil
+}
+
+func (j *Jenkins) DeleteProjectMember(membership *devops.ProjectMembership) (*devops.ProjectMembership, error) {
+ oldProjectRole, err := j.GetProjectRole(GetProjectRoleName(membership.ProjectId, membership.Role))
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ err = oldProjectRole.UnAssignRole(membership.Username)
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ oldPipelineRole, err := j.GetProjectRole(GetPipelineRoleName(membership.ProjectId, membership.Role))
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ err = oldPipelineRole.UnAssignRole(membership.Username)
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ return membership, nil
+}
diff --git a/pkg/simple/client/devops/options.go b/pkg/simple/client/devops/jenkins/options.go
similarity index 99%
rename from pkg/simple/client/devops/options.go
rename to pkg/simple/client/devops/jenkins/options.go
index e3b1bd0920e81d56355ec8d0a32dca26dcda4c5e..70280a279bf4d764f49c41426b728118787b14b4 100644
--- a/pkg/simple/client/devops/options.go
+++ b/pkg/simple/client/devops/jenkins/options.go
@@ -1,4 +1,4 @@
-package devops
+package jenkins
import (
"fmt"
diff --git a/pkg/simple/client/devops/jenkins/pipeline.go b/pkg/simple/client/devops/jenkins/pipeline.go
new file mode 100644
index 0000000000000000000000000000000000000000..08122f46bb77fa0cddc154b7439cf83ed387af66
--- /dev/null
+++ b/pkg/simple/client/devops/jenkins/pipeline.go
@@ -0,0 +1,722 @@
+package jenkins
+
+import (
+ "encoding/json"
+ "github.com/PuerkitoBio/goquery"
+ "k8s.io/klog"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "net/http"
+ "net/url"
+ "strings"
+ "time"
+)
+
+type Pipeline struct {
+ HttpParameters *devops.HttpParameters
+ Jenkins *Jenkins
+ Path string
+}
+
+const (
+ GetPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/"
+ ListPipelinesUrl = "/blue/rest/search/?"
+ GetPipelineRunUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/"
+ ListPipelineRunUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/?"
+ StopPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/stop/?"
+ ReplayPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/replay/"
+ RunPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/"
+ GetArtifactsUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/artifacts/?"
+ GetRunLogUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/log/?"
+ GetStepLogUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/nodes/%s/steps/%s/log/?"
+ GetPipelineRunNodesUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/nodes/?"
+ SubmitInputStepUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/nodes/%s/steps/%s/"
+ GetNodeStepsUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/runs/%s/nodes/%s/steps/?"
+
+ GetBranchPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/"
+ GetBranchPipelineRunUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/"
+ StopBranchPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/stop/?"
+ ReplayBranchPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/replay/"
+ RunBranchPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/"
+ GetBranchArtifactsUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/artifacts/?"
+ GetBranchRunLogUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/log/?"
+ GetBranchStepLogUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/nodes/%s/steps/%s/log/?"
+ GetBranchNodeStepsUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/nodes/%s/steps/?"
+ GetBranchPipeRunNodesUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/nodes/?"
+ CheckBranchPipelineUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/%s/runs/%s/nodes/%s/steps/%s/"
+ GetPipeBranchUrl = "/blue/rest/organizations/jenkins/pipelines/%s/pipelines/%s/branches/?"
+ ScanBranchUrl = "/job/%s/job/%s/build?"
+ GetConsoleLogUrl = "/job/%s/job/%s/indexing/consoleText"
+ GetCrumbUrl = "/crumbIssuer/api/json/"
+ GetSCMServersUrl = "/blue/rest/organizations/jenkins/scm/%s/servers/"
+ GetSCMOrgUrl = "/blue/rest/organizations/jenkins/scm/%s/organizations/?"
+ GetOrgRepoUrl = "/blue/rest/organizations/jenkins/scm/%s/organizations/%s/repositories/?"
+ CreateSCMServersUrl = "/blue/rest/organizations/jenkins/scm/%s/servers/"
+ ValidateUrl = "/blue/rest/organizations/jenkins/scm/%s/validate"
+
+ GetNotifyCommitUrl = "/git/notifyCommit/?"
+ GithubWebhookUrl = "/github-webhook/"
+ CheckScriptCompileUrl = "/job/%s/job/%s/descriptorByName/org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition/checkScriptCompile"
+
+ CheckPipelienCronUrl = "/job/%s/job/%s/descriptorByName/hudson.triggers.TimerTrigger/checkSpec?value=%s"
+ CheckCronUrl = "/job/%s/descriptorByName/hudson.triggers.TimerTrigger/checkSpec?value=%s"
+ ToJenkinsfileUrl = "/pipeline-model-converter/toJenkinsfile"
+ ToJsonUrl = "/pipeline-model-converter/toJson"
+
+ cronJobLayout = "Monday, January 2, 2006 15:04:05 PM"
+)
+
+func (p *Pipeline) GetPipeline() (*devops.Pipeline, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+ var pipeline devops.Pipeline
+
+ err = json.Unmarshal(res, &pipeline)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+ return &pipeline, err
+}
+
+func (p *Pipeline) ListPipelines() (*devops.PipelineList, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+ count, err := p.searchPipelineCount()
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ pipelienList := devops.PipelineList{Total: count}
+ err = json.Unmarshal(res, &pipelienList.Items)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+ return &pipelienList, err
+}
+
+func (p *Pipeline) searchPipelineCount() (int, error) {
+ query, _ := parseJenkinsQuery(p.HttpParameters.Url.RawQuery)
+ query.Set("start", "0")
+ query.Set("limit", "1000")
+ query.Set("depth", "-1")
+
+ formatUrl := ListPipelinesUrl + query.Encode()
+
+ res, err := p.Jenkins.SendPureRequest(formatUrl, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ return 0, err
+ }
+ var pipelines []devops.Pipeline
+ err = json.Unmarshal(res, &pipelines)
+ if err != nil {
+ klog.Error(err)
+ return 0, err
+ }
+ return len(pipelines), nil
+}
+
+func (p *Pipeline) GetPipelineRun() (*devops.PipelineRun, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ var pipelineRun devops.PipelineRun
+ err = json.Unmarshal(res, &pipelineRun)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+ return &pipelineRun, err
+}
+
+func (p *Pipeline) ListPipelineRuns() (*devops.PipelineRunList, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ var pipelineRunList devops.PipelineRunList
+ err = json.Unmarshal(res, &pipelineRunList)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+ return &pipelineRunList, err
+}
+
+func (p *Pipeline) searchPipelineRunsCount() (int, error) {
+ query, _ := parseJenkinsQuery(p.HttpParameters.Url.RawQuery)
+ query.Set("start", "0")
+ query.Set("limit", "1000")
+ query.Set("depth", "-1")
+ //formatUrl := fmt.Sprintf(SearchPipelineRunUrl, projectName, pipelineName)
+
+ res, err := p.Jenkins.SendPureRequest(ListPipelineRunUrl+query.Encode(), p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ return 0, err
+ }
+ var runs []devops.PipelineRun
+ err = json.Unmarshal(res, &runs)
+ if err != nil {
+ klog.Error(err)
+ return 0, err
+ }
+ return len(runs), nil
+}
+
+func (p *Pipeline) StopPipeline() (*devops.StopPipeline, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ var stopPipeline devops.StopPipeline
+ err = json.Unmarshal(res, &stopPipeline)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return &stopPipeline, err
+}
+
+func (p *Pipeline) ReplayPipeline() (*devops.ReplayPipeline, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ var replayPipeline devops.ReplayPipeline
+ err = json.Unmarshal(res, &replayPipeline)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return &replayPipeline, err
+}
+
+func (p *Pipeline) RunPipeline() (*devops.RunPipeline, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ var runPipeline devops.RunPipeline
+ err = json.Unmarshal(res, &runPipeline)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return &runPipeline, err
+}
+
+func (p *Pipeline) GetArtifacts() ([]devops.Artifacts, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ var artifacts []devops.Artifacts
+ err = json.Unmarshal(res, &artifacts)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return artifacts, err
+}
+
+func (p *Pipeline) GetRunLog() ([]byte, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ return res, err
+}
+
+func (p *Pipeline) GetStepLog() ([]byte, http.Header, error) {
+ res, header, err := p.Jenkins.SendPureRequestWithHeaderResp(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ return res, header, err
+}
+
+func (p *Pipeline) GetNodeSteps() ([]devops.NodeSteps, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ var nodeSteps []devops.NodeSteps
+ err = json.Unmarshal(res, &nodeSteps)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return nodeSteps, err
+}
+
+func (p *Pipeline) GetPipelineRunNodes() ([]devops.PipelineRunNodes, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ var pipelineRunNodes []devops.PipelineRunNodes
+ err = json.Unmarshal(res, &pipelineRunNodes)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return pipelineRunNodes, err
+}
+
+func (p *Pipeline) SubmitInputStep() ([]byte, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ return res, err
+}
+
+func (p *Pipeline) GetBranchPipeline() (*devops.BranchPipeline, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+ var branchPipeline devops.BranchPipeline
+ err = json.Unmarshal(res, &branchPipeline)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return &branchPipeline, err
+}
+
+func (p *Pipeline) GetBranchPipelineRun() (*devops.PipelineRun, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+ var branchPipelineRun devops.PipelineRun
+ err = json.Unmarshal(res, &branchPipelineRun)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return &branchPipelineRun, err
+}
+
+func (p *Pipeline) StopBranchPipeline() (*devops.StopPipeline, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+ var branchStopPipeline devops.StopPipeline
+ err = json.Unmarshal(res, &branchStopPipeline)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return &branchStopPipeline, err
+}
+
+func (p *Pipeline) ReplayBranchPipeline() (*devops.ReplayPipeline, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+ var branchReplayPipeline devops.ReplayPipeline
+ err = json.Unmarshal(res, &branchReplayPipeline)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return &branchReplayPipeline, err
+}
+
+func (p *Pipeline) RunBranchPipeline() (*devops.RunPipeline, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+ var branchRunPipeline devops.RunPipeline
+ err = json.Unmarshal(res, &branchRunPipeline)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return &branchRunPipeline, err
+}
+
+func (p *Pipeline) GetBranchArtifacts() ([]devops.Artifacts, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ var artifacts []devops.Artifacts
+ err = json.Unmarshal(res, &artifacts)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return artifacts, err
+}
+
+func (p *Pipeline) GetBranchRunLog() ([]byte, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ return res, err
+}
+
+func (p *Pipeline) GetBranchStepLog() ([]byte, http.Header, error) {
+ res, header, err := p.Jenkins.SendPureRequestWithHeaderResp(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ return res, header, err
+}
+
+func (p *Pipeline) GetBranchNodeSteps() ([]devops.NodeSteps, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+ var branchNodeSteps []devops.NodeSteps
+ err = json.Unmarshal(res, &branchNodeSteps)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return branchNodeSteps, err
+}
+
+func (p *Pipeline) GetBranchPipelineRunNodes() ([]devops.BranchPipelineRunNodes, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+ var branchPipelineRunNodes []devops.BranchPipelineRunNodes
+ err = json.Unmarshal(res, &branchPipelineRunNodes)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return branchPipelineRunNodes, err
+}
+
+func (p *Pipeline) SubmitBranchInputStep() ([]byte, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ return res, err
+}
+
+func (p *Pipeline) GetPipelineBranch() (*devops.PipelineBranch, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+ var pipelineBranch devops.PipelineBranch
+ err = json.Unmarshal(res, &pipelineBranch)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return &pipelineBranch, err
+}
+
+func (p *Pipeline) ScanBranch() ([]byte, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ return res, err
+}
+
+func (p *Pipeline) GetConsoleLog() ([]byte, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ return res, err
+}
+
+func (p *Pipeline) GetCrumb() (*devops.Crumb, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+ var crumb devops.Crumb
+ err = json.Unmarshal(res, &crumb)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return &crumb, err
+}
+
+func (p *Pipeline) GetSCMServers() ([]devops.SCMServer, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+ var SCMServer []devops.SCMServer
+ err = json.Unmarshal(res, &SCMServer)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return SCMServer, err
+}
+
+func (p *Pipeline) GetSCMOrg() ([]devops.SCMOrg, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+ var SCMOrg []devops.SCMOrg
+ err = json.Unmarshal(res, &SCMOrg)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return SCMOrg, err
+}
+
+func (p *Pipeline) GetOrgRepo() ([]devops.OrgRepo, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+ var OrgRepo []devops.OrgRepo
+ err = json.Unmarshal(res, &OrgRepo)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return OrgRepo, err
+}
+
+func (p *Pipeline) CreateSCMServers() (*devops.SCMServer, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+ var SCMServer devops.SCMServer
+ err = json.Unmarshal(res, &SCMServer)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return &SCMServer, err
+}
+
+func (p *Pipeline) GetNotifyCommit() ([]byte, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ return res, err
+}
+
+func (p *Pipeline) GithubWebhook() ([]byte, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ return res, err
+}
+
+func (p *Pipeline) Validate() (*devops.Validates, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ var validates devops.Validates
+ err = json.Unmarshal(res, &validates)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return &validates, err
+}
+
+func (p *Pipeline) CheckScriptCompile() (*devops.CheckScript, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ // Jenkins will return different struct according to different results.
+ var checkScript devops.CheckScript
+ ok := json.Unmarshal(res, &checkScript)
+ if ok != nil {
+ var resJson []*devops.CheckScript
+ err := json.Unmarshal(res, &resJson)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return resJson[0], nil
+ }
+
+ return &checkScript, err
+
+}
+
+func (p *Pipeline) CheckCron() (*devops.CheckCronRes, error) {
+
+ var res = new(devops.CheckCronRes)
+
+ Url, err := url.Parse(p.Jenkins.Server + p.Path)
+
+ reqJenkins := &http.Request{
+ Method: http.MethodGet,
+ URL: Url,
+ Header: p.HttpParameters.Header,
+ }
+
+ client := &http.Client{Timeout: 30 * time.Second}
+
+ resp, err := client.Do(reqJenkins)
+
+ if resp != nil && resp.StatusCode != http.StatusOK {
+ resBody, _ := getRespBody(resp)
+ return &devops.CheckCronRes{
+ Result: "error",
+ Message: string(resBody),
+ }, err
+ }
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+ defer resp.Body.Close()
+
+ doc, err := goquery.NewDocumentFromReader(resp.Body)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+ doc.Find("div").Each(func(i int, selection *goquery.Selection) {
+ res.Message = selection.Text()
+ res.Result, _ = selection.Attr("class")
+ })
+ if res.Result == "ok" {
+ res.LastTime, res.NextTime, err = parseCronJobTime(res.Message)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+ }
+
+ return res, err
+}
+
+func parseCronJobTime(msg string) (string, string, error) {
+
+ times := strings.Split(msg, ";")
+
+ lastTmp := strings.Split(times[0], " ")
+ lastCount := len(lastTmp)
+ lastTmp = lastTmp[lastCount-7 : lastCount-1]
+ lastTime := strings.Join(lastTmp, " ")
+ lastUinx, err := time.Parse(cronJobLayout, lastTime)
+ if err != nil {
+ klog.Error(err)
+ return "", "", err
+ }
+ last := lastUinx.Format(time.RFC3339)
+
+ nextTmp := strings.Split(times[1], " ")
+ nextCount := len(nextTmp)
+ nextTmp = nextTmp[nextCount-7 : nextCount-1]
+ nextTime := strings.Join(nextTmp, " ")
+ nextUinx, err := time.Parse(cronJobLayout, nextTime)
+ if err != nil {
+ klog.Error(err)
+ return "", "", err
+ }
+ next := nextUinx.Format(time.RFC3339)
+
+ return last, next, nil
+}
+
+func (p *Pipeline) ToJenkinsfile() (*devops.ResJenkinsfile, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ var jenkinsfile devops.ResJenkinsfile
+ err = json.Unmarshal(res, &jenkinsfile)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return &jenkinsfile, err
+}
+
+func (p *Pipeline) ToJson() (*devops.ResJson, error) {
+ res, err := p.Jenkins.SendPureRequest(p.Path, p.HttpParameters)
+ if err != nil {
+ klog.Error(err)
+ }
+
+ var toJson devops.ResJson
+ err = json.Unmarshal(res, &toJson)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+
+ return &toJson, err
+}
diff --git a/pkg/models/devops/project_pipeline.go b/pkg/simple/client/devops/jenkins/pipeline_internal.go
similarity index 59%
rename from pkg/models/devops/project_pipeline.go
rename to pkg/simple/client/devops/jenkins/pipeline_internal.go
index 1cd5d2ee453b535598a025114bbed71b40095fed..cb84f4fc123253356520a8a6b5be1cc81da781a1 100644
--- a/pkg/models/devops/project_pipeline.go
+++ b/pkg/simple/client/devops/jenkins/pipeline_internal.go
@@ -1,179 +1,14 @@
-/*
-Copyright 2019 The KubeSphere Authors.
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package devops
+package jenkins
import (
"fmt"
"github.com/beevik/etree"
- "github.com/kubesphere/sonargo/sonar"
- "k8s.io/klog"
- "kubesphere.io/kubesphere/pkg/gojenkins"
- "kubesphere.io/kubesphere/pkg/simple/client"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
"strconv"
"strings"
"time"
)
-const (
- NoScmPipelineType = "pipeline"
- MultiBranchPipelineType = "multi-branch-pipeline"
-)
-
-type Parameters []*Parameter
-
-var ParameterTypeMap = map[string]string{
- "hudson.model.StringParameterDefinition": "string",
- "hudson.model.ChoiceParameterDefinition": "choice",
- "hudson.model.TextParameterDefinition": "text",
- "hudson.model.BooleanParameterDefinition": "boolean",
- "hudson.model.FileParameterDefinition": "file",
- "hudson.model.PasswordParameterDefinition": "password",
-}
-
-const (
- SonarAnalysisActionClass = "hudson.plugins.sonar.action.SonarAnalysisAction"
- SonarMetricKeys = "alert_status,quality_gate_details,bugs,new_bugs,reliability_rating,new_reliability_rating,vulnerabilities,new_vulnerabilities,security_rating,new_security_rating,code_smells,new_code_smells,sqale_rating,new_maintainability_rating,sqale_index,new_technical_debt,coverage,new_coverage,new_lines_to_cover,tests,duplicated_lines_density,new_duplicated_lines_density,duplicated_blocks,ncloc,ncloc_language_distribution,projects,new_lines"
- SonarAdditionalFields = "metrics,periods"
-)
-
-type SonarStatus struct {
- Measures *sonargo.MeasuresComponentObject `json:"measures,omitempty"`
- Issues *sonargo.IssuesSearchObject `json:"issues,omitempty"`
- JenkinsAction *gojenkins.GeneralObj `json:"jenkinsAction,omitempty"`
- Task *sonargo.CeTaskObject `json:"task,omitempty"`
-}
-
-type ProjectPipeline struct {
- Type string `json:"type" description:"type of devops pipeline, in scm or no scm"`
- Pipeline *NoScmPipeline `json:"pipeline,omitempty" description:"no scm pipeline structs"`
- MultiBranchPipeline *MultiBranchPipeline `json:"multi_branch_pipeline,omitempty" description:"in scm pipeline structs"`
-}
-
-type NoScmPipeline struct {
- Name string `json:"name" description:"name of pipeline"`
- Description string `json:"descriptio,omitempty" description:"description of pipeline"`
- Discarder *DiscarderProperty `json:"discarder,omitempty" description:"Discarder of pipeline, managing when to drop a pipeline"`
- Parameters *Parameters `json:"parameters,omitempty" description:"Parameters define of pipeline,user could pass param when run pipeline"`
- DisableConcurrent bool `json:"disable_concurrent,omitempty" mapstructure:"disable_concurrent" description:"Whether to prohibit the pipeline from running in parallel"`
- TimerTrigger *TimerTrigger `json:"timer_trigger,omitempty" mapstructure:"timer_trigger" description:"Timer to trigger pipeline run"`
- RemoteTrigger *RemoteTrigger `json:"remote_trigger,omitempty" mapstructure:"remote_trigger" description:"Remote api define to trigger pipeline run"`
- Jenkinsfile string `json:"jenkinsfile,omitempty" description:"Jenkinsfile's content'"`
-}
-
-type MultiBranchPipeline struct {
- Name string `json:"name" description:"name of pipeline"`
- Description string `json:"descriptio,omitempty" description:"description of pipeline"`
- Discarder *DiscarderProperty `json:"discarder,omitempty" description:"Discarder of pipeline, managing when to drop a pipeline"`
- TimerTrigger *TimerTrigger `json:"timer_trigger,omitempty" mapstructure:"timer_trigger" description:"Timer to trigger pipeline run"`
- SourceType string `json:"source_type" description:"type of scm, such as github/git/svn"`
- GitSource *GitSource `json:"git_source,omitempty" description:"git scm define"`
- GitHubSource *GithubSource `json:"github_source,omitempty" description:"github scm define"`
- SvnSource *SvnSource `json:"svn_source,omitempty" description:"multi branch svn scm define"`
- SingleSvnSource *SingleSvnSource `json:"single_svn_source,omitempty" description:"single branch svn scm define"`
- BitbucketServerSource *BitbucketServerSource `json:"bitbucket_server_source,omitempty" description:"bitbucket server scm defile"`
- ScriptPath string `json:"script_path" mapstructure:"script_path" description:"script path in scm"`
- MultiBranchJobTrigger *MultiBranchJobTrigger `json:"multibranch_job_trigger,omitempty" mapstructure:"multibranch_job_trigger" description:"Pipeline tasks that need to be triggered when branch creation/deletion"`
-}
-
-type GitSource struct {
- ScmId string `json:"scm_id,omitempty" description:"uid of scm"`
- Url string `json:"url,omitempty" mapstructure:"url" description:"url of git source"`
- CredentialId string `json:"credential_id,omitempty" mapstructure:"credential_id" description:"credential id to access git source"`
- DiscoverBranches bool `json:"discover_branches,omitempty" mapstructure:"discover_branches" description:"Whether to discover a branch"`
- CloneOption *GitCloneOption `json:"git_clone_option,omitempty" mapstructure:"git_clone_option" description:"advavced git clone options"`
- RegexFilter string `json:"regex_filter,omitempty" mapstructure:"regex_filter" description:"Regex used to match the name of the branch that needs to be run"`
-}
-
-type GithubSource struct {
- ScmId string `json:"scm_id,omitempty" description:"uid of scm"`
- Owner string `json:"owner,omitempty" mapstructure:"owner" description:"owner of github repo"`
- Repo string `json:"repo,omitempty" mapstructure:"repo" description:"repo name of github repo"`
- CredentialId string `json:"credential_id,omitempty" mapstructure:"credential_id" description:"credential id to access github source"`
- ApiUri string `json:"api_uri,omitempty" mapstructure:"api_uri" description:"The api url can specify the location of the github apiserver.For private cloud configuration"`
- DiscoverBranches int `json:"discover_branches,omitempty" mapstructure:"discover_branches" description:"Discover branch configuration"`
- DiscoverPRFromOrigin int `json:"discover_pr_from_origin,omitempty" mapstructure:"discover_pr_from_origin" description:"Discover origin PR configuration"`
- DiscoverPRFromForks *DiscoverPRFromForks `json:"discover_pr_from_forks,omitempty" mapstructure:"discover_pr_from_forks" description:"Discover fork PR configuration"`
- CloneOption *GitCloneOption `json:"git_clone_option,omitempty" mapstructure:"git_clone_option" description:"advavced git clone options"`
- RegexFilter string `json:"regex_filter,omitempty" mapstructure:"regex_filter" description:"Regex used to match the name of the branch that needs to be run"`
-}
-
-type MultiBranchJobTrigger struct {
- CreateActionJobsToTrigger string `json:"create_action_job_to_trigger,omitempty" description:"pipeline name to trigger"`
- DeleteActionJobsToTrigger string `json:"delete_action_job_to_trigger,omitempty" description:"pipeline name to trigger"`
-}
-
-type BitbucketServerSource struct {
- ScmId string `json:"scm_id,omitempty" description:"uid of scm"`
- Owner string `json:"owner,omitempty" mapstructure:"owner" description:"owner of github repo"`
- Repo string `json:"repo,omitempty" mapstructure:"repo" description:"repo name of github repo"`
- CredentialId string `json:"credential_id,omitempty" mapstructure:"credential_id" description:"credential id to access github source"`
- ApiUri string `json:"api_uri,omitempty" mapstructure:"api_uri" description:"The api url can specify the location of the github apiserver.For private cloud configuration"`
- DiscoverBranches int `json:"discover_branches,omitempty" mapstructure:"discover_branches" description:"Discover branch configuration"`
- DiscoverPRFromOrigin int `json:"discover_pr_from_origin,omitempty" mapstructure:"discover_pr_from_origin" description:"Discover origin PR configuration"`
- DiscoverPRFromForks *DiscoverPRFromForks `json:"discover_pr_from_forks,omitempty" mapstructure:"discover_pr_from_forks" description:"Discover fork PR configuration"`
- CloneOption *GitCloneOption `json:"git_clone_option,omitempty" mapstructure:"git_clone_option" description:"advavced git clone options"`
- RegexFilter string `json:"regex_filter,omitempty" mapstructure:"regex_filter" description:"Regex used to match the name of the branch that needs to be run"`
-}
-
-type GitCloneOption struct {
- Shallow bool `json:"shallow,omitempty" mapstructure:"shallow" description:"Whether to use git shallow clone"`
- Timeout int `json:"timeout,omitempty" mapstructure:"timeout" description:"git clone timeout mins"`
- Depth int `json:"depth,omitempty" mapstructure:"depth" description:"git clone depth"`
-}
-
-type SvnSource struct {
- ScmId string `json:"scm_id,omitempty" description:"uid of scm"`
- Remote string `json:"remote,omitempty" description:"remote address url"`
- CredentialId string `json:"credential_id,omitempty" mapstructure:"credential_id" description:"credential id to access svn source"`
- Includes string `json:"includes,omitempty" description:"branches to run pipeline"`
- Excludes string `json:"excludes,omitempty" description:"branches do not run pipeline"`
-}
-type SingleSvnSource struct {
- ScmId string `json:"scm_id,omitempty" description:"uid of scm"`
- Remote string `json:"remote,omitempty" description:"remote address url"`
- CredentialId string `json:"credential_id,omitempty" mapstructure:"credential_id" description:"credential id to access svn source"`
-}
-
-type DiscoverPRFromForks struct {
- Strategy int `json:"strategy,omitempty" mapstructure:"strategy" description:"github discover strategy"`
- Trust int `json:"trust,omitempty" mapstructure:"trust" description:"trust user type"`
-}
-
-type DiscarderProperty struct {
- DaysToKeep string `json:"days_to_keep,omitempty" mapstructure:"days_to_keep" description:"days to keep pipeline"`
- NumToKeep string `json:"num_to_keep,omitempty" mapstructure:"num_to_keep" description:"nums to keep pipeline"`
-}
-
-type Parameter struct {
- Name string `json:"name" description:"name of param"`
- DefaultValue string `json:"default_value,omitempty" mapstructure:"default_value" description:"default value of param"`
- Type string `json:"type" description:"type of param"`
- Description string `json:"description,omitempty" description:"description of pipeline"`
-}
-
-type TimerTrigger struct {
- // user in no scm job
- Cron string `json:"cron,omitempty" description:"jenkins cron script"`
-
- // use in multi-branch job
- Interval string `json:"interval,omitempty" description:"interval ms"`
-}
-
-type RemoteTrigger struct {
- Token string `json:"token,omitempty" description:"remote trigger token"`
-}
-
func replaceXmlVersion(config, oldVersion, targetVersion string) string {
lines := strings.Split(config, "\n")
lines[0] = strings.Replace(lines[0], oldVersion, targetVersion, -1)
@@ -181,7 +16,7 @@ func replaceXmlVersion(config, oldVersion, targetVersion string) string {
return output
}
-func createPipelineConfigXml(pipeline *NoScmPipeline) (string, error) {
+func createPipelineConfigXml(pipeline *devops.NoScmPipeline) (string, error) {
doc := etree.NewDocument()
xmlString := `
@@ -215,7 +50,7 @@ func createPipelineConfigXml(pipeline *NoScmPipeline) (string, error) {
strategy.CreateElement("artifactNumToKeep").SetText("-1")
}
if pipeline.Parameters != nil {
- pipeline.Parameters.appendToEtree(properties)
+ appendParametersToEtree(properties, pipeline.Parameters)
}
if pipeline.TimerTrigger != nil {
@@ -247,8 +82,8 @@ func createPipelineConfigXml(pipeline *NoScmPipeline) (string, error) {
return replaceXmlVersion(stringXml, "1.0", "1.1"), err
}
-func parsePipelineConfigXml(config string) (*NoScmPipeline, error) {
- pipeline := &NoScmPipeline{}
+func parsePipelineConfigXml(config string) (*devops.NoScmPipeline, error) {
+ pipeline := &devops.NoScmPipeline{}
config = replaceXmlVersion(config, "1.1", "1.0")
doc := etree.NewDocument()
err := doc.ReadFromString(config)
@@ -271,13 +106,13 @@ func parsePipelineConfigXml(config string) (*NoScmPipeline, error) {
strategy := properties.
SelectElement("jenkins.model.BuildDiscarderProperty").
SelectElement("strategy")
- pipeline.Discarder = &DiscarderProperty{
+ pipeline.Discarder = &devops.DiscarderProperty{
DaysToKeep: strategy.SelectElement("daysToKeep").Text(),
NumToKeep: strategy.SelectElement("numToKeep").Text(),
}
}
- pipeline.Parameters = &Parameters{}
- pipeline.Parameters = pipeline.Parameters.fromEtree(properties)
+ pipeline.Parameters = &devops.Parameters{}
+ pipeline.Parameters = getParametersfromEtree(properties)
if len(*pipeline.Parameters) == 0 {
pipeline.Parameters = nil
}
@@ -287,13 +122,13 @@ func parsePipelineConfigXml(config string) (*NoScmPipeline, error) {
"org.jenkinsci.plugins.workflow.job.properties.PipelineTriggersJobProperty"); triggerProperty != nil {
triggers := triggerProperty.SelectElement("triggers")
if timerTrigger := triggers.SelectElement("hudson.triggers.TimerTrigger"); timerTrigger != nil {
- pipeline.TimerTrigger = &TimerTrigger{
+ pipeline.TimerTrigger = &devops.TimerTrigger{
Cron: timerTrigger.SelectElement("spec").Text(),
}
}
}
if authToken := flow.SelectElement("authToken"); authToken != nil {
- pipeline.RemoteTrigger = &RemoteTrigger{
+ pipeline.RemoteTrigger = &devops.RemoteTrigger{
Token: authToken.Text(),
}
}
@@ -305,11 +140,11 @@ func parsePipelineConfigXml(config string) (*NoScmPipeline, error) {
return pipeline, nil
}
-func (s *Parameters) appendToEtree(properties *etree.Element) *Parameters {
+func appendParametersToEtree(properties *etree.Element, parameters *devops.Parameters) {
parameterDefinitions := properties.CreateElement("hudson.model.ParametersDefinitionProperty").
CreateElement("parameterDefinitions")
- for _, parameter := range *s {
- for className, typeName := range ParameterTypeMap {
+ for _, parameter := range *parameters {
+ for className, typeName := range devops.ParameterTypeMap {
if typeName == parameter.Type {
paramDefine := parameterDefinitions.CreateElement(className)
paramDefine.CreateElement("name").SetText(parameter.Name)
@@ -332,66 +167,62 @@ func (s *Parameters) appendToEtree(properties *etree.Element) *Parameters {
}
}
}
- return s
}
-func (s *Parameters) fromEtree(properties *etree.Element) *Parameters {
-
+func getParametersfromEtree(properties *etree.Element) *devops.Parameters {
+ var parameters devops.Parameters
if parametersProperty := properties.SelectElement("hudson.model.ParametersDefinitionProperty"); parametersProperty != nil {
params := parametersProperty.SelectElement("parameterDefinitions").ChildElements()
- if *s == nil {
- *s = make([]*Parameter, 0)
- }
for _, param := range params {
switch param.Tag {
case "hudson.model.StringParameterDefinition":
- *s = append(*s, &Parameter{
+ parameters = append(parameters, &devops.Parameter{
Name: param.SelectElement("name").Text(),
Description: param.SelectElement("description").Text(),
DefaultValue: param.SelectElement("defaultValue").Text(),
- Type: ParameterTypeMap["hudson.model.StringParameterDefinition"],
+ Type: devops.ParameterTypeMap["hudson.model.StringParameterDefinition"],
})
case "hudson.model.BooleanParameterDefinition":
- *s = append(*s, &Parameter{
+ parameters = append(parameters, &devops.Parameter{
Name: param.SelectElement("name").Text(),
Description: param.SelectElement("description").Text(),
DefaultValue: param.SelectElement("defaultValue").Text(),
- Type: ParameterTypeMap["hudson.model.BooleanParameterDefinition"],
+ Type: devops.ParameterTypeMap["hudson.model.BooleanParameterDefinition"],
})
case "hudson.model.TextParameterDefinition":
- *s = append(*s, &Parameter{
+ parameters = append(parameters, &devops.Parameter{
Name: param.SelectElement("name").Text(),
Description: param.SelectElement("description").Text(),
DefaultValue: param.SelectElement("defaultValue").Text(),
- Type: ParameterTypeMap["hudson.model.TextParameterDefinition"],
+ Type: devops.ParameterTypeMap["hudson.model.TextParameterDefinition"],
})
case "hudson.model.FileParameterDefinition":
- *s = append(*s, &Parameter{
+ parameters = append(parameters, &devops.Parameter{
Name: param.SelectElement("name").Text(),
Description: param.SelectElement("description").Text(),
- Type: ParameterTypeMap["hudson.model.FileParameterDefinition"],
+ Type: devops.ParameterTypeMap["hudson.model.FileParameterDefinition"],
})
case "hudson.model.PasswordParameterDefinition":
- *s = append(*s, &Parameter{
+ parameters = append(parameters, &devops.Parameter{
Name: param.SelectElement("name").Text(),
Description: param.SelectElement("description").Text(),
DefaultValue: param.SelectElement("name").Text(),
- Type: ParameterTypeMap["hudson.model.PasswordParameterDefinition"],
+ Type: devops.ParameterTypeMap["hudson.model.PasswordParameterDefinition"],
})
case "hudson.model.ChoiceParameterDefinition":
- choiceParameter := &Parameter{
+ choiceParameter := &devops.Parameter{
Name: param.SelectElement("name").Text(),
Description: param.SelectElement("description").Text(),
- Type: ParameterTypeMap["hudson.model.ChoiceParameterDefinition"],
+ Type: devops.ParameterTypeMap["hudson.model.ChoiceParameterDefinition"],
}
choices := param.SelectElement("choices").SelectElement("a").SelectElements("string")
for _, choice := range choices {
choiceParameter.DefaultValue += fmt.Sprintf("%s\n", choice.Text())
}
choiceParameter.DefaultValue = strings.TrimSpace(choiceParameter.DefaultValue)
- *s = append(*s, choiceParameter)
+ parameters = append(parameters, choiceParameter)
default:
- *s = append(*s, &Parameter{
+ parameters = append(parameters, &devops.Parameter{
Name: param.SelectElement("name").Text(),
Description: param.SelectElement("description").Text(),
DefaultValue: "unknown",
@@ -400,110 +231,112 @@ func (s *Parameters) fromEtree(properties *etree.Element) *Parameters {
}
}
}
- return s
+ return ¶meters
}
-func (s *GitSource) appendToEtree(source *etree.Element) *GitSource {
+func appendGitSourceToEtree(source *etree.Element, gitSource *devops.GitSource) {
source.CreateAttr("class", "jenkins.plugins.git.GitSCMSource")
source.CreateAttr("plugin", "git")
- source.CreateElement("id").SetText(s.ScmId)
- source.CreateElement("remote").SetText(s.Url)
- if s.CredentialId != "" {
- source.CreateElement("credentialsId").SetText(s.CredentialId)
+ source.CreateElement("id").SetText(gitSource.ScmId)
+ source.CreateElement("remote").SetText(gitSource.Url)
+ if gitSource.CredentialId != "" {
+ source.CreateElement("credentialsId").SetText(gitSource.CredentialId)
}
traits := source.CreateElement("traits")
- if s.DiscoverBranches {
+ if gitSource.DiscoverBranches {
traits.CreateElement("jenkins.plugins.git.traits.BranchDiscoveryTrait")
}
- if s.CloneOption != nil {
+ if gitSource.CloneOption != nil {
cloneExtension := traits.CreateElement("jenkins.plugins.git.traits.CloneOptionTrait").CreateElement("extension")
cloneExtension.CreateAttr("class", "hudson.plugins.git.extensions.impl.CloneOption")
- cloneExtension.CreateElement("shallow").SetText(strconv.FormatBool(s.CloneOption.Shallow))
+ cloneExtension.CreateElement("shallow").SetText(strconv.FormatBool(gitSource.CloneOption.Shallow))
cloneExtension.CreateElement("noTags").SetText(strconv.FormatBool(false))
cloneExtension.CreateElement("honorRefspec").SetText(strconv.FormatBool(true))
cloneExtension.CreateElement("reference")
- if s.CloneOption.Timeout >= 0 {
- cloneExtension.CreateElement("timeout").SetText(strconv.Itoa(s.CloneOption.Timeout))
+ if gitSource.CloneOption.Timeout >= 0 {
+ cloneExtension.CreateElement("timeout").SetText(strconv.Itoa(gitSource.CloneOption.Timeout))
} else {
cloneExtension.CreateElement("timeout").SetText(strconv.Itoa(10))
}
- if s.CloneOption.Depth >= 0 {
- cloneExtension.CreateElement("depth").SetText(strconv.Itoa(s.CloneOption.Depth))
+ if gitSource.CloneOption.Depth >= 0 {
+ cloneExtension.CreateElement("depth").SetText(strconv.Itoa(gitSource.CloneOption.Depth))
} else {
cloneExtension.CreateElement("depth").SetText(strconv.Itoa(1))
}
}
- if s.RegexFilter != "" {
+ if gitSource.RegexFilter != "" {
regexTraits := traits.CreateElement("jenkins.scm.impl.trait.RegexSCMHeadFilterTrait")
regexTraits.CreateAttr("plugin", "scm-api@2.4.0")
- regexTraits.CreateElement("regex").SetText(s.RegexFilter)
+ regexTraits.CreateElement("regex").SetText(gitSource.RegexFilter)
}
- return s
+ return
}
-func (s *GitSource) fromEtree(source *etree.Element) *GitSource {
+func getGitSourcefromEtree(source *etree.Element) *devops.GitSource {
+ var gitSource devops.GitSource
if credential := source.SelectElement("credentialsId"); credential != nil {
- s.CredentialId = credential.Text()
+ gitSource.CredentialId = credential.Text()
}
if remote := source.SelectElement("remote"); remote != nil {
- s.Url = remote.Text()
+ gitSource.Url = remote.Text()
}
traits := source.SelectElement("traits")
if branchDiscoverTrait := traits.SelectElement(
"jenkins.plugins.git.traits.BranchDiscoveryTrait"); branchDiscoverTrait != nil {
- s.DiscoverBranches = true
+ gitSource.DiscoverBranches = true
}
if cloneTrait := traits.SelectElement(
"jenkins.plugins.git.traits.CloneOptionTrait"); cloneTrait != nil {
if cloneExtension := cloneTrait.SelectElement(
"extension"); cloneExtension != nil {
- s.CloneOption = &GitCloneOption{}
+ gitSource.CloneOption = &devops.GitCloneOption{}
if value, err := strconv.ParseBool(cloneExtension.SelectElement("shallow").Text()); err == nil {
- s.CloneOption.Shallow = value
+ gitSource.CloneOption.Shallow = value
}
if value, err := strconv.ParseInt(cloneExtension.SelectElement("timeout").Text(), 10, 32); err == nil {
- s.CloneOption.Timeout = int(value)
+ gitSource.CloneOption.Timeout = int(value)
}
if value, err := strconv.ParseInt(cloneExtension.SelectElement("depth").Text(), 10, 32); err == nil {
- s.CloneOption.Depth = int(value)
+ gitSource.CloneOption.Depth = int(value)
}
}
}
if regexTrait := traits.SelectElement(
"jenkins.scm.impl.trait.RegexSCMHeadFilterTrait"); regexTrait != nil {
if regex := regexTrait.SelectElement("regex"); regex != nil {
- s.RegexFilter = regex.Text()
+ gitSource.RegexFilter = regex.Text()
}
}
- return s
+ return &gitSource
}
-func (s *GithubSource) fromEtree(source *etree.Element) *GithubSource {
+func getGithubSourcefromEtree(source *etree.Element) *devops.GithubSource {
+ var githubSource devops.GithubSource
if credential := source.SelectElement("credentialsId"); credential != nil {
- s.CredentialId = credential.Text()
+ githubSource.CredentialId = credential.Text()
}
if repoOwner := source.SelectElement("repoOwner"); repoOwner != nil {
- s.Owner = repoOwner.Text()
+ githubSource.Owner = repoOwner.Text()
}
if repository := source.SelectElement("repository"); repository != nil {
- s.Repo = repository.Text()
+ githubSource.Repo = repository.Text()
}
if apiUri := source.SelectElement("apiUri"); apiUri != nil {
- s.ApiUri = apiUri.Text()
+ githubSource.ApiUri = apiUri.Text()
}
traits := source.SelectElement("traits")
if branchDiscoverTrait := traits.SelectElement(
"org.jenkinsci.plugins.github__branch__source.BranchDiscoveryTrait"); branchDiscoverTrait != nil {
strategyId, _ := strconv.Atoi(branchDiscoverTrait.SelectElement("strategyId").Text())
- s.DiscoverBranches = strategyId
+ githubSource.DiscoverBranches = strategyId
}
if originPRDiscoverTrait := traits.SelectElement(
"org.jenkinsci.plugins.github__branch__source.OriginPullRequestDiscoveryTrait"); originPRDiscoverTrait != nil {
strategyId, _ := strconv.Atoi(originPRDiscoverTrait.SelectElement("strategyId").Text())
- s.DiscoverPRFromOrigin = strategyId
+ githubSource.DiscoverPRFromOrigin = strategyId
}
if forkPRDiscoverTrait := traits.SelectElement(
"org.jenkinsci.plugins.github__branch__source.ForkPullRequestDiscoveryTrait"); forkPRDiscoverTrait != nil {
@@ -512,22 +345,22 @@ func (s *GithubSource) fromEtree(source *etree.Element) *GithubSource {
trust := strings.Split(trustClass, "$")
switch trust[1] {
case "TrustContributors":
- s.DiscoverPRFromForks = &DiscoverPRFromForks{
+ githubSource.DiscoverPRFromForks = &devops.DiscoverPRFromForks{
Strategy: strategyId,
Trust: 1,
}
case "TrustEveryone":
- s.DiscoverPRFromForks = &DiscoverPRFromForks{
+ githubSource.DiscoverPRFromForks = &devops.DiscoverPRFromForks{
Strategy: strategyId,
Trust: 2,
}
case "TrustPermission":
- s.DiscoverPRFromForks = &DiscoverPRFromForks{
+ githubSource.DiscoverPRFromForks = &devops.DiscoverPRFromForks{
Strategy: strategyId,
Trust: 3,
}
case "TrustNobody":
- s.DiscoverPRFromForks = &DiscoverPRFromForks{
+ githubSource.DiscoverPRFromForks = &devops.DiscoverPRFromForks{
Strategy: strategyId,
Trust: 4,
}
@@ -536,15 +369,15 @@ func (s *GithubSource) fromEtree(source *etree.Element) *GithubSource {
"jenkins.plugins.git.traits.CloneOptionTrait"); cloneTrait != nil {
if cloneExtension := cloneTrait.SelectElement(
"extension"); cloneExtension != nil {
- s.CloneOption = &GitCloneOption{}
+ githubSource.CloneOption = &devops.GitCloneOption{}
if value, err := strconv.ParseBool(cloneExtension.SelectElement("shallow").Text()); err == nil {
- s.CloneOption.Shallow = value
+ githubSource.CloneOption.Shallow = value
}
if value, err := strconv.ParseInt(cloneExtension.SelectElement("timeout").Text(), 10, 32); err == nil {
- s.CloneOption.Timeout = int(value)
+ githubSource.CloneOption.Timeout = int(value)
}
if value, err := strconv.ParseInt(cloneExtension.SelectElement("depth").Text(), 10, 32); err == nil {
- s.CloneOption.Depth = int(value)
+ githubSource.CloneOption.Depth = int(value)
}
}
}
@@ -552,37 +385,37 @@ func (s *GithubSource) fromEtree(source *etree.Element) *GithubSource {
if regexTrait := traits.SelectElement(
"jenkins.scm.impl.trait.RegexSCMHeadFilterTrait"); regexTrait != nil {
if regex := regexTrait.SelectElement("regex"); regex != nil {
- s.RegexFilter = regex.Text()
+ githubSource.RegexFilter = regex.Text()
}
}
}
- return s
+ return &githubSource
}
-func (s *GithubSource) appendToEtree(source *etree.Element) *GithubSource {
+func appendGithubSourceToEtree(source *etree.Element, githubSource *devops.GithubSource) {
source.CreateAttr("class", "org.jenkinsci.plugins.github_branch_source.GitHubSCMSource")
source.CreateAttr("plugin", "github-branch-source")
- source.CreateElement("id").SetText(s.ScmId)
- source.CreateElement("credentialsId").SetText(s.CredentialId)
- source.CreateElement("repoOwner").SetText(s.Owner)
- source.CreateElement("repository").SetText(s.Repo)
- if s.ApiUri != "" {
- source.CreateElement("apiUri").SetText(s.ApiUri)
+ source.CreateElement("id").SetText(githubSource.ScmId)
+ source.CreateElement("credentialsId").SetText(githubSource.CredentialId)
+ source.CreateElement("repoOwner").SetText(githubSource.Owner)
+ source.CreateElement("repository").SetText(githubSource.Repo)
+ if githubSource.ApiUri != "" {
+ source.CreateElement("apiUri").SetText(githubSource.ApiUri)
}
traits := source.CreateElement("traits")
- if s.DiscoverBranches != 0 {
+ if githubSource.DiscoverBranches != 0 {
traits.CreateElement("org.jenkinsci.plugins.github__branch__source.BranchDiscoveryTrait").
- CreateElement("strategyId").SetText(strconv.Itoa(s.DiscoverBranches))
+ CreateElement("strategyId").SetText(strconv.Itoa(githubSource.DiscoverBranches))
}
- if s.DiscoverPRFromOrigin != 0 {
+ if githubSource.DiscoverPRFromOrigin != 0 {
traits.CreateElement("org.jenkinsci.plugins.github__branch__source.OriginPullRequestDiscoveryTrait").
- CreateElement("strategyId").SetText(strconv.Itoa(s.DiscoverPRFromOrigin))
+ CreateElement("strategyId").SetText(strconv.Itoa(githubSource.DiscoverPRFromOrigin))
}
- if s.DiscoverPRFromForks != nil {
+ if githubSource.DiscoverPRFromForks != nil {
forkTrait := traits.CreateElement("org.jenkinsci.plugins.github__branch__source.ForkPullRequestDiscoveryTrait")
- forkTrait.CreateElement("strategyId").SetText(strconv.Itoa(s.DiscoverPRFromForks.Strategy))
+ forkTrait.CreateElement("strategyId").SetText(strconv.Itoa(githubSource.DiscoverPRFromForks.Strategy))
trustClass := "org.jenkinsci.plugins.github_branch_source.ForkPullRequestDiscoveryTrait$"
- switch s.DiscoverPRFromForks.Trust {
+ switch githubSource.DiscoverPRFromForks.Trust {
case 1:
trustClass += "TrustContributors"
case 2:
@@ -595,34 +428,35 @@ func (s *GithubSource) appendToEtree(source *etree.Element) *GithubSource {
}
forkTrait.CreateElement("trust").CreateAttr("class", trustClass)
}
- if s.CloneOption != nil {
+ if githubSource.CloneOption != nil {
cloneExtension := traits.CreateElement("jenkins.plugins.git.traits.CloneOptionTrait").CreateElement("extension")
cloneExtension.CreateAttr("class", "hudson.plugins.git.extensions.impl.CloneOption")
- cloneExtension.CreateElement("shallow").SetText(strconv.FormatBool(s.CloneOption.Shallow))
+ cloneExtension.CreateElement("shallow").SetText(strconv.FormatBool(githubSource.CloneOption.Shallow))
cloneExtension.CreateElement("noTags").SetText(strconv.FormatBool(false))
cloneExtension.CreateElement("honorRefspec").SetText(strconv.FormatBool(true))
cloneExtension.CreateElement("reference")
- if s.CloneOption.Timeout >= 0 {
- cloneExtension.CreateElement("timeout").SetText(strconv.Itoa(s.CloneOption.Timeout))
+ if githubSource.CloneOption.Timeout >= 0 {
+ cloneExtension.CreateElement("timeout").SetText(strconv.Itoa(githubSource.CloneOption.Timeout))
} else {
cloneExtension.CreateElement("timeout").SetText(strconv.Itoa(10))
}
- if s.CloneOption.Depth >= 0 {
- cloneExtension.CreateElement("depth").SetText(strconv.Itoa(s.CloneOption.Depth))
+ if githubSource.CloneOption.Depth >= 0 {
+ cloneExtension.CreateElement("depth").SetText(strconv.Itoa(githubSource.CloneOption.Depth))
} else {
cloneExtension.CreateElement("depth").SetText(strconv.Itoa(1))
}
}
- if s.RegexFilter != "" {
+ if githubSource.RegexFilter != "" {
regexTraits := traits.CreateElement("jenkins.scm.impl.trait.RegexSCMHeadFilterTrait")
regexTraits.CreateAttr("plugin", "scm-api@2.4.0")
- regexTraits.CreateElement("regex").SetText(s.RegexFilter)
+ regexTraits.CreateElement("regex").SetText(githubSource.RegexFilter)
}
- return s
+ return
}
-func (s *BitbucketServerSource) fromEtree(source *etree.Element) *BitbucketServerSource {
+func getBitbucketServerSourceFromEtree(source *etree.Element) *devops.BitbucketServerSource {
+ var s devops.BitbucketServerSource
if credential := source.SelectElement("credentialsId"); credential != nil {
s.CredentialId = credential.Text()
}
@@ -653,17 +487,17 @@ func (s *BitbucketServerSource) fromEtree(source *etree.Element) *BitbucketServe
trust := strings.Split(trustClass, "$")
switch trust[1] {
case "TrustEveryone":
- s.DiscoverPRFromForks = &DiscoverPRFromForks{
+ s.DiscoverPRFromForks = &devops.DiscoverPRFromForks{
Strategy: strategyId,
Trust: 1,
}
case "TrustTeamForks":
- s.DiscoverPRFromForks = &DiscoverPRFromForks{
+ s.DiscoverPRFromForks = &devops.DiscoverPRFromForks{
Strategy: strategyId,
Trust: 2,
}
case "TrustNobody":
- s.DiscoverPRFromForks = &DiscoverPRFromForks{
+ s.DiscoverPRFromForks = &devops.DiscoverPRFromForks{
Strategy: strategyId,
Trust: 3,
}
@@ -672,7 +506,7 @@ func (s *BitbucketServerSource) fromEtree(source *etree.Element) *BitbucketServe
"jenkins.plugins.git.traits.CloneOptionTrait"); cloneTrait != nil {
if cloneExtension := cloneTrait.SelectElement(
"extension"); cloneExtension != nil {
- s.CloneOption = &GitCloneOption{}
+ s.CloneOption = &devops.GitCloneOption{}
if value, err := strconv.ParseBool(cloneExtension.SelectElement("shallow").Text()); err == nil {
s.CloneOption.Shallow = value
}
@@ -692,10 +526,10 @@ func (s *BitbucketServerSource) fromEtree(source *etree.Element) *BitbucketServe
}
}
}
- return s
+ return &s
}
-func (s *BitbucketServerSource) appendToEtree(source *etree.Element) *BitbucketServerSource {
+func appendBitbucketServerSourceToEtree(source *etree.Element, s *devops.BitbucketServerSource) {
source.CreateAttr("class", "com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSource")
source.CreateAttr("plugin", "cloudbees-bitbucket-branch-source")
source.CreateElement("id").SetText(s.ScmId)
@@ -753,10 +587,11 @@ func (s *BitbucketServerSource) appendToEtree(source *etree.Element) *BitbucketS
regexTraits.CreateAttr("plugin", "scm-api@2.4.0")
regexTraits.CreateElement("regex").SetText(s.RegexFilter)
}
- return s
+ return
}
-func (s *SvnSource) fromEtree(source *etree.Element) *SvnSource {
+func getSvnSourcefromEtree(source *etree.Element) *devops.SvnSource {
+ var s devops.SvnSource
if remote := source.SelectElement("remoteBase"); remote != nil {
s.Remote = remote.Text()
}
@@ -772,10 +607,10 @@ func (s *SvnSource) fromEtree(source *etree.Element) *SvnSource {
if excludes := source.SelectElement("excludes"); excludes != nil {
s.Excludes = excludes.Text()
}
- return s
+ return &s
}
-func (s *SvnSource) appendToEtree(source *etree.Element) *SvnSource {
+func appendSvnSourceToEtree(source *etree.Element, s *devops.SvnSource) {
source.CreateAttr("class", "jenkins.scm.impl.subversion.SubversionSCMSource")
source.CreateAttr("plugin", "subversion")
source.CreateElement("id").SetText(s.ScmId)
@@ -791,10 +626,11 @@ func (s *SvnSource) appendToEtree(source *etree.Element) *SvnSource {
if s.Excludes != "" {
source.CreateElement("excludes").SetText(s.Excludes)
}
- return nil
+ return
}
-func (s *SingleSvnSource) fromEtree(source *etree.Element) *SingleSvnSource {
+func getSingleSvnSourceFromEtree(source *etree.Element) *devops.SingleSvnSource {
+ var s devops.SingleSvnSource
if scm := source.SelectElement("scm"); scm != nil {
if locations := scm.SelectElement("locations"); locations != nil {
if moduleLocations := locations.SelectElement("hudson.scm.SubversionSCM_-ModuleLocation"); moduleLocations != nil {
@@ -807,10 +643,10 @@ func (s *SingleSvnSource) fromEtree(source *etree.Element) *SingleSvnSource {
}
}
}
- return s
+ return &s
}
-func (s *SingleSvnSource) appendToEtree(source *etree.Element) *SingleSvnSource {
+func appendSingleSvnSourceToEtree(source *etree.Element, s *devops.SingleSvnSource) {
source.CreateAttr("class", "jenkins.scm.impl.SingleSCMSource")
source.CreateAttr("plugin", "scm-api")
@@ -843,26 +679,27 @@ func (s *SingleSvnSource) appendToEtree(source *etree.Element) *SingleSvnSource
source.CreateElement("filterChangelog").SetText("false")
source.CreateElement("quietOperation").SetText("true")
- return s
+ return
}
-func (s *MultiBranchJobTrigger) appendToEtree(properties *etree.Element) *MultiBranchJobTrigger {
+func appendMultiBranchJobTriggerToEtree(properties *etree.Element, s *devops.MultiBranchJobTrigger) {
triggerProperty := properties.CreateElement("org.jenkinsci.plugins.workflow.multibranch.PipelineTriggerProperty")
triggerProperty.CreateAttr("plugin", "multibranch-action-triggers")
triggerProperty.CreateElement("createActionJobsToTrigger").SetText(s.CreateActionJobsToTrigger)
triggerProperty.CreateElement("deleteActionJobsToTrigger").SetText(s.DeleteActionJobsToTrigger)
- return s
+ return
}
-func (s *MultiBranchJobTrigger) fromEtree(properties *etree.Element) *MultiBranchJobTrigger {
+func getMultiBranchJobTriggerfromEtree(properties *etree.Element) *devops.MultiBranchJobTrigger {
+ var s devops.MultiBranchJobTrigger
triggerProperty := properties.SelectElement("org.jenkinsci.plugins.workflow.multibranch.PipelineTriggerProperty")
if triggerProperty != nil {
s.CreateActionJobsToTrigger = triggerProperty.SelectElement("createActionJobsToTrigger").Text()
s.DeleteActionJobsToTrigger = triggerProperty.SelectElement("deleteActionJobsToTrigger").Text()
}
- return s
+ return &s
}
-func createMultiBranchPipelineConfigXml(projectName string, pipeline *MultiBranchPipeline) (string, error) {
+func createMultiBranchPipelineConfigXml(projectName string, pipeline *devops.MultiBranchPipeline) (string, error) {
doc := etree.NewDocument()
xmlString := `
@@ -896,7 +733,7 @@ func createMultiBranchPipelineConfigXml(projectName string, pipeline *MultiBranc
if pipeline.MultiBranchJobTrigger != nil {
properties := project.SelectElement("properties")
- pipeline.MultiBranchJobTrigger.appendToEtree(properties)
+ appendMultiBranchJobTriggerToEtree(properties, pipeline.MultiBranchJobTrigger)
}
if pipeline.Discarder != nil {
@@ -939,27 +776,15 @@ func createMultiBranchPipelineConfigXml(projectName string, pipeline *MultiBranc
switch pipeline.SourceType {
case "git":
- gitDefine := pipeline.GitSource
- gitDefine.ScmId = projectName + pipeline.Name
- gitDefine.appendToEtree(source)
+ appendGitSourceToEtree(source, pipeline.GitSource)
case "github":
- githubDefine := pipeline.GitHubSource
- githubDefine.ScmId = projectName + pipeline.Name
- githubDefine.appendToEtree(source)
+ appendGithubSourceToEtree(source, pipeline.GitHubSource)
case "svn":
- svnDefine := pipeline.SvnSource
- svnDefine.ScmId = projectName + pipeline.Name
- svnDefine.appendToEtree(source)
-
+ appendSvnSourceToEtree(source, pipeline.SvnSource)
case "single_svn":
- singSvnDefine := pipeline.SingleSvnSource
- singSvnDefine.ScmId = projectName + pipeline.Name
- singSvnDefine.appendToEtree(source)
-
+ appendSingleSvnSourceToEtree(source, pipeline.SingleSvnSource)
case "bitbucket_server":
- bitbucketServerDefine := pipeline.BitbucketServerSource
- bitbucketServerDefine.ScmId = projectName + pipeline.Name
- bitbucketServerDefine.appendToEtree(source)
+ appendBitbucketServerSourceToEtree(source, pipeline.BitbucketServerSource)
default:
return "", fmt.Errorf("unsupport source type")
@@ -977,8 +802,8 @@ func createMultiBranchPipelineConfigXml(projectName string, pipeline *MultiBranc
return replaceXmlVersion(stringXml, "1.0", "1.1"), err
}
-func parseMultiBranchPipelineConfigXml(config string) (*MultiBranchPipeline, error) {
- pipeline := &MultiBranchPipeline{}
+func parseMultiBranchPipelineConfigXml(config string) (*devops.MultiBranchPipeline, error) {
+ pipeline := &devops.MultiBranchPipeline{}
config = replaceXmlVersion(config, "1.1", "1.0")
doc := etree.NewDocument()
err := doc.ReadFromString(config)
@@ -992,15 +817,13 @@ func parseMultiBranchPipelineConfigXml(config string) (*MultiBranchPipeline, err
if properties := project.SelectElement("properties"); properties != nil {
if multibranchTrigger := properties.SelectElement(
"org.jenkinsci.plugins.workflow.multibranch.PipelineTriggerProperty"); multibranchTrigger != nil {
- trigger := &MultiBranchJobTrigger{}
- trigger.fromEtree(properties)
- pipeline.MultiBranchJobTrigger = trigger
+ pipeline.MultiBranchJobTrigger = getMultiBranchJobTriggerfromEtree(properties)
}
}
pipeline.Description = project.SelectElement("description").Text()
if discarder := project.SelectElement("orphanedItemStrategy"); discarder != nil {
- pipeline.Discarder = &DiscarderProperty{
+ pipeline.Discarder = &devops.DiscarderProperty{
DaysToKeep: discarder.SelectElement("daysToKeep").Text(),
NumToKeep: discarder.SelectElement("numToKeep").Text(),
}
@@ -1008,7 +831,7 @@ func parseMultiBranchPipelineConfigXml(config string) (*MultiBranchPipeline, err
if triggers := project.SelectElement("triggers"); triggers != nil {
if timerTrigger := triggers.SelectElement(
"com.cloudbees.hudson.plugins.folder.computed.PeriodicFolderTrigger"); timerTrigger != nil {
- pipeline.TimerTrigger = &TimerTrigger{
+ pipeline.TimerTrigger = &devops.TimerTrigger{
Interval: timerTrigger.SelectElement("interval").Text(),
}
}
@@ -1020,33 +843,23 @@ func parseMultiBranchPipelineConfigXml(config string) (*MultiBranchPipeline, err
source := branchSource.SelectElement("source")
switch source.SelectAttr("class").Value {
case "org.jenkinsci.plugins.github_branch_source.GitHubSCMSource":
- githubSource := &GithubSource{}
- githubSource.fromEtree(source)
- pipeline.GitHubSource = githubSource
+ pipeline.GitHubSource = getGithubSourcefromEtree(source)
pipeline.SourceType = "github"
case "com.cloudbees.jenkins.plugins.bitbucket.BitbucketSCMSource":
- bitbucketServerSource := &BitbucketServerSource{}
- bitbucketServerSource.fromEtree(source)
- pipeline.BitbucketServerSource = bitbucketServerSource
+ pipeline.BitbucketServerSource = getBitbucketServerSourceFromEtree(source)
pipeline.SourceType = "bitbucket_server"
case "jenkins.plugins.git.GitSCMSource":
- gitSource := &GitSource{}
- gitSource.fromEtree(source)
pipeline.SourceType = "git"
- pipeline.GitSource = gitSource
+ pipeline.GitSource = getGitSourcefromEtree(source)
case "jenkins.scm.impl.SingleSCMSource":
- singleSvnSource := &SingleSvnSource{}
- singleSvnSource.fromEtree(source)
pipeline.SourceType = "single_svn"
- pipeline.SingleSvnSource = singleSvnSource
+ pipeline.SingleSvnSource = getSingleSvnSourceFromEtree(source)
case "jenkins.scm.impl.subversion.SubversionSCMSource":
- svnSource := &SvnSource{}
- svnSource.fromEtree(source)
pipeline.SourceType = "svn"
- pipeline.SvnSource = svnSource
+ pipeline.SvnSource = getSvnSourcefromEtree(source)
}
}
}
@@ -1078,55 +891,3 @@ func toCrontab(millis int64) string {
return "H H * * *"
}
-
-func getBuildSonarResults(build *gojenkins.Build) ([]*SonarStatus, error) {
-
- sonarClient, err := client.ClientSets().SonarQube()
- if err != nil {
- return nil, err
- }
-
- actions := build.GetActions()
- sonarStatuses := make([]*SonarStatus, 0)
- for _, action := range actions {
- if action.ClassName == SonarAnalysisActionClass {
- sonarStatus := &SonarStatus{}
- taskOptions := &sonargo.CeTaskOption{
- Id: action.SonarTaskId,
- }
- ceTask, _, err := sonarClient.SonarQube().Ce.Task(taskOptions)
- if err != nil {
- klog.Errorf("get sonar task error [%+v]", err)
- continue
- }
- sonarStatus.Task = ceTask
- measuresComponentOption := &sonargo.MeasuresComponentOption{
- Component: ceTask.Task.ComponentKey,
- AdditionalFields: SonarAdditionalFields,
- MetricKeys: SonarMetricKeys,
- }
- measures, _, err := sonarClient.SonarQube().Measures.Component(measuresComponentOption)
- if err != nil {
- klog.Errorf("get sonar task error [%+v]", err)
- continue
- }
- sonarStatus.Measures = measures
-
- issuesSearchOption := &sonargo.IssuesSearchOption{
- AdditionalFields: "_all",
- ComponentKeys: ceTask.Task.ComponentKey,
- Resolved: "false",
- Ps: "10",
- S: "FILE_LINE",
- Facets: "severities,types",
- }
- issuesSearch, _, err := sonarClient.SonarQube().Issues.Search(issuesSearchOption)
- sonarStatus.Issues = issuesSearch
- jenkinsAction := action
- sonarStatus.JenkinsAction = &jenkinsAction
-
- sonarStatuses = append(sonarStatuses, sonarStatus)
- }
- }
- return sonarStatuses, nil
-}
diff --git a/pkg/models/devops/project_pipeline_test.go b/pkg/simple/client/devops/jenkins/pipeline_internal_test.go
similarity index 82%
rename from pkg/models/devops/project_pipeline_test.go
rename to pkg/simple/client/devops/jenkins/pipeline_internal_test.go
index 4f572b554b5204414e48b72caf4b44177862b0c8..478a3fa4782c29b30310c0fb5a2a64e050033cb8 100644
--- a/pkg/models/devops/project_pipeline_test.go
+++ b/pkg/simple/client/devops/jenkins/pipeline_internal_test.go
@@ -1,25 +1,13 @@
-/*
-Copyright 2019 The KubeSphere Authors.
-Licensed under the Apache License, Version 2.0 (the "License");
-you may not use this file except in compliance with the License.
-You may obtain a copy of the License at
- http://www.apache.org/licenses/LICENSE-2.0
-Unless required by applicable law or agreed to in writing, software
-distributed under the License is distributed on an "AS IS" BASIS,
-WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-See the License for the specific language governing permissions and
-limitations under the License.
-*/
-
-package devops
+package jenkins
import (
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
"reflect"
"testing"
)
func Test_NoScmPipelineConfig(t *testing.T) {
- inputs := []*NoScmPipeline{
+ inputs := []*devops.NoScmPipeline{
{
Name: "",
Description: "for test",
@@ -54,12 +42,12 @@ func Test_NoScmPipelineConfig(t *testing.T) {
}
func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
- inputs := []*NoScmPipeline{
+ inputs := []*devops.NoScmPipeline{
{
Name: "",
Description: "for test",
Jenkinsfile: "node{echo 'hello'}",
- Discarder: &DiscarderProperty{
+ Discarder: &devops.DiscarderProperty{
"3", "5",
},
},
@@ -67,7 +55,7 @@ func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
Name: "",
Description: "for test",
Jenkinsfile: "node{echo 'hello'}",
- Discarder: &DiscarderProperty{
+ Discarder: &devops.DiscarderProperty{
"3", "",
},
},
@@ -75,7 +63,7 @@ func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
Name: "",
Description: "for test",
Jenkinsfile: "node{echo 'hello'}",
- Discarder: &DiscarderProperty{
+ Discarder: &devops.DiscarderProperty{
"", "21321",
},
},
@@ -83,7 +71,7 @@ func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
Name: "",
Description: "for test",
Jenkinsfile: "node{echo 'hello'}",
- Discarder: &DiscarderProperty{
+ Discarder: &devops.DiscarderProperty{
"", "",
},
},
@@ -105,13 +93,13 @@ func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
}
func Test_NoScmPipelineConfig_Param(t *testing.T) {
- inputs := []*NoScmPipeline{
+ inputs := []*devops.NoScmPipeline{
{
Name: "",
Description: "for test",
Jenkinsfile: "node{echo 'hello'}",
- Parameters: &Parameters{
- &Parameter{
+ Parameters: &devops.Parameters{
+ &devops.Parameter{
Name: "d",
DefaultValue: "a\nb",
Type: "choice",
@@ -123,26 +111,26 @@ func Test_NoScmPipelineConfig_Param(t *testing.T) {
Name: "",
Description: "for test",
Jenkinsfile: "node{echo 'hello'}",
- Parameters: &Parameters{
- &Parameter{
+ Parameters: &devops.Parameters{
+ &devops.Parameter{
Name: "a",
DefaultValue: "abc",
Type: "string",
Description: "fortest",
},
- &Parameter{
+ &devops.Parameter{
Name: "b",
DefaultValue: "false",
Type: "boolean",
Description: "fortest",
},
- &Parameter{
+ &devops.Parameter{
Name: "c",
DefaultValue: "password \n aaa",
Type: "text",
Description: "fortest",
},
- &Parameter{
+ &devops.Parameter{
Name: "d",
DefaultValue: "a\nb",
Type: "choice",
@@ -168,12 +156,12 @@ func Test_NoScmPipelineConfig_Param(t *testing.T) {
}
func Test_NoScmPipelineConfig_Trigger(t *testing.T) {
- inputs := []*NoScmPipeline{
+ inputs := []*devops.NoScmPipeline{
{
Name: "",
Description: "for test",
Jenkinsfile: "node{echo 'hello'}",
- TimerTrigger: &TimerTrigger{
+ TimerTrigger: &devops.TimerTrigger{
Cron: "1 1 1 * * *",
},
},
@@ -182,7 +170,7 @@ func Test_NoScmPipelineConfig_Trigger(t *testing.T) {
Name: "",
Description: "for test",
Jenkinsfile: "node{echo 'hello'}",
- RemoteTrigger: &RemoteTrigger{
+ RemoteTrigger: &devops.RemoteTrigger{
Token: "abc",
},
},
@@ -190,10 +178,10 @@ func Test_NoScmPipelineConfig_Trigger(t *testing.T) {
Name: "",
Description: "for test",
Jenkinsfile: "node{echo 'hello'}",
- TimerTrigger: &TimerTrigger{
+ TimerTrigger: &devops.TimerTrigger{
Cron: "1 1 1 * * *",
},
- RemoteTrigger: &RemoteTrigger{
+ RemoteTrigger: &devops.RemoteTrigger{
Token: "abc",
},
},
@@ -217,34 +205,34 @@ func Test_NoScmPipelineConfig_Trigger(t *testing.T) {
func Test_MultiBranchPipelineConfig(t *testing.T) {
- inputs := []*MultiBranchPipeline{
+ inputs := []*devops.MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "git",
- GitSource: &GitSource{},
+ GitSource: &devops.GitSource{},
},
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "github",
- GitHubSource: &GithubSource{},
+ GitHubSource: &devops.GithubSource{},
},
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "single_svn",
- SingleSvnSource: &SingleSvnSource{},
+ SingleSvnSource: &devops.SingleSvnSource{},
},
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "svn",
- SvnSource: &SvnSource{},
+ SvnSource: &devops.SvnSource{},
},
}
for _, input := range inputs {
@@ -265,17 +253,17 @@ func Test_MultiBranchPipelineConfig(t *testing.T) {
func Test_MultiBranchPipelineConfig_Discarder(t *testing.T) {
- inputs := []*MultiBranchPipeline{
+ inputs := []*devops.MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "git",
- Discarder: &DiscarderProperty{
+ Discarder: &devops.DiscarderProperty{
DaysToKeep: "1",
NumToKeep: "2",
},
- GitSource: &GitSource{},
+ GitSource: &devops.GitSource{},
},
}
for _, input := range inputs {
@@ -295,16 +283,16 @@ func Test_MultiBranchPipelineConfig_Discarder(t *testing.T) {
}
func Test_MultiBranchPipelineConfig_TimerTrigger(t *testing.T) {
- inputs := []*MultiBranchPipeline{
+ inputs := []*devops.MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "git",
- TimerTrigger: &TimerTrigger{
+ TimerTrigger: &devops.TimerTrigger{
Interval: "12345566",
},
- GitSource: &GitSource{},
+ GitSource: &devops.GitSource{},
},
}
for _, input := range inputs {
@@ -325,16 +313,16 @@ func Test_MultiBranchPipelineConfig_TimerTrigger(t *testing.T) {
func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
- inputs := []*MultiBranchPipeline{
+ inputs := []*devops.MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "git",
- TimerTrigger: &TimerTrigger{
+ TimerTrigger: &devops.TimerTrigger{
Interval: "12345566",
},
- GitSource: &GitSource{
+ GitSource: &devops.GitSource{
Url: "https://github.com/kubesphere/devops",
CredentialId: "git",
DiscoverBranches: true,
@@ -345,17 +333,17 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "github",
- TimerTrigger: &TimerTrigger{
+ TimerTrigger: &devops.TimerTrigger{
Interval: "12345566",
},
- GitHubSource: &GithubSource{
+ GitHubSource: &devops.GithubSource{
Owner: "kubesphere",
Repo: "devops",
CredentialId: "github",
ApiUri: "https://api.github.com",
DiscoverBranches: 1,
DiscoverPRFromOrigin: 2,
- DiscoverPRFromForks: &DiscoverPRFromForks{
+ DiscoverPRFromForks: &devops.DiscoverPRFromForks{
Strategy: 1,
Trust: 1,
},
@@ -366,17 +354,17 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "bitbucket_server",
- TimerTrigger: &TimerTrigger{
+ TimerTrigger: &devops.TimerTrigger{
Interval: "12345566",
},
- BitbucketServerSource: &BitbucketServerSource{
+ BitbucketServerSource: &devops.BitbucketServerSource{
Owner: "kubesphere",
Repo: "devops",
CredentialId: "github",
ApiUri: "https://api.github.com",
DiscoverBranches: 1,
DiscoverPRFromOrigin: 2,
- DiscoverPRFromForks: &DiscoverPRFromForks{
+ DiscoverPRFromForks: &devops.DiscoverPRFromForks{
Strategy: 1,
Trust: 1,
},
@@ -388,10 +376,10 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "svn",
- TimerTrigger: &TimerTrigger{
+ TimerTrigger: &devops.TimerTrigger{
Interval: "12345566",
},
- SvnSource: &SvnSource{
+ SvnSource: &devops.SvnSource{
Remote: "https://api.svn.com/bcd",
CredentialId: "svn",
Excludes: "truck",
@@ -403,10 +391,10 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "single_svn",
- TimerTrigger: &TimerTrigger{
+ TimerTrigger: &devops.TimerTrigger{
Interval: "12345566",
},
- SingleSvnSource: &SingleSvnSource{
+ SingleSvnSource: &devops.SingleSvnSource{
Remote: "https://api.svn.com/bcd",
CredentialId: "svn",
},
@@ -431,17 +419,17 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
func Test_MultiBranchPipelineCloneConfig(t *testing.T) {
- inputs := []*MultiBranchPipeline{
+ inputs := []*devops.MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "git",
- GitSource: &GitSource{
+ GitSource: &devops.GitSource{
Url: "https://github.com/kubesphere/devops",
CredentialId: "git",
DiscoverBranches: true,
- CloneOption: &GitCloneOption{
+ CloneOption: &devops.GitCloneOption{
Shallow: false,
Depth: 3,
Timeout: 20,
@@ -453,18 +441,18 @@ func Test_MultiBranchPipelineCloneConfig(t *testing.T) {
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "github",
- GitHubSource: &GithubSource{
+ GitHubSource: &devops.GithubSource{
Owner: "kubesphere",
Repo: "devops",
CredentialId: "github",
ApiUri: "https://api.github.com",
DiscoverBranches: 1,
DiscoverPRFromOrigin: 2,
- DiscoverPRFromForks: &DiscoverPRFromForks{
+ DiscoverPRFromForks: &devops.DiscoverPRFromForks{
Strategy: 1,
Trust: 1,
},
- CloneOption: &GitCloneOption{
+ CloneOption: &devops.GitCloneOption{
Shallow: false,
Depth: 3,
Timeout: 20,
@@ -492,13 +480,13 @@ func Test_MultiBranchPipelineCloneConfig(t *testing.T) {
func Test_MultiBranchPipelineRegexFilter(t *testing.T) {
- inputs := []*MultiBranchPipeline{
+ inputs := []*devops.MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "git",
- GitSource: &GitSource{
+ GitSource: &devops.GitSource{
Url: "https://github.com/kubesphere/devops",
CredentialId: "git",
DiscoverBranches: true,
@@ -510,14 +498,14 @@ func Test_MultiBranchPipelineRegexFilter(t *testing.T) {
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "github",
- GitHubSource: &GithubSource{
+ GitHubSource: &devops.GithubSource{
Owner: "kubesphere",
Repo: "devops",
CredentialId: "github",
ApiUri: "https://api.github.com",
DiscoverBranches: 1,
DiscoverPRFromOrigin: 2,
- DiscoverPRFromForks: &DiscoverPRFromForks{
+ DiscoverPRFromForks: &devops.DiscoverPRFromForks{
Strategy: 1,
Trust: 1,
},
@@ -545,26 +533,26 @@ func Test_MultiBranchPipelineRegexFilter(t *testing.T) {
func Test_MultiBranchPipelineMultibranchTrigger(t *testing.T) {
- inputs := []*MultiBranchPipeline{
+ inputs := []*devops.MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "github",
- GitHubSource: &GithubSource{
+ GitHubSource: &devops.GithubSource{
Owner: "kubesphere",
Repo: "devops",
CredentialId: "github",
ApiUri: "https://api.github.com",
DiscoverBranches: 1,
DiscoverPRFromOrigin: 2,
- DiscoverPRFromForks: &DiscoverPRFromForks{
+ DiscoverPRFromForks: &devops.DiscoverPRFromForks{
Strategy: 1,
Trust: 1,
},
RegexFilter: ".*",
},
- MultiBranchJobTrigger: &MultiBranchJobTrigger{
+ MultiBranchJobTrigger: &devops.MultiBranchJobTrigger{
CreateActionJobsToTrigger: "abc",
DeleteActionJobsToTrigger: "ddd",
},
@@ -574,20 +562,20 @@ func Test_MultiBranchPipelineMultibranchTrigger(t *testing.T) {
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "github",
- GitHubSource: &GithubSource{
+ GitHubSource: &devops.GithubSource{
Owner: "kubesphere",
Repo: "devops",
CredentialId: "github",
ApiUri: "https://api.github.com",
DiscoverBranches: 1,
DiscoverPRFromOrigin: 2,
- DiscoverPRFromForks: &DiscoverPRFromForks{
+ DiscoverPRFromForks: &devops.DiscoverPRFromForks{
Strategy: 1,
Trust: 1,
},
RegexFilter: ".*",
},
- MultiBranchJobTrigger: &MultiBranchJobTrigger{
+ MultiBranchJobTrigger: &devops.MultiBranchJobTrigger{
CreateActionJobsToTrigger: "abc",
},
},
@@ -596,20 +584,20 @@ func Test_MultiBranchPipelineMultibranchTrigger(t *testing.T) {
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "github",
- GitHubSource: &GithubSource{
+ GitHubSource: &devops.GithubSource{
Owner: "kubesphere",
Repo: "devops",
CredentialId: "github",
ApiUri: "https://api.github.com",
DiscoverBranches: 1,
DiscoverPRFromOrigin: 2,
- DiscoverPRFromForks: &DiscoverPRFromForks{
+ DiscoverPRFromForks: &devops.DiscoverPRFromForks{
Strategy: 1,
Trust: 1,
},
RegexFilter: ".*",
},
- MultiBranchJobTrigger: &MultiBranchJobTrigger{
+ MultiBranchJobTrigger: &devops.MultiBranchJobTrigger{
DeleteActionJobsToTrigger: "ddd",
},
},
diff --git a/pkg/gojenkins/pipeline_model_converter.go b/pkg/simple/client/devops/jenkins/pipeline_model_converter.go
similarity index 99%
rename from pkg/gojenkins/pipeline_model_converter.go
rename to pkg/simple/client/devops/jenkins/pipeline_model_converter.go
index 12b9003a10280c7bfbc5b40647339fdeddcad02d..46640a6e0aeed2536eeb07ad5a4d3835f565f7af 100644
--- a/pkg/gojenkins/pipeline_model_converter.go
+++ b/pkg/simple/client/devops/jenkins/pipeline_model_converter.go
@@ -11,7 +11,7 @@ See the License for the specific language governing permissions and
limitations under the License.
*/
-package gojenkins
+package jenkins
import (
"errors"
diff --git a/pkg/simple/client/devops/jenkins/project.go b/pkg/simple/client/devops/jenkins/project.go
new file mode 100644
index 0000000000000000000000000000000000000000..43579e688bf60cbb86024e7379a060e0cbc9a5f4
--- /dev/null
+++ b/pkg/simple/client/devops/jenkins/project.go
@@ -0,0 +1,109 @@
+package jenkins
+
+import (
+ "github.com/emicklei/go-restful"
+ "k8s.io/klog"
+ "kubesphere.io/kubesphere/pkg/api/devops/v1alpha2"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "net/http"
+ "sync"
+)
+
+type DevOpsProjectRoleResponse struct {
+ ProjectRole *ProjectRole
+ Err error
+}
+
+func (j *Jenkins) CreateDevOpsProject(username string, project *v1alpha2.DevOpsProject) (*v1alpha2.DevOpsProject, error) {
+ _, err := j.CreateFolder(project.ProjectId, project.Description)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ var addRoleCh = make(chan *DevOpsProjectRoleResponse, 8)
+ var addRoleWg sync.WaitGroup
+ for role, permission := range JenkinsProjectPermissionMap {
+ addRoleWg.Add(1)
+ go func(role string, permission ProjectPermissionIds) {
+ _, err := j.AddProjectRole(GetProjectRoleName(project.ProjectId, role),
+ GetProjectRolePattern(project.ProjectId), permission, true)
+ addRoleCh <- &DevOpsProjectRoleResponse{nil, err}
+ addRoleWg.Done()
+ }(role, permission)
+ }
+ for role, permission := range JenkinsPipelinePermissionMap {
+ addRoleWg.Add(1)
+ go func(role string, permission ProjectPermissionIds) {
+ _, err := j.AddProjectRole(GetPipelineRoleName(project.ProjectId, role),
+ GetPipelineRolePattern(project.ProjectId), permission, true)
+ addRoleCh <- &DevOpsProjectRoleResponse{nil, err}
+ addRoleWg.Done()
+ }(role, permission)
+ }
+ addRoleWg.Wait()
+ close(addRoleCh)
+ for addRoleResponse := range addRoleCh {
+ if addRoleResponse.Err != nil {
+ klog.Errorf("%+v", addRoleResponse.Err)
+ return nil, restful.NewError(GetJenkinsStatusCode(addRoleResponse.Err), addRoleResponse.Err.Error())
+ }
+ }
+
+ globalRole, err := j.GetGlobalRole(JenkinsAllUserRoleName)
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ if globalRole == nil {
+ _, err := j.AddGlobalRole(JenkinsAllUserRoleName, GlobalPermissionIds{
+ GlobalRead: true,
+ }, true)
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ }
+ err = globalRole.AssignRole(username)
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ projectRole, err := j.GetProjectRole(GetProjectRoleName(project.ProjectId, devops.ProjectOwner))
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ err = projectRole.AssignRole(username)
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ pipelineRole, err := j.GetProjectRole(GetPipelineRoleName(project.ProjectId, devops.ProjectOwner))
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ err = pipelineRole.AssignRole(username)
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ return project, nil
+}
+
+func (j *Jenkins) DeleteDevOpsProject(projectId string) error {
+ _, err := j.DeleteJob(projectId)
+
+ if err != nil && GetJenkinsStatusCode(err) != http.StatusNotFound {
+ klog.Errorf("%+v", err)
+ return restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ roleNames := make([]string, 0)
+ for role := range JenkinsProjectPermissionMap {
+ roleNames = append(roleNames, GetProjectRoleName(projectId, role))
+ roleNames = append(roleNames, GetPipelineRoleName(projectId, role))
+ }
+ err = j.DeleteProjectRoles(roleNames...)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ return restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ return nil
+}
diff --git a/pkg/simple/client/devops/jenkins/project_pipeline.go b/pkg/simple/client/devops/jenkins/project_pipeline.go
new file mode 100644
index 0000000000000000000000000000000000000000..7768c2fb32e5f737b92f0e23a847ffbcff6d49e6
--- /dev/null
+++ b/pkg/simple/client/devops/jenkins/project_pipeline.go
@@ -0,0 +1,165 @@
+package jenkins
+
+import (
+ "fmt"
+ "github.com/emicklei/go-restful"
+ "k8s.io/klog"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "net/http"
+)
+
+func (j *Jenkins) CreateProjectPipeline(projectId string, pipeline *devops.ProjectPipeline) (string, error) {
+ switch pipeline.Type {
+ case devops.NoScmPipelineType:
+
+ config, err := createPipelineConfigXml(pipeline.Pipeline)
+ if err != nil {
+ return "", restful.NewError(http.StatusInternalServerError, err.Error())
+ }
+
+ job, err := j.GetJob(pipeline.Pipeline.Name, projectId)
+ if job != nil {
+ err := fmt.Errorf("job name [%s] has been used", job.GetName())
+ return "", restful.NewError(http.StatusConflict, err.Error())
+ }
+
+ if err != nil && GetJenkinsStatusCode(err) != http.StatusNotFound {
+ return "", restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ _, err = j.CreateJobInFolder(config, pipeline.Pipeline.Name, projectId)
+ if err != nil {
+ return "", restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ return pipeline.Pipeline.Name, nil
+ case devops.MultiBranchPipelineType:
+ config, err := createMultiBranchPipelineConfigXml(projectId, pipeline.MultiBranchPipeline)
+ if err != nil {
+ return "", restful.NewError(http.StatusInternalServerError, err.Error())
+ }
+
+ job, err := j.GetJob(pipeline.MultiBranchPipeline.Name, projectId)
+ if job != nil {
+ err := fmt.Errorf("job name [%s] has been used", job.GetName())
+ return "", restful.NewError(http.StatusConflict, err.Error())
+ }
+
+ if err != nil && GetJenkinsStatusCode(err) != http.StatusNotFound {
+ return "", restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ _, err = j.CreateJobInFolder(config, pipeline.MultiBranchPipeline.Name, projectId)
+ if err != nil {
+ return "", restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ return pipeline.MultiBranchPipeline.Name, nil
+
+ default:
+ err := fmt.Errorf("error unsupport job type")
+ klog.Errorf("%+v", err)
+ return "", restful.NewError(http.StatusBadRequest, err.Error())
+ }
+}
+
+func (j *Jenkins) DeleteProjectPipeline(projectId string, pipelineId string) (string, error) {
+ _, err := j.DeleteJob(pipelineId, projectId)
+ if err != nil {
+ return "", restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ return pipelineId, nil
+
+}
+func (j *Jenkins) UpdateProjectPipeline(projectId string, pipeline *devops.ProjectPipeline) (string, error) {
+ switch pipeline.Type {
+ case devops.NoScmPipelineType:
+
+ config, err := createPipelineConfigXml(pipeline.Pipeline)
+ if err != nil {
+ return "", restful.NewError(http.StatusInternalServerError, err.Error())
+ }
+
+ job, err := j.GetJob(pipeline.Pipeline.Name, projectId)
+
+ if err != nil {
+ return "", restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ err = job.UpdateConfig(config)
+ if err != nil {
+ return "", restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ return pipeline.Pipeline.Name, nil
+ case devops.MultiBranchPipelineType:
+
+ config, err := createMultiBranchPipelineConfigXml(projectId, pipeline.MultiBranchPipeline)
+ if err != nil {
+ klog.Errorf("%+v", err)
+
+ return "", restful.NewError(http.StatusInternalServerError, err.Error())
+ }
+
+ job, err := j.GetJob(pipeline.MultiBranchPipeline.Name, projectId)
+
+ if err != nil {
+ return "", restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ err = job.UpdateConfig(config)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ return "", restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+
+ return pipeline.MultiBranchPipeline.Name, nil
+
+ default:
+ err := fmt.Errorf("error unsupport job type")
+ klog.Errorf("%+v", err)
+ return "", restful.NewError(http.StatusBadRequest, err.Error())
+ }
+}
+
+func (j *Jenkins) GetProjectPipelineConfig(projectId, pipelineId string) (*devops.ProjectPipeline, error) {
+ job, err := j.GetJob(pipelineId, projectId)
+ if err != nil {
+ klog.Errorf("%+v", err)
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ switch job.Raw.Class {
+ case "org.jenkinsci.plugins.workflow.job.WorkflowJob":
+ config, err := job.GetConfig()
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ pipeline, err := parsePipelineConfigXml(config)
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ pipeline.Name = pipelineId
+ return &devops.ProjectPipeline{
+ Type: devops.NoScmPipelineType,
+ Pipeline: pipeline,
+ }, nil
+
+ case "org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject":
+ config, err := job.GetConfig()
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ pipeline, err := parseMultiBranchPipelineConfigXml(config)
+ if err != nil {
+ return nil, restful.NewError(GetJenkinsStatusCode(err), err.Error())
+ }
+ pipeline.Name = pipelineId
+ return &devops.ProjectPipeline{
+ Type: devops.MultiBranchPipelineType,
+ MultiBranchPipeline: pipeline,
+ }, nil
+ default:
+ klog.Errorf("%+v", err)
+ return nil, restful.NewError(http.StatusBadRequest, err.Error())
+ }
+}
diff --git a/pkg/simple/client/devops/jenkins/pure_request.go b/pkg/simple/client/devops/jenkins/pure_request.go
new file mode 100644
index 0000000000000000000000000000000000000000..4943d06ce88d802f277425b73f8677126b210bad
--- /dev/null
+++ b/pkg/simple/client/devops/jenkins/pure_request.go
@@ -0,0 +1,54 @@
+package jenkins
+
+import (
+ "k8s.io/klog"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "net/http"
+ "net/url"
+ "time"
+)
+
+// TODO: deprecated, use SendJenkinsRequestWithHeaderResp() instead
+func (j *Jenkins) SendPureRequest(path string, httpParameters *devops.HttpParameters) ([]byte, error) {
+ resBody, _, err := j.SendPureRequestWithHeaderResp(path, httpParameters)
+
+ return resBody, err
+}
+
+func (j *Jenkins) SendPureRequestWithHeaderResp(path string, httpParameters *devops.HttpParameters) ([]byte, http.Header, error) {
+ Url, err := url.Parse(j.Server + path)
+ if err != nil {
+ klog.Error(err)
+ return nil, nil, err
+ }
+
+ client := &http.Client{Timeout: 30 * time.Second}
+
+ newRequest := &http.Request{
+ Method: httpParameters.Method,
+ URL: Url,
+ Header: httpParameters.Header,
+ Body: httpParameters.Body,
+ Form: httpParameters.Form,
+ PostForm: httpParameters.PostForm,
+ }
+
+ resp, err := client.Do(newRequest)
+ if err != nil {
+ klog.Error(err)
+ return nil, nil, err
+ }
+
+ resBody, _ := getRespBody(resp)
+ defer resp.Body.Close()
+
+ if resp.StatusCode >= http.StatusBadRequest {
+ klog.Errorf("%+v", string(resBody))
+ jkerr := new(JkError)
+ jkerr.Code = resp.StatusCode
+ jkerr.Message = string(resBody)
+ return nil, nil, jkerr
+ }
+
+ return resBody, resp.Header, nil
+}
diff --git a/pkg/gojenkins/request.go b/pkg/simple/client/devops/jenkins/request.go
similarity index 99%
rename from pkg/gojenkins/request.go
rename to pkg/simple/client/devops/jenkins/request.go
index 25cc3e06451cdcfadaf42b0d33a651a94f115e75..6239162eae4d1959f3d4aff54bb1cf563a21430e 100644
--- a/pkg/gojenkins/request.go
+++ b/pkg/simple/client/devops/jenkins/request.go
@@ -12,7 +12,7 @@
// License for the specific language governing permissions and limitations
// under the License.
-package gojenkins
+package jenkins
import (
"bytes"
diff --git a/pkg/gojenkins/role.go b/pkg/simple/client/devops/jenkins/role.go
similarity index 99%
rename from pkg/gojenkins/role.go
rename to pkg/simple/client/devops/jenkins/role.go
index 872d32655fea217c17f21f00acacb8479db93530..f8a7e643f65a3812c12f4750e9357a38e96eb9e6 100644
--- a/pkg/gojenkins/role.go
+++ b/pkg/simple/client/devops/jenkins/role.go
@@ -1,4 +1,4 @@
-package gojenkins
+package jenkins
import (
"errors"
diff --git a/pkg/simple/client/devops/jenkins/utils.go b/pkg/simple/client/devops/jenkins/utils.go
new file mode 100644
index 0000000000000000000000000000000000000000..f080fedc8df972a035aa258da202211f1230e39d
--- /dev/null
+++ b/pkg/simple/client/devops/jenkins/utils.go
@@ -0,0 +1,146 @@
+// Copyright 2015 Vadim Kravcenko
+//
+// Licensed under the Apache License, Version 2.0 (the "License"): you may
+// not use this file except in compliance with the License. You may obtain
+// a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+// WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+// License for the specific language governing permissions and limitations
+// under the License.
+
+package jenkins
+
+import (
+ "compress/gzip"
+ "encoding/json"
+ "github.com/asaskevich/govalidator"
+ "io"
+ "io/ioutil"
+ "k8s.io/klog"
+ "net/http"
+ "net/url"
+ "strconv"
+ "strings"
+ "time"
+ "unicode/utf8"
+)
+
+func makeJson(data interface{}) string {
+ str, err := json.Marshal(data)
+ if err != nil {
+ return ""
+ }
+ return string(json.RawMessage(str))
+}
+
+func Reverse(s string) string {
+ size := len(s)
+ buf := make([]byte, size)
+ for start := 0; start < size; {
+ r, n := utf8.DecodeRuneInString(s[start:])
+ start += n
+ utf8.EncodeRune(buf[size-start:], r)
+ }
+ return string(buf)
+}
+
+type JkError struct {
+ Message string `json:"message"`
+ Code int `json:"code"`
+}
+
+func (err *JkError) Error() string {
+ return err.Message
+}
+
+// Decompress response.body of JenkinsAPIResponse
+func getRespBody(resp *http.Response) ([]byte, error) {
+ var reader io.ReadCloser
+ if resp.Header.Get("Content-Encoding") == "gzip" {
+ reader, _ = gzip.NewReader(resp.Body)
+ } else {
+ reader = resp.Body
+ }
+ resBody, err := ioutil.ReadAll(reader)
+ if err != nil {
+ klog.Error(err)
+ return nil, err
+ }
+ return resBody, err
+
+}
+
+// parseJenkinsQuery Parse the special query of jenkins.
+// ParseQuery in the standard library makes the query not re-encode
+func parseJenkinsQuery(query string) (url.Values, error) {
+ m := make(url.Values)
+ err := error(nil)
+ for query != "" {
+ key := query
+ if i := strings.IndexAny(key, "&"); i >= 0 {
+ key, query = key[:i], key[i+1:]
+ } else {
+ query = ""
+ }
+ if key == "" {
+ continue
+ }
+ value := ""
+ if i := strings.Index(key, "="); i >= 0 {
+ key, value = key[:i], key[i+1:]
+ }
+ key, err1 := url.QueryUnescape(key)
+ if err1 != nil {
+ if err == nil {
+ err = err1
+ }
+ continue
+ }
+ value, err1 = url.QueryUnescape(value)
+ if err1 != nil {
+ if err == nil {
+ err = err1
+ }
+ continue
+ }
+ m[key] = append(m[key], value)
+ }
+ return m, err
+}
+
+type JenkinsBlueTime time.Time
+
+func (t *JenkinsBlueTime) UnmarshalJSON(b []byte) error {
+ if b == nil || strings.Trim(string(b), "\"") == "null" {
+ *t = JenkinsBlueTime(time.Time{})
+ return nil
+ }
+ j, err := time.Parse("2006-01-02T15:04:05.000-0700", strings.Trim(string(b), "\""))
+
+ if err != nil {
+ return err
+ }
+ *t = JenkinsBlueTime(j)
+ return nil
+}
+
+func (t JenkinsBlueTime) MarshalJSON() ([]byte, error) {
+ return json.Marshal(time.Time(t))
+}
+
+func GetJenkinsStatusCode(jenkinsErr error) int {
+ if code, err := strconv.Atoi(jenkinsErr.Error()); err == nil {
+ message := http.StatusText(code)
+ if !govalidator.IsNull(message) {
+ return code
+ }
+ }
+ if jErr, ok := jenkinsErr.(*ErrorResponse); ok {
+ return jErr.Response.StatusCode
+ }
+ return http.StatusInternalServerError
+}
diff --git a/pkg/simple/client/devops/member.go b/pkg/simple/client/devops/member.go
new file mode 100644
index 0000000000000000000000000000000000000000..eaa5a486fd030da5e3600103ce5b4ebfc42cb94a
--- /dev/null
+++ b/pkg/simple/client/devops/member.go
@@ -0,0 +1,48 @@
+package devops
+
+type ProjectMembership struct {
+ Username string `json:"username" description:"Member's username,username can uniquely identify a user"`
+ ProjectId string `json:"project_id" db:"project_id" description:"the DevOps Projects which project membership belongs to"`
+ Role string `json:"role" description:"DevOps Project membership's role type. e.g. owner '"`
+ Status string `json:"status" description:"Deprecated, Status of project membership. e.g. active "`
+ GrantBy string `json:"grand_by,omitempty" description:"Username of the user who assigned the role"`
+}
+
+type ProjectMemberOperator interface {
+ AddProjectMember(membership *ProjectMembership) (*ProjectMembership, error)
+ UpdateProjectMember(oldMembership, newMembership *ProjectMembership) (*ProjectMembership, error)
+ DeleteProjectMember(membership *ProjectMembership) (*ProjectMembership, error)
+}
+
+var DefaultRoles = []*Role{
+ {
+ Name: ProjectOwner,
+ Description: "Owner have access to do all the operations of a DevOps project and own the highest permissions as well.",
+ },
+ {
+ Name: ProjectMaintainer,
+ Description: "Maintainer have access to manage pipeline and credential configuration in a DevOps project.",
+ },
+ {
+ Name: ProjectDeveloper,
+ Description: "Developer is able to view and trigger the pipeline.",
+ },
+ {
+ Name: ProjectReporter,
+ Description: "Reporter is only allowed to view the status of the pipeline.",
+ },
+}
+
+var AllRoleSlice = []string{ProjectDeveloper, ProjectReporter, ProjectMaintainer, ProjectOwner}
+
+const (
+ ProjectOwner = "owner"
+ ProjectMaintainer = "maintainer"
+ ProjectDeveloper = "developer"
+ ProjectReporter = "reporter"
+)
+
+type Role struct {
+ Name string `json:"name" description:"role's name e.g. owner'"`
+ Description string `json:"description" description:"role 's description'"`
+}
diff --git a/pkg/models/devops/json.go b/pkg/simple/client/devops/pipeline.go
similarity index 92%
rename from pkg/models/devops/json.go
rename to pkg/simple/client/devops/pipeline.go
index 05ec9808e44e342cab3c8952e724f013167deff8..8043a50fefc47b806c4794976232d45169bd5020 100644
--- a/pkg/models/devops/json.go
+++ b/pkg/simple/client/devops/pipeline.go
@@ -1,21 +1,15 @@
-/*
-
- Copyright 2019 The KubeSphere Authors.
-
- Licensed under the Apache License, Version 2.0 (the "License");
- you may not use this file except in compliance with the License.
- You may obtain a copy of the License at
-
- http://www.apache.org/licenses/LICENSE-2.0
+package devops
- Unless required by applicable law or agreed to in writing, software
- distributed under the License is distributed on an "AS IS" BASIS,
- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- See the License for the specific language governing permissions and
- limitations under the License.
+import (
+ "io"
+ "net/http"
+ "net/url"
+)
-*/
-package devops
+type PipelineList struct {
+ Items []Pipeline `json:"items"`
+ Total int `json:"total_count"`
+}
// GetPipeline & SearchPipelines
type Pipeline struct {
@@ -85,7 +79,7 @@ type Pipeline struct {
}
// GetPipeBranchRun & SearchPipelineRuns
-type BranchPipelineRun struct {
+type PipelineRunList struct {
Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."`
Links struct {
PrevRun struct {
@@ -316,7 +310,7 @@ type OrgRepo struct {
}
// StopPipeline
-type StopPipe struct {
+type StopPipeline struct {
Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."`
Links struct {
Parent struct {
@@ -390,7 +384,7 @@ type StopPipe struct {
}
// ReplayPipeline
-type ReplayPipe struct {
+type ReplayPipeline struct {
Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."`
Links struct {
Parent struct {
@@ -468,7 +462,7 @@ type Artifacts struct {
}
// GetPipeBranch
-type PipeBranch struct {
+type PipelineBranch struct {
Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."`
Links struct {
Self struct {
@@ -598,7 +592,7 @@ type RunPayload struct {
} `json:"parameters,omitempty"`
}
-type QueuedBlueRun struct {
+type RunPipeline struct {
Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."`
Links struct {
Parent struct {
@@ -1108,22 +1102,18 @@ type NodesDetail struct {
Actions []interface{} `json:"actions,omitempty" description:"the list of all actions"`
DisplayDescription interface{} `json:"displayDescription,omitempty" description:"display description"`
DisplayName string `json:"displayName,omitempty" description:"display name"`
- DurationInMillis int `json:"durationInMillis,omitempty" description:"duration time in millis"`
+ DurationInMillis int `json:"durationInMillis,omitempty" description:"duration time in mullis"`
ID string `json:"id,omitempty" description:"id"`
Input *Input `json:"input,omitempty" description:"the action should user input"`
Result string `json:"result,omitempty" description:"the result of pipeline run. e.g. SUCCESS"`
StartTime string `json:"startTime,omitempty" description:"the time of start"`
- State string `json:"state,omitempty" description:"run state. e.g. SKIPPED"`
+ State string `json:"state,omitempty" description:"run state. e.g. FINISHED"`
Type string `json:"type,omitempty" description:"type"`
CauseOfBlockage interface{} `json:"causeOfBlockage,omitempty" description:"the cause of blockage"`
- Edges []struct {
- Class string `json:"_class,omitempty" description:"It’s a fully qualified name and is an identifier of the producer of this resource's capability."`
- ID string `json:"id,omitempty" description:"id"`
- Type string `json:"type,omitempty" description:"type"`
- } `json:"edges,omitempty"`
- FirstParent interface{} `json:"firstParent,omitempty" description:"first parent"`
- Restartable bool `json:"restartable,omitempty" description:"restartable or not"`
- Steps []NodeSteps `json:"steps,omitempty" description:"steps"`
+ Edges []interface{} `json:"edges,omitempty" description:"edges"`
+ FirstParent interface{} `json:"firstParent,omitempty" description:"first parent"`
+ Restartable bool `json:"restartable,omitempty" description:"restartable or not"`
+ Steps []NodeSteps `json:"steps,omitempty" description:"steps"`
}
type NodesStepsIndex struct {
@@ -1145,3 +1135,65 @@ type Input struct {
Parameters []interface{} `json:"parameters,omitempty" description:"the parameters of check action"`
Submitter interface{} `json:"submitter,omitempty" description:"check submitter"`
}
+
+type HttpParameters struct {
+ Method string `json:"method,omitempty"`
+ Header http.Header `json:"header,omitempty"`
+ Body io.ReadCloser `json:"body,omitempty"`
+ Form url.Values `json:"form,omitempty"`
+ PostForm url.Values `json:"postForm,omitempty"`
+ Url *url.URL `json:"url,omitempty"`
+}
+
+type PipelineOperator interface {
+
+ // Pipelinne operator interface
+ GetPipeline(projectName, pipelineName string, httpParameters *HttpParameters) (*Pipeline, error)
+ ListPipelines(httpParameters *HttpParameters) (*PipelineList, error)
+ GetPipelineRun(projectName, pipelineName, runId string, httpParameters *HttpParameters) (*PipelineRun, error)
+ ListPipelineRuns(projectName, pipelineName string, httpParameters *HttpParameters) (*PipelineRunList, error)
+ StopPipeline(projectName, pipelineName, runId string, httpParameters *HttpParameters) (*StopPipeline, error)
+ ReplayPipeline(projectName, pipelineName, runId string, httpParameters *HttpParameters) (*ReplayPipeline, error)
+ RunPipeline(projectName, pipelineName string, httpParameters *HttpParameters) (*RunPipeline, error)
+ GetArtifacts(projectName, pipelineName, runId string, httpParameters *HttpParameters) ([]Artifacts, error)
+ GetRunLog(projectName, pipelineName, runId string, httpParameters *HttpParameters) ([]byte, error)
+ GetStepLog(projectName, pipelineName, runId, nodeId, stepId string, httpParameters *HttpParameters) ([]byte, http.Header, error)
+ GetNodeSteps(projectName, pipelineName, runId, nodeId string, httpParameters *HttpParameters) ([]NodeSteps, error)
+ GetPipelineRunNodes(projectName, pipelineName, runId string, httpParameters *HttpParameters) ([]PipelineRunNodes, error)
+ SubmitInputStep(projectName, pipelineName, runId, nodeId, stepId string, httpParameters *HttpParameters) ([]byte, error)
+
+ //BranchPipelinne operator interface
+ GetBranchPipeline(projectName, pipelineName, branchName string, httpParameters *HttpParameters) (*BranchPipeline, error)
+ GetBranchPipelineRun(projectName, pipelineName, branchName, runId string, httpParameters *HttpParameters) (*PipelineRun, error)
+ StopBranchPipeline(projectName, pipelineName, branchName, runId string, httpParameters *HttpParameters) (*StopPipeline, error)
+ ReplayBranchPipeline(projectName, pipelineName, branchName, runId string, httpParameters *HttpParameters) (*ReplayPipeline, error)
+ RunBranchPipeline(projectName, pipelineName, branchName string, httpParameters *HttpParameters) (*RunPipeline, error)
+ GetBranchArtifacts(projectName, pipelineName, branchName, runId string, httpParameters *HttpParameters) ([]Artifacts, error)
+ GetBranchRunLog(projectName, pipelineName, branchName, runId string, httpParameters *HttpParameters) ([]byte, error)
+ GetBranchStepLog(projectName, pipelineName, branchName, runId, nodeId, stepId string, httpParameters *HttpParameters) ([]byte, http.Header, error)
+ GetBranchNodeSteps(projectName, pipelineName, branchName, runId, nodeId string, httpParameters *HttpParameters) ([]NodeSteps, error)
+ GetBranchPipelineRunNodes(projectName, pipelineName, branchName, runId string, httpParameters *HttpParameters) ([]BranchPipelineRunNodes, error)
+ SubmitBranchInputStep(projectName, pipelineName, branchName, runId, nodeId, stepId string, httpParameters *HttpParameters) ([]byte, error)
+ GetPipelineBranch(projectName, pipelineName string, httpParameters *HttpParameters) (*PipelineBranch, error)
+ ScanBranch(projectName, pipelineName string, httpParameters *HttpParameters) ([]byte, error)
+
+ // Common pipeline operator interface
+ GetConsoleLog(projectName, pipelineName string, httpParameters *HttpParameters) ([]byte, error)
+ GetCrumb(httpParameters *HttpParameters) (*Crumb, error)
+
+ // SCM operator interface
+ GetSCMServers(scmId string, httpParameters *HttpParameters) ([]SCMServer, error)
+ GetSCMOrg(scmId string, httpParameters *HttpParameters) ([]SCMOrg, error)
+ GetOrgRepo(scmId, organizationId string, httpParameters *HttpParameters) ([]OrgRepo, error)
+ CreateSCMServers(scmId string, httpParameters *HttpParameters) (*SCMServer, error)
+ Validate(scmId string, httpParameters *HttpParameters) (*Validates, error)
+
+ //Webhook operator interface
+ GetNotifyCommit(httpParameters *HttpParameters) ([]byte, error)
+ GithubWebhook(httpParameters *HttpParameters) ([]byte, error)
+
+ CheckScriptCompile(projectName, pipelineName string, httpParameters *HttpParameters) (*CheckScript, error)
+ CheckCron(projectName string, httpParameters *HttpParameters) (*CheckCronRes, error)
+ ToJenkinsfile(httpParameters *HttpParameters) (*ResJenkinsfile, error)
+ ToJson(httpParameters *HttpParameters) (*ResJson, error)
+}
diff --git a/pkg/simple/client/devops/project.go b/pkg/simple/client/devops/project.go
new file mode 100644
index 0000000000000000000000000000000000000000..2ce7a782b13db9fa0bdf4fef0d1c9962ce861bde
--- /dev/null
+++ b/pkg/simple/client/devops/project.go
@@ -0,0 +1,8 @@
+package devops
+
+import "kubesphere.io/kubesphere/pkg/api/devops/v1alpha2"
+
+type ProjectOperator interface {
+ CreateDevOpsProject(username string, project *v1alpha2.DevOpsProject) (*v1alpha2.DevOpsProject, error)
+ DeleteDevOpsProject(projectId string) error
+}
diff --git a/pkg/simple/client/devops/project_pipeline.go b/pkg/simple/client/devops/project_pipeline.go
new file mode 100644
index 0000000000000000000000000000000000000000..587b037ce729265999dcafdf89bc4abadf587c75
--- /dev/null
+++ b/pkg/simple/client/devops/project_pipeline.go
@@ -0,0 +1,144 @@
+package devops
+
+const (
+ NoScmPipelineType = "pipeline"
+ MultiBranchPipelineType = "multi-branch-pipeline"
+)
+
+type Parameters []*Parameter
+
+var ParameterTypeMap = map[string]string{
+ "hudson.model.StringParameterDefinition": "string",
+ "hudson.model.ChoiceParameterDefinition": "choice",
+ "hudson.model.TextParameterDefinition": "text",
+ "hudson.model.BooleanParameterDefinition": "boolean",
+ "hudson.model.FileParameterDefinition": "file",
+ "hudson.model.PasswordParameterDefinition": "password",
+}
+
+type ProjectPipeline struct {
+ Type string `json:"type" description:"type of devops pipeline, in scm or no scm"`
+ Pipeline *NoScmPipeline `json:"pipeline,omitempty" description:"no scm pipeline structs"`
+ MultiBranchPipeline *MultiBranchPipeline `json:"multi_branch_pipeline,omitempty" description:"in scm pipeline structs"`
+}
+
+type NoScmPipeline struct {
+ Name string `json:"name" description:"name of pipeline"`
+ Description string `json:"descriptio,omitempty" description:"description of pipeline"`
+ Discarder *DiscarderProperty `json:"discarder,omitempty" description:"Discarder of pipeline, managing when to drop a pipeline"`
+ Parameters *Parameters `json:"parameters,omitempty" description:"Parameters define of pipeline,user could pass param when run pipeline"`
+ DisableConcurrent bool `json:"disable_concurrent,omitempty" mapstructure:"disable_concurrent" description:"Whether to prohibit the pipeline from running in parallel"`
+ TimerTrigger *TimerTrigger `json:"timer_trigger,omitempty" mapstructure:"timer_trigger" description:"Timer to trigger pipeline run"`
+ RemoteTrigger *RemoteTrigger `json:"remote_trigger,omitempty" mapstructure:"remote_trigger" description:"Remote api define to trigger pipeline run"`
+ Jenkinsfile string `json:"jenkinsfile,omitempty" description:"Jenkinsfile's content'"`
+}
+
+type MultiBranchPipeline struct {
+ Name string `json:"name" description:"name of pipeline"`
+ Description string `json:"descriptio,omitempty" description:"description of pipeline"`
+ Discarder *DiscarderProperty `json:"discarder,omitempty" description:"Discarder of pipeline, managing when to drop a pipeline"`
+ TimerTrigger *TimerTrigger `json:"timer_trigger,omitempty" mapstructure:"timer_trigger" description:"Timer to trigger pipeline run"`
+ SourceType string `json:"source_type" description:"type of scm, such as github/git/svn"`
+ GitSource *GitSource `json:"git_source,omitempty" description:"git scm define"`
+ GitHubSource *GithubSource `json:"github_source,omitempty" description:"github scm define"`
+ SvnSource *SvnSource `json:"svn_source,omitempty" description:"multi branch svn scm define"`
+ SingleSvnSource *SingleSvnSource `json:"single_svn_source,omitempty" description:"single branch svn scm define"`
+ BitbucketServerSource *BitbucketServerSource `json:"bitbucket_server_source,omitempty" description:"bitbucket server scm defile"`
+ ScriptPath string `json:"script_path" mapstructure:"script_path" description:"script path in scm"`
+ MultiBranchJobTrigger *MultiBranchJobTrigger `json:"multibranch_job_trigger,omitempty" mapstructure:"multibranch_job_trigger" description:"Pipeline tasks that need to be triggered when branch creation/deletion"`
+}
+
+type GitSource struct {
+ ScmId string `json:"scm_id,omitempty" description:"uid of scm"`
+ Url string `json:"url,omitempty" mapstructure:"url" description:"url of git source"`
+ CredentialId string `json:"credential_id,omitempty" mapstructure:"credential_id" description:"credential id to access git source"`
+ DiscoverBranches bool `json:"discover_branches,omitempty" mapstructure:"discover_branches" description:"Whether to discover a branch"`
+ CloneOption *GitCloneOption `json:"git_clone_option,omitempty" mapstructure:"git_clone_option" description:"advavced git clone options"`
+ RegexFilter string `json:"regex_filter,omitempty" mapstructure:"regex_filter" description:"Regex used to match the name of the branch that needs to be run"`
+}
+
+type GithubSource struct {
+ ScmId string `json:"scm_id,omitempty" description:"uid of scm"`
+ Owner string `json:"owner,omitempty" mapstructure:"owner" description:"owner of github repo"`
+ Repo string `json:"repo,omitempty" mapstructure:"repo" description:"repo name of github repo"`
+ CredentialId string `json:"credential_id,omitempty" mapstructure:"credential_id" description:"credential id to access github source"`
+ ApiUri string `json:"api_uri,omitempty" mapstructure:"api_uri" description:"The api url can specify the location of the github apiserver.For private cloud configuration"`
+ DiscoverBranches int `json:"discover_branches,omitempty" mapstructure:"discover_branches" description:"Discover branch configuration"`
+ DiscoverPRFromOrigin int `json:"discover_pr_from_origin,omitempty" mapstructure:"discover_pr_from_origin" description:"Discover origin PR configuration"`
+ DiscoverPRFromForks *DiscoverPRFromForks `json:"discover_pr_from_forks,omitempty" mapstructure:"discover_pr_from_forks" description:"Discover fork PR configuration"`
+ CloneOption *GitCloneOption `json:"git_clone_option,omitempty" mapstructure:"git_clone_option" description:"advavced git clone options"`
+ RegexFilter string `json:"regex_filter,omitempty" mapstructure:"regex_filter" description:"Regex used to match the name of the branch that needs to be run"`
+}
+
+type MultiBranchJobTrigger struct {
+ CreateActionJobsToTrigger string `json:"create_action_job_to_trigger,omitempty" description:"pipeline name to trigger"`
+ DeleteActionJobsToTrigger string `json:"delete_action_job_to_trigger,omitempty" description:"pipeline name to trigger"`
+}
+
+type BitbucketServerSource struct {
+ ScmId string `json:"scm_id,omitempty" description:"uid of scm"`
+ Owner string `json:"owner,omitempty" mapstructure:"owner" description:"owner of github repo"`
+ Repo string `json:"repo,omitempty" mapstructure:"repo" description:"repo name of github repo"`
+ CredentialId string `json:"credential_id,omitempty" mapstructure:"credential_id" description:"credential id to access github source"`
+ ApiUri string `json:"api_uri,omitempty" mapstructure:"api_uri" description:"The api url can specify the location of the github apiserver.For private cloud configuration"`
+ DiscoverBranches int `json:"discover_branches,omitempty" mapstructure:"discover_branches" description:"Discover branch configuration"`
+ DiscoverPRFromOrigin int `json:"discover_pr_from_origin,omitempty" mapstructure:"discover_pr_from_origin" description:"Discover origin PR configuration"`
+ DiscoverPRFromForks *DiscoverPRFromForks `json:"discover_pr_from_forks,omitempty" mapstructure:"discover_pr_from_forks" description:"Discover fork PR configuration"`
+ CloneOption *GitCloneOption `json:"git_clone_option,omitempty" mapstructure:"git_clone_option" description:"advavced git clone options"`
+ RegexFilter string `json:"regex_filter,omitempty" mapstructure:"regex_filter" description:"Regex used to match the name of the branch that needs to be run"`
+}
+
+type GitCloneOption struct {
+ Shallow bool `json:"shallow,omitempty" mapstructure:"shallow" description:"Whether to use git shallow clone"`
+ Timeout int `json:"timeout,omitempty" mapstructure:"timeout" description:"git clone timeout mins"`
+ Depth int `json:"depth,omitempty" mapstructure:"depth" description:"git clone depth"`
+}
+
+type SvnSource struct {
+ ScmId string `json:"scm_id,omitempty" description:"uid of scm"`
+ Remote string `json:"remote,omitempty" description:"remote address url"`
+ CredentialId string `json:"credential_id,omitempty" mapstructure:"credential_id" description:"credential id to access svn source"`
+ Includes string `json:"includes,omitempty" description:"branches to run pipeline"`
+ Excludes string `json:"excludes,omitempty" description:"branches do not run pipeline"`
+}
+type SingleSvnSource struct {
+ ScmId string `json:"scm_id,omitempty" description:"uid of scm"`
+ Remote string `json:"remote,omitempty" description:"remote address url"`
+ CredentialId string `json:"credential_id,omitempty" mapstructure:"credential_id" description:"credential id to access svn source"`
+}
+
+type DiscoverPRFromForks struct {
+ Strategy int `json:"strategy,omitempty" mapstructure:"strategy" description:"github discover strategy"`
+ Trust int `json:"trust,omitempty" mapstructure:"trust" description:"trust user type"`
+}
+
+type DiscarderProperty struct {
+ DaysToKeep string `json:"days_to_keep,omitempty" mapstructure:"days_to_keep" description:"days to keep pipeline"`
+ NumToKeep string `json:"num_to_keep,omitempty" mapstructure:"num_to_keep" description:"nums to keep pipeline"`
+}
+
+type Parameter struct {
+ Name string `json:"name" description:"name of param"`
+ DefaultValue string `json:"default_value,omitempty" mapstructure:"default_value" description:"default value of param"`
+ Type string `json:"type" description:"type of param"`
+ Description string `json:"description,omitempty" description:"description of pipeline"`
+}
+
+type TimerTrigger struct {
+ // user in no scm job
+ Cron string `json:"cron,omitempty" description:"jenkins cron script"`
+
+ // use in multi-branch job
+ Interval string `json:"interval,omitempty" description:"interval ms"`
+}
+
+type RemoteTrigger struct {
+ Token string `json:"token,omitempty" description:"remote trigger token"`
+}
+
+type ProjectPipelineOperator interface {
+ CreateProjectPipeline(projectId string, pipeline *ProjectPipeline) (string, error)
+ DeleteProjectPipeline(projectId string, pipelineId string) (string, error)
+ UpdateProjectPipeline(projectId string, pipeline *ProjectPipeline) (string, error)
+ GetProjectPipelineConfig(projectId, pipelineId string) (*ProjectPipeline, error)
+}
diff --git a/pkg/simple/client/factory.go b/pkg/simple/client/factory.go
index 223fa6ce0b53df267aae54acbf8fd917d4d95448..d19325ea2e3b1d6162ea8d95661cfc12e8753079 100644
--- a/pkg/simple/client/factory.go
+++ b/pkg/simple/client/factory.go
@@ -4,6 +4,7 @@ import (
"errors"
"kubesphere.io/kubesphere/pkg/simple/client/cache"
"kubesphere.io/kubesphere/pkg/simple/client/devops"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins"
esclient "kubesphere.io/kubesphere/pkg/simple/client/elasticsearch"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/kubesphere"
@@ -22,7 +23,7 @@ type ClientSetOptions struct {
mySQLOptions *mysql.Options
redisOptions *cache.Options
kubernetesOptions *k8s.KubernetesOptions
- devopsOptions *devops.Options
+ devopsOptions *jenkins.Options
sonarqubeOptions *sonarqube.Options
ldapOptions *ldap.Options
s3Options *s3.Options
@@ -38,7 +39,7 @@ func NewClientSetOptions() *ClientSetOptions {
redisOptions: cache.NewRedisOptions(),
kubernetesOptions: k8s.NewKubernetesOptions(),
ldapOptions: ldap.NewLdapOptions(),
- devopsOptions: devops.NewDevopsOptions(),
+ devopsOptions: jenkins.NewDevopsOptions(),
sonarqubeOptions: sonarqube.NewSonarQubeOptions(),
s3Options: s3.NewS3Options(),
openPitrixOptions: openpitrix.NewOpenPitrixOptions(),
@@ -63,7 +64,7 @@ func (c *ClientSetOptions) SetKubernetesOptions(options *k8s.KubernetesOptions)
return c
}
-func (c *ClientSetOptions) SetDevopsOptions(options *devops.Options) *ClientSetOptions {
+func (c *ClientSetOptions) SetDevopsOptions(options *jenkins.Options) *ClientSetOptions {
c.devopsOptions = options
return c
}
@@ -114,7 +115,7 @@ type ClientSet struct {
k8sClient k8s.Client
ldapClient *ldap.Client
- devopsClient *devops.Client
+ devopsClient *jenkins.Client
sonarQubeClient *sonarqube.Client
redisClient cache.Interface
s3Client s3.Interface
@@ -194,27 +195,28 @@ func (cs *ClientSet) Cache() (cache.Interface, error) {
}
}
-func (cs *ClientSet) Devops() (*devops.Client, error) {
- var err error
-
- if cs.csoptions.devopsOptions == nil || cs.csoptions.devopsOptions.Host == "" {
- return nil, ErrClientSetNotEnabled
- }
-
- if cs.devopsClient != nil {
- return cs.devopsClient, nil
- } else {
- mutex.Lock()
- defer mutex.Unlock()
-
- if cs.devopsClient == nil {
- cs.devopsClient, err = devops.NewDevopsClient(cs.csoptions.devopsOptions)
- if err != nil {
- return nil, err
- }
- }
- return cs.devopsClient, nil
- }
+func (cs *ClientSet) Devops() (devops.Interface, error) {
+ //var err error
+ //
+ //if cs.csoptions.devopsOptions == nil || cs.csoptions.devopsOptions.Host == "" {
+ // return nil, ErrClientSetNotEnabled
+ //}
+ //
+ //if cs.devopsClient != nil {
+ // return cs.devopsClient, nil
+ //} else {
+ // mutex.Lock()
+ // defer mutex.Unlock()
+ //
+ // if cs.devopsClient == nil {
+ // cs.devopsClient, err = jenkins.NewDevopsClient(cs.csoptions.devopsOptions)
+ // if err != nil {
+ // return nil, err
+ // }
+ // }
+ // return cs.devopsClient, nil
+ //}
+ return nil, nil
}
func (cs *ClientSet) SonarQube() (*sonarqube.Client, error) {
diff --git a/pkg/simple/client/monitoring/interface.go b/pkg/simple/client/monitoring/interface.go
index 6dfce3ca1aad72e06c1e7afdeeb366a67c56f3ab..8230be3a25fe0e45b95c24a8729a63514fa92cc1 100644
--- a/pkg/simple/client/monitoring/interface.go
+++ b/pkg/simple/client/monitoring/interface.go
@@ -1,39 +1,32 @@
package monitoring
-
type ClusterQuery struct {
-
}
type ClusterMetrics struct {
-
}
type WorkspaceQuery struct {
-
}
type WorkspaceMetrics struct {
-
}
type NamespaceQuery struct {
-
}
type NamespaceMetrics struct {
-
}
// Interface defines all the abstract behaviors of monitoring
type Interface interface {
- // Get
- GetClusterMetrics(query ClusterQuery) ClusterMetrics
+ // Get
+ GetClusterMetrics(query ClusterQuery) ClusterMetrics
- //
- GetWorkspaceMetrics(query WorkspaceQuery) WorkspaceMetrics
+ //
+ GetWorkspaceMetrics(query WorkspaceQuery) WorkspaceMetrics
- //
- GetNamespaceMetrics(query NamespaceQuery) NamespaceMetrics
+ //
+ GetNamespaceMetrics(query NamespaceQuery) NamespaceMetrics
}
diff --git a/pkg/simple/client/monitoring/prometheus.go b/pkg/simple/client/monitoring/prometheus.go
index d2e53895e1840da9445bda9cadacba9a8c4629ea..5b82066e631912b8ae7d6e83a7b031235dda2eb4 100644
--- a/pkg/simple/client/monitoring/prometheus.go
+++ b/pkg/simple/client/monitoring/prometheus.go
@@ -1,31 +1,31 @@
package monitoring
import (
- "net/http"
- "time"
+ "net/http"
+ "time"
)
// prometheus implements monitoring interface backed by Prometheus
type prometheus struct {
- options *Options
- client *http.Client
+ options *Options
+ client *http.Client
}
func NewPrometheus(options *Options) Interface {
- return &prometheus{
- options:options,
- client: &http.Client{ Timeout: 10 * time.Second },
- }
+ return &prometheus{
+ options: options,
+ client: &http.Client{Timeout: 10 * time.Second},
+ }
}
func (p prometheus) GetClusterMetrics(query ClusterQuery) ClusterMetrics {
- panic("implement me")
+ panic("implement me")
}
func (p prometheus) GetWorkspaceMetrics(query WorkspaceQuery) WorkspaceMetrics {
- panic("implement me")
+ panic("implement me")
}
func (p prometheus) GetNamespaceMetrics(query NamespaceQuery) NamespaceMetrics {
- panic("implement me")
+ panic("implement me")
}
diff --git a/pkg/simple/client/monitoring/prometheus_options.go b/pkg/simple/client/monitoring/prometheus_options.go
index b29e01d1b6f65256541a74d2560abdb04dca7198..0aed413c9dbb403d3c6ca56b08fb7ad2b8827952 100644
--- a/pkg/simple/client/monitoring/prometheus_options.go
+++ b/pkg/simple/client/monitoring/prometheus_options.go
@@ -1,41 +1,41 @@
package monitoring
import (
- "github.com/spf13/pflag"
+ "github.com/spf13/pflag"
)
type Options struct {
- Endpoint string `json:"endpoint,omitempty" yaml:"endpoint"`
- SecondaryEndpoint string `json:"secondaryEndpoint,omitempty" yaml:"secondaryEndpoint"`
+ Endpoint string `json:"endpoint,omitempty" yaml:"endpoint"`
+ SecondaryEndpoint string `json:"secondaryEndpoint,omitempty" yaml:"secondaryEndpoint"`
}
func NewPrometheusOptions() *Options {
- return &Options{
- Endpoint: "",
- SecondaryEndpoint: "",
- }
+ return &Options{
+ Endpoint: "",
+ SecondaryEndpoint: "",
+ }
}
func (s *Options) Validate() []error {
- var errs []error
- return errs
+ var errs []error
+ return errs
}
func (s *Options) ApplyTo(options *Options) {
- if s.Endpoint != "" {
- options.Endpoint = s.Endpoint
- }
+ if s.Endpoint != "" {
+ options.Endpoint = s.Endpoint
+ }
- if s.SecondaryEndpoint != "" {
- options.SecondaryEndpoint = s.SecondaryEndpoint
- }
+ if s.SecondaryEndpoint != "" {
+ options.SecondaryEndpoint = s.SecondaryEndpoint
+ }
}
func (s *Options) AddFlags(fs *pflag.FlagSet, c *Options) {
- fs.StringVar(&s.Endpoint, "prometheus-endpoint", c.Endpoint, ""+
- "Prometheus service endpoint which stores KubeSphere monitoring data, if left "+
- "blank, will use builtin metrics-server as data source.")
+ fs.StringVar(&s.Endpoint, "prometheus-endpoint", c.Endpoint, ""+
+ "Prometheus service endpoint which stores KubeSphere monitoring data, if left "+
+ "blank, will use builtin metrics-server as data source.")
- fs.StringVar(&s.SecondaryEndpoint, "prometheus-secondary-endpoint", c.SecondaryEndpoint, ""+
- "Prometheus secondary service endpoint, if left empty and endpoint is set, will use endpoint instead.")
+ fs.StringVar(&s.SecondaryEndpoint, "prometheus-secondary-endpoint", c.SecondaryEndpoint, ""+
+ "Prometheus secondary service endpoint, if left empty and endpoint is set, will use endpoint instead.")
}
diff --git a/pkg/simple/client/prometheus/prometheus.go b/pkg/simple/client/prometheus/prometheus.go
index e419ce203e383ca24d6623c2bf2875eadfa037c5..a24cb16071ab6c67a97d7eaa8690e3c56fa918ba 100644
--- a/pkg/simple/client/prometheus/prometheus.go
+++ b/pkg/simple/client/prometheus/prometheus.go
@@ -27,7 +27,6 @@ import (
"time"
)
-
type Client struct {
client *http.Client
endpoint string
diff --git a/pkg/simple/client/s3/fake/fakes3.go b/pkg/simple/client/s3/fake/fakes3.go
new file mode 100644
index 0000000000000000000000000000000000000000..f798033509e599f9adee0eb2d89cf8ccf3522777
--- /dev/null
+++ b/pkg/simple/client/s3/fake/fakes3.go
@@ -0,0 +1,43 @@
+package fake
+
+import (
+ "fmt"
+ "github.com/aws/aws-sdk-go/aws/awserr"
+ "github.com/aws/aws-sdk-go/service/s3"
+ "io"
+)
+
+type FakeS3 struct {
+ Storage map[string]*object
+}
+
+func NewFakeS3() *FakeS3 {
+ return &FakeS3{Storage: map[string]*object{}}
+}
+
+type object struct {
+ key string
+ fileName string
+ body io.Reader
+}
+
+func (s *FakeS3) Upload(key, fileName string, body io.Reader) error {
+ s.Storage[key] = &object{
+ key: key,
+ fileName: fileName,
+ body: body,
+ }
+ return nil
+}
+
+func (s *FakeS3) GetDownloadURL(key string, fileName string) (string, error) {
+ if o, ok := s.Storage[key]; ok {
+ return fmt.Sprintf("http://%s/%s", o.key, fileName), nil
+ }
+ return "", awserr.New(s3.ErrCodeNoSuchKey, "no such object", nil)
+}
+
+func (s *FakeS3) Delete(key string) error {
+ delete(s.Storage, key)
+ return nil
+}
diff --git a/pkg/simple/client/s3/fake/fakes3_test.go b/pkg/simple/client/s3/fake/fakes3_test.go
new file mode 100644
index 0000000000000000000000000000000000000000..6a5e80d5b4ce8a4c0967a52e4263a2c727a3545b
--- /dev/null
+++ b/pkg/simple/client/s3/fake/fakes3_test.go
@@ -0,0 +1,52 @@
+package fake
+
+import (
+ "fmt"
+ "testing"
+)
+
+func TestFakeS3(t *testing.T) {
+ s3 := NewFakeS3()
+ key := "hello"
+ fileName := "world"
+ err := s3.Upload(key, fileName, nil)
+ if err != nil {
+ t.Fatal(err)
+ }
+ o, ok := s3.storage["hello"]
+ if !ok {
+ t.Fatal("should have hello object")
+ }
+ if o.key != key || o.fileName != fileName {
+ t.Fatalf("key should be %s, fileName should be %s", key, fileName)
+ }
+
+ url, err := s3.GetDownloadURL(key, fileName+"1")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if url != fmt.Sprintf("http://%s/%s", key, fileName+"1") {
+ t.Fatalf("url should be %s", fmt.Sprintf("http://%s/%s", key, fileName+"1"))
+ }
+
+ url, err = s3.GetDownloadURL(key, fileName+"2")
+ if err != nil {
+ t.Fatal(err)
+ }
+ if url != fmt.Sprintf("http://%s/%s", key, fileName+"2") {
+ t.Fatalf("url should be %s", fmt.Sprintf("http://%s/%s", key, fileName+"2"))
+ }
+
+ err = s3.Delete(key)
+ if err != nil {
+ t.Fatal(err)
+ }
+ _, ok = s3.storage["hello"]
+ if ok {
+ t.Fatal("should not have hello object")
+ }
+ err = s3.Delete(key)
+ if err != nil {
+ t.Fatal(err)
+ }
+}
diff --git a/pkg/simple/client/s3/interface.go b/pkg/simple/client/s3/interface.go
index 594b8438dc6f3cf0b0e279959c5e690e3e0edc0f..96672ca0fcc22455e5ef27d6eb0ef8cb038eed56 100644
--- a/pkg/simple/client/s3/interface.go
+++ b/pkg/simple/client/s3/interface.go
@@ -2,15 +2,13 @@ package s3
import (
"io"
- "time"
)
type Interface interface {
// Upload uploads a object to storage and returns object location if succeeded
- Upload(key string, body io.Reader) (string, error)
+ Upload(key, fileName string, body io.Reader) error
- // Get retrieves and object's downloadable location if succeeded
- Get(key string, fileName string, expire time.Duration) (string, error)
+ GetDownloadURL(key string, fileName string) (string, error)
// Delete deletes an object by its key
Delete(key string) error
diff --git a/pkg/simple/client/s3/s3.go b/pkg/simple/client/s3/s3.go
index f74985f5ab7adbfdee73edcf8b7bf0e7a7800d4d..244f78c329c9d078ced884068a5c7901f33f2408 100644
--- a/pkg/simple/client/s3/s3.go
+++ b/pkg/simple/client/s3/s3.go
@@ -1,10 +1,13 @@
package s3
import (
+ "code.cloudfoundry.org/bytefmt"
+ "fmt"
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/aws/aws-sdk-go/aws/session"
"github.com/aws/aws-sdk-go/service/s3"
+ "github.com/aws/aws-sdk-go/service/s3/s3manager"
"io"
"k8s.io/klog"
"time"
@@ -16,16 +19,38 @@ type Client struct {
bucket string
}
-func (s *Client) Upload(key string, body io.Reader) (string, error) {
- panic("implement me")
+func (s *Client) Upload(key, fileName string, body io.Reader) error {
+ uploader := s3manager.NewUploader(s.s3Session, func(uploader *s3manager.Uploader) {
+ uploader.PartSize = 5 * bytefmt.MEGABYTE
+ uploader.LeavePartsOnError = true
+ })
+ _, err := uploader.Upload(&s3manager.UploadInput{
+ Bucket: aws.String(s.bucket),
+ Key: aws.String(key),
+ Body: body,
+ ContentDisposition: aws.String(fmt.Sprintf("attachment; filename=\"%s\"", fileName)),
+ })
+ return err
}
-func (s *Client) Get(key string, fileName string, expire time.Duration) (string, error) {
- panic("implement me")
+func (s *Client) GetDownloadURL(key string, fileName string) (string, error) {
+ req, _ := s.s3Client.GetObjectRequest(&s3.GetObjectInput{
+ Bucket: aws.String(s.bucket),
+ Key: aws.String(key),
+ ResponseContentDisposition: aws.String(fmt.Sprintf("attachment; filename=\"%s\"", fileName)),
+ })
+ return req.Presign(5 * time.Minute)
}
func (s *Client) Delete(key string) error {
- panic("implement me")
+ _, err := s.s3Client.DeleteObject(
+ &s3.DeleteObjectInput{Bucket: aws.String(s.bucket),
+ Key: aws.String(key),
+ })
+ if err != nil {
+ return err
+ }
+ return nil
}
func NewS3Client(options *Options) (Interface, error) {
@@ -55,7 +80,6 @@ func NewS3Client(options *Options) (Interface, error) {
}
func (s *Client) Client() *s3.S3 {
-
return s.s3Client
}
func (s *Client) Session() *session.Session {
diff --git a/pkg/simple/client/sonarqube/interface.go b/pkg/simple/client/sonarqube/interface.go
index 9873cf9ff9f6a76217e5f22b65a90add83135bcc..a7ab3782b21599921d8210df3ac41fb41a26c732 100644
--- a/pkg/simple/client/sonarqube/interface.go
+++ b/pkg/simple/client/sonarqube/interface.go
@@ -1,8 +1,68 @@
package sonarqube
-type Interface interface {
- //
- GetIssues()
+import (
+ sonargo "github.com/kubesphere/sonargo/sonar"
+ "k8s.io/klog"
+ "kubesphere.io/kubesphere/pkg/simple/client/devops"
+)
- //
+type SonarInterface interface {
+ GetSonarResultsByTaskIds(taskId ...string) ([]*SonarStatus, error)
+}
+
+type sonarQube struct {
+ client *sonargo.Client
+}
+
+const (
+ SonarAnalysisActionClass = "hudson.plugins.sonar.action.SonarAnalysisAction"
+ SonarMetricKeys = "alert_status,quality_gate_details,bugs,new_bugs,reliability_rating,new_reliability_rating,vulnerabilities,new_vulnerabilities,security_rating,new_security_rating,code_smells,new_code_smells,sqale_rating,new_maintainability_rating,sqale_index,new_technical_debt,coverage,new_coverage,new_lines_to_cover,tests,duplicated_lines_density,new_duplicated_lines_density,duplicated_blocks,ncloc,ncloc_language_distribution,projects,new_lines"
+ SonarAdditionalFields = "metrics,periods"
+)
+
+type SonarStatus struct {
+ Measures *sonargo.MeasuresComponentObject `json:"measures,omitempty"`
+ Issues *sonargo.IssuesSearchObject `json:"issues,omitempty"`
+ GeneralAction *devops.GeneralAction `json:"generalAction,omitempty"`
+ Task *sonargo.CeTaskObject `json:"task,omitempty"`
+}
+
+func (s *sonarQube) GetSonarResultsByTaskIds(taskIds ...string) ([]*SonarStatus, error) {
+ sonarStatuses := make([]*SonarStatus, 0)
+ for _, taskId := range taskIds {
+ sonarStatus := &SonarStatus{}
+ taskOptions := &sonargo.CeTaskOption{
+ Id: taskId,
+ }
+ ceTask, _, err := s.client.Ce.Task(taskOptions)
+ if err != nil {
+ klog.Errorf("get sonar task error [%+v]", err)
+ continue
+ }
+ sonarStatus.Task = ceTask
+ measuresComponentOption := &sonargo.MeasuresComponentOption{
+ Component: ceTask.Task.ComponentKey,
+ AdditionalFields: SonarAdditionalFields,
+ MetricKeys: SonarMetricKeys,
+ }
+ measures, _, err := s.client.Measures.Component(measuresComponentOption)
+ if err != nil {
+ klog.Errorf("get sonar task error [%+v]", err)
+ continue
+ }
+ sonarStatus.Measures = measures
+
+ issuesSearchOption := &sonargo.IssuesSearchOption{
+ AdditionalFields: "_all",
+ ComponentKeys: ceTask.Task.ComponentKey,
+ Resolved: "false",
+ Ps: "10",
+ S: "FILE_LINE",
+ Facets: "severities,types",
+ }
+ issuesSearch, _, err := s.client.Issues.Search(issuesSearchOption)
+ sonarStatus.Issues = issuesSearch
+ sonarStatuses = append(sonarStatuses, sonarStatus)
+ }
+ return sonarStatuses, nil
}
|