diff --git a/pkg/apiserver/apiserver.go b/pkg/apiserver/apiserver.go index 3376f980a82f65da1f043d299a0c2499a7143f91..8e786eeb2f6512d056a28389ce3d0d363b25ed1c 100644 --- a/pkg/apiserver/apiserver.go +++ b/pkg/apiserver/apiserver.go @@ -195,7 +195,8 @@ func (s *APIServer) installKubeSphereAPIs() { s.DevopsClient, s.SonarClient, s.KubernetesClient.KubeSphere(), - s.S3Client)) + s.S3Client, + s.Config.DevopsOptions.Host)) urlruntime.Must(devopsv1alpha3.AddToContainer(s.container, s.DevopsClient, s.KubernetesClient.Kubernetes(), diff --git a/pkg/kapis/devops/v1alpha2/register.go b/pkg/kapis/devops/v1alpha2/register.go index 9a01edb5cfad47df387b1866a52e47040c8cdd7b..fd3fabf4143df517c4d2adb9c3094e78d2268c92 100644 --- a/pkg/kapis/devops/v1alpha2/register.go +++ b/pkg/kapis/devops/v1alpha2/register.go @@ -17,20 +17,25 @@ limitations under the License. package v1alpha2 import ( + "fmt" "github.com/emicklei/go-restful" "github.com/emicklei/go-restful-openapi" "k8s.io/apimachinery/pkg/runtime/schema" + "k8s.io/apimachinery/pkg/util/proxy" + "k8s.io/klog" devopsv1alpha1 "kubesphere.io/kubesphere/pkg/apis/devops/v1alpha1" "kubesphere.io/kubesphere/pkg/apiserver/runtime" "kubesphere.io/kubesphere/pkg/client/clientset/versioned" "kubesphere.io/kubesphere/pkg/client/informers/externalversions" "kubesphere.io/kubesphere/pkg/constants" + "kubesphere.io/kubesphere/pkg/simple/client/devops/jenkins" "kubesphere.io/kubesphere/pkg/simple/client/s3" "kubesphere.io/kubesphere/pkg/simple/client/sonarqube" + "net/url" + "strings" //"kubesphere.io/kubesphere/pkg/models/devops" "kubesphere.io/kubesphere/pkg/simple/client/devops" - "net/http" ) @@ -41,7 +46,7 @@ const ( var GroupVersion = schema.GroupVersion{Group: GroupName, Version: "v1alpha2"} -func AddToContainer(container *restful.Container, ksInformers externalversions.SharedInformerFactory, devopsClient devops.Interface, sonarqubeClient sonarqube.SonarInterface, ksClient versioned.Interface, s3Client s3.Interface) error { +func AddToContainer(container *restful.Container, ksInformers externalversions.SharedInformerFactory, devopsClient devops.Interface, sonarqubeClient sonarqube.SonarInterface, ksClient versioned.Interface, s3Client s3.Interface, endpoint string) error { ws := runtime.NewWebService(GroupVersion) err := AddPipelineToWebService(ws, devopsClient) @@ -59,6 +64,11 @@ func AddToContainer(container *restful.Container, ksInformers externalversions.S return err } + err = AddJenkinsToContainer(ws, devopsClient, endpoint) + if err != nil { + return err + } + container.Add(ws) return nil @@ -685,3 +695,31 @@ func AddS2IToWebService(webservice *restful.WebService, ksClient versioned.Inter } return nil } + +func AddJenkinsToContainer(webservice *restful.WebService, devopsClient devops.Interface, endpoint string) error { + if devopsClient == nil { + return nil + } + parse, err := url.Parse(endpoint) + if err != nil { + return err + } + parse.Path = strings.Trim(parse.Path, "/") + webservice.Route(webservice.GET("/jenkins/{path:*}"). + To(func(request *restful.Request, response *restful.Response) { + u := request.Request.URL + u.Host = parse.Host + u.Scheme = parse.Scheme + jenkins.SetBasicBearTokenHeader(&request.Request.Header) + u.Path = strings.Replace(request.Request.URL.Path, fmt.Sprintf("/kapis/%s/%s/jenkins", GroupVersion.Group, GroupVersion.Version), "", 1) + httpProxy := proxy.NewUpgradeAwareHandler(u, http.DefaultTransport, false, false, &errorResponder{}) + httpProxy.ServeHTTP(response, request.Request) + }).Returns(http.StatusOK, RespOK, nil)) + return nil +} + +type errorResponder struct{} + +func (e *errorResponder) Error(w http.ResponseWriter, req *http.Request, err error) { + klog.Error(err) +} diff --git a/pkg/simple/client/devops/jenkins/pure_request.go b/pkg/simple/client/devops/jenkins/pure_request.go index a95e5df0a7caf476a037392afd9aa62eb3f41b28..2f73ae3c91d9e926953ece557866854da87600f7 100644 --- a/pkg/simple/client/devops/jenkins/pure_request.go +++ b/pkg/simple/client/devops/jenkins/pure_request.go @@ -1,15 +1,10 @@ package jenkins import ( - "encoding/base64" - "fmt" - "github.com/dgrijalva/jwt-go" "k8s.io/klog" - authtoken "kubesphere.io/kubesphere/pkg/apiserver/authentication/token" "kubesphere.io/kubesphere/pkg/simple/client/devops" "net/http" "net/url" - "strings" "time" ) @@ -32,23 +27,7 @@ func (j *Jenkins) SendPureRequestWithHeaderResp(path string, httpParameters *dev client := &http.Client{Timeout: 30 * time.Second} header := httpParameters.Header - bearTokenArray := strings.Split(header.Get("Authorization"), " ") - bearFlag := bearTokenArray[0] - if strings.ToLower(bearFlag) == "bearer" { - bearToken := bearTokenArray[1] - if err != nil { - klog.Error(err) - return nil, nil, err - } - claim := authtoken.Claims{} - parser := jwt.Parser{} - _, _, err = parser.ParseUnverified(bearToken, &claim) - if err != nil { - return nil, nil, err - } - creds := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", claim.Username, bearToken))) - header.Set("Authorization", fmt.Sprintf("Basic %s", creds)) - } + SetBasicBearTokenHeader(&header) newRequest := &http.Request{ Method: httpParameters.Method, diff --git a/pkg/simple/client/devops/jenkins/request.go b/pkg/simple/client/devops/jenkins/request.go index 968d0cc003e191327489e9def54b1975fe1e705b..6addc258dbc8b8c1d1199cbcca264bf8206009ed 100644 --- a/pkg/simple/client/devops/jenkins/request.go +++ b/pkg/simple/client/devops/jenkins/request.go @@ -16,11 +16,14 @@ package jenkins import ( "bytes" + "encoding/base64" "encoding/json" "errors" "fmt" + "github.com/dgrijalva/jwt-go" "io" "io/ioutil" + authtoken "kubesphere.io/kubesphere/pkg/apiserver/authentication/token" "kubesphere.io/kubesphere/pkg/simple/client/devops" "mime/multipart" "net/http" @@ -40,6 +43,28 @@ type APIRequest struct { Suffix string } +// set basic token for jenkins auth +func SetBasicBearTokenHeader(header *http.Header) error { + bearTokenArray := strings.Split(header.Get("Authorization"), " ") + bearFlag := bearTokenArray[0] + var err error + if strings.ToLower(bearFlag) == "bearer" { + bearToken := bearTokenArray[1] + if err != nil { + return err + } + claim := authtoken.Claims{} + parser := jwt.Parser{} + _, _, err = parser.ParseUnverified(bearToken, &claim) + if err != nil { + return err + } + creds := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", claim.Username, bearToken))) + header.Set("Authorization", fmt.Sprintf("Basic %s", creds)) + } + return nil +} + func (ar *APIRequest) SetHeader(key string, value string) *APIRequest { ar.Headers.Set(key, value) return ar