Merge branch 'master' into jenkins-pageable-response

Signed-off-by: runzexia <runzexia@yunify.com>

# Conflicts:
#	pkg/models/devops/devops.go
This commit is contained in:
runzexia
2019-09-12 11:04:32 +08:00
245 changed files with 27248 additions and 2657 deletions

View File

@@ -31,7 +31,7 @@ import (
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/resources"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/simple/client/openpitrix"
"strings"
"time"
@@ -63,7 +63,11 @@ type workLoads struct {
}
func ListApplication(runtimeId string, conditions *params.Conditions, limit, offset int) (*models.PageableResponse, error) {
clusterList, err := openpitrix.ListClusters(runtimeId, conditions.Match["keyword"], conditions.Match["status"], limit, offset)
openPitrixClient, err := client.ClientSets().OpenPitrix()
if err != nil {
return nil, err
}
clusterList, err := openPitrixClient.ListClusters(runtimeId, conditions.Match["keyword"], conditions.Match["status"], limit, offset)
if err != nil {
return nil, err
}
@@ -76,13 +80,13 @@ func ListApplication(runtimeId string, conditions *params.Conditions, limit, off
app.ClusterID = item.ClusterID
app.UpdateTime = item.UpdateTime
app.Status = item.Status
versionInfo, _ := openpitrix.GetVersion(item.VersionID)
versionInfo, _ := openPitrixClient.GetVersion(item.VersionID)
app.Version = versionInfo
app.VersionId = item.VersionID
runtimeInfo, _ := openpitrix.GetRuntime(item.RunTimeId)
runtimeInfo, _ := openPitrixClient.GetRuntime(item.RunTimeId)
app.Runtime = runtimeInfo
app.RuntimeId = item.RunTimeId
appInfo, _, appId, _ := openpitrix.GetAppInfo(item.AppID)
appInfo, _, appId, _ := openPitrixClient.GetAppInfo(item.AppID)
app.App = appInfo
app.AppId = appId
app.Description = item.Description
@@ -94,8 +98,11 @@ func ListApplication(runtimeId string, conditions *params.Conditions, limit, off
}
func GetApp(clusterId string) (*Application, error) {
item, err := openpitrix.GetCluster(clusterId)
openPitrixClient, err := client.ClientSets().OpenPitrix()
if err != nil {
return nil, err
}
item, err := openPitrixClient.GetCluster(clusterId)
if err != nil {
glog.Error(err)
@@ -109,19 +116,19 @@ func GetApp(clusterId string) (*Application, error) {
app.UpdateTime = item.UpdateTime
app.CreateTime = item.CreateTime
app.Status = item.Status
versionInfo, _ := openpitrix.GetVersion(item.VersionID)
versionInfo, _ := openPitrixClient.GetVersion(item.VersionID)
app.Version = versionInfo
app.VersionId = item.VersionID
runtimeInfo, _ := openpitrix.GetRuntime(item.RunTimeId)
runtimeInfo, _ := openPitrixClient.GetRuntime(item.RunTimeId)
app.Runtime = runtimeInfo
app.RuntimeId = item.RunTimeId
appInfo, repoId, appId, _ := openpitrix.GetAppInfo(item.AppID)
appInfo, repoId, appId, _ := openPitrixClient.GetAppInfo(item.AppID)
app.App = appInfo
app.AppId = appId
app.Description = item.Description
app.RepoName, _ = openpitrix.GetRepo(repoId)
app.RepoName, _ = openPitrixClient.GetRepo(repoId)
workloads, err := getWorkLoads(app.Runtime, item.ClusterRoleSets)
if err != nil {
@@ -195,7 +202,7 @@ func getWorkLoads(namespace string, clusterRoles []openpitrix.ClusterRole) (*wor
}
func getLabels(namespace string, workloads *workLoads) *[]map[string]string {
k8sClient := k8s.Client()
k8sClient := client.ClientSets().K8s().Kubernetes()
var workloadLables []map[string]string
if workloads == nil {
@@ -242,7 +249,7 @@ func getSvcs(namespace string, workLoadLabels *[]map[string]string) []v1.Service
if len(*workLoadLabels) == 0 {
return nil
}
k8sClient := k8s.Client()
k8sClient := client.ClientSets().K8s().Kubernetes()
var services []v1.Service
for _, label := range *workLoadLabels {
labelSelector := labels.Set(label).AsSelector().String()
@@ -302,6 +309,11 @@ func getIng(namespace string, services []v1.Service) []v1beta1.Ingress {
}
func DeployApplication(namespace string, app openpitrix.CreateClusterRequest) error {
openPitrixClient, err := client.ClientSets().OpenPitrix()
if err != nil {
return err
}
ns, err := informers.SharedInformerFactory().Core().V1().Namespaces().Lister().Get(namespace)
if err != nil {
glog.Errorf("deploy application failed: %+v", err)
@@ -313,9 +325,14 @@ func DeployApplication(namespace string, app openpitrix.CreateClusterRequest) er
} else {
return fmt.Errorf("runtime not init: namespace %s", namespace)
}
return openpitrix.CreateCluster(app)
return openPitrixClient.CreateCluster(app)
}
func DeleteApplication(clusterId string) error {
return openpitrix.DeleteCluster(openpitrix.DeleteClusterRequest{ClusterId: []string{clusterId}})
openPitrixClient, err := client.ClientSets().OpenPitrix()
if err != nil {
return err
}
return openPitrixClient.DeleteCluster(openpitrix.DeleteClusterRequest{ClusterId: []string{clusterId}})
}

View File

@@ -19,9 +19,9 @@ package components
import (
"fmt"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/informers"
@@ -93,7 +93,7 @@ func GetSystemHealthStatus() (*models.HealthStatus, error) {
status := &models.HealthStatus{}
componentStatuses, err := k8s.Client().CoreV1().ComponentStatuses().List(meta_v1.ListOptions{})
componentStatuses, err := client.ClientSets().K8s().Kubernetes().CoreV1().ComponentStatuses().List(metav1.ListOptions{})
if err != nil {
return nil, err
}

View File

@@ -16,9 +16,10 @@ 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/devops_mysql"
"kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/utils/reflectutils"
"kubesphere.io/kubesphere/pkg/utils/stringutils"
)
@@ -126,7 +127,7 @@ var JenkinsOwnerProjectPermissionIds = &gojenkins.ProjectPermissionIds{
}
var JenkinsProjectPermissionMap = map[string]gojenkins.ProjectPermissionIds{
ProjectOwner: gojenkins.ProjectPermissionIds{
ProjectOwner: {
CredentialCreate: true,
CredentialDelete: true,
CredentialManageDomains: true,
@@ -146,7 +147,7 @@ var JenkinsProjectPermissionMap = map[string]gojenkins.ProjectPermissionIds{
RunUpdate: true,
SCMTag: true,
},
ProjectMaintainer: gojenkins.ProjectPermissionIds{
ProjectMaintainer: {
CredentialCreate: true,
CredentialDelete: true,
CredentialManageDomains: true,
@@ -166,7 +167,7 @@ var JenkinsProjectPermissionMap = map[string]gojenkins.ProjectPermissionIds{
RunUpdate: true,
SCMTag: true,
},
ProjectDeveloper: gojenkins.ProjectPermissionIds{
ProjectDeveloper: {
CredentialCreate: false,
CredentialDelete: false,
CredentialManageDomains: false,
@@ -186,7 +187,7 @@ var JenkinsProjectPermissionMap = map[string]gojenkins.ProjectPermissionIds{
RunUpdate: true,
SCMTag: false,
},
ProjectReporter: gojenkins.ProjectPermissionIds{
ProjectReporter: {
CredentialCreate: false,
CredentialDelete: false,
CredentialManageDomains: false,
@@ -209,7 +210,7 @@ var JenkinsProjectPermissionMap = map[string]gojenkins.ProjectPermissionIds{
}
var JenkinsPipelinePermissionMap = map[string]gojenkins.ProjectPermissionIds{
ProjectOwner: gojenkins.ProjectPermissionIds{
ProjectOwner: {
CredentialCreate: true,
CredentialDelete: true,
CredentialManageDomains: true,
@@ -229,7 +230,7 @@ var JenkinsPipelinePermissionMap = map[string]gojenkins.ProjectPermissionIds{
RunUpdate: true,
SCMTag: true,
},
ProjectMaintainer: gojenkins.ProjectPermissionIds{
ProjectMaintainer: {
CredentialCreate: true,
CredentialDelete: true,
CredentialManageDomains: true,
@@ -249,7 +250,7 @@ var JenkinsPipelinePermissionMap = map[string]gojenkins.ProjectPermissionIds{
RunUpdate: true,
SCMTag: true,
},
ProjectDeveloper: gojenkins.ProjectPermissionIds{
ProjectDeveloper: {
CredentialCreate: false,
CredentialDelete: false,
CredentialManageDomains: false,
@@ -269,7 +270,7 @@ var JenkinsPipelinePermissionMap = map[string]gojenkins.ProjectPermissionIds{
RunUpdate: true,
SCMTag: false,
},
ProjectReporter: gojenkins.ProjectPermissionIds{
ProjectReporter: {
CredentialCreate: false,
CredentialDelete: false,
CredentialManageDomains: false,
@@ -311,9 +312,18 @@ func CheckProjectUserInRole(username, projectId string, roles []string) error {
if username == KS_ADMIN {
return nil
}
dbconn := devops_mysql.OpenDatabase()
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...).
err = dbconn.Select(DevOpsProjectMembershipColumns...).
From(DevOpsProjectMembershipTableName).
Where(db.And(
db.Eq(DevOpsProjectMembershipUsernameColumn, username),
@@ -331,9 +341,17 @@ func GetProjectUserRole(username, projectId string) (string, error) {
if username == KS_ADMIN {
return ProjectOwner, nil
}
dbconn := devops_mysql.OpenDatabase()
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...).
err = dbconn.Select(DevOpsProjectMembershipColumns...).
From(DevOpsProjectMembershipTableName).
Where(db.And(
db.Eq(DevOpsProjectMembershipUsernameColumn, username),

View File

@@ -23,13 +23,14 @@ import (
"encoding/json"
"fmt"
"github.com/PuerkitoBio/goquery"
log "github.com/golang/glog"
"github.com/emicklei/go-restful"
"io"
"io/ioutil"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/gojenkins"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins"
log "k8s.io/klog"
cs "kubesphere.io/kubesphere/pkg/simple/client"
"net/http"
"net/url"
"strings"
@@ -37,17 +38,18 @@ import (
"time"
)
const channelMaxCapacity = 100
var jenkins *gojenkins.Jenkins
func JenkinsInit() {
jenkins = admin_jenkins.GetJenkins()
}
const (
channelMaxCapacity = 100
cronJobLayout = "Monday, January 2, 2006 15:04:05 PM"
)
func GetPipeline(projectName, pipelineName string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetPipelineUrl, projectName, pipelineName)
log.Infof("Jenkins-url: " + baseUrl)
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetPipelineUrl, projectName, pipelineName)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -59,8 +61,12 @@ func GetPipeline(projectName, pipelineName string, req *http.Request) ([]byte, e
}
func SearchPipelines(req *http.Request) ([]byte, error) {
baseUrl := jenkins.Server + SearchPipelineUrl + req.URL.RawQuery
klog.V(3).Infof("Jenkins-url: " + baseUrl)
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := devops.Jenkins().Server + SearchPipelineUrl + req.URL.RawQuery
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -87,13 +93,18 @@ func SearchPipelines(req *http.Request) ([]byte, error) {
}
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 := jenkins.Server + SearchPipelineUrl + query.Encode()
klog.Infof("Jenkins-url: " + baseUrl)
baseUrl := devops.Jenkins().Server + SearchPipelineUrl + query.Encode()
klog.V(4).Info("Jenkins-url: " + baseUrl)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -110,13 +121,17 @@ func searchPipelineCount(req *http.Request) (int, error) {
}
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(jenkins.Server+SearchPipelineRunUrl, projectName, pipelineName)
baseUrl := fmt.Sprintf(devops.Jenkins().Server+SearchPipelineRunUrl, projectName, pipelineName)
klog.V(3).Info("Jenkins-url: " + baseUrl)
klog.V(4).Info("Jenkins-url: " + baseUrl)
res, err := sendJenkinsRequest(baseUrl+query.Encode(), req)
if err != nil {
@@ -133,9 +148,14 @@ func searchPipelineRunsCount(projectName, pipelineName string, req *http.Request
}
func SearchPipelineRuns(projectName, pipelineName string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+SearchPipelineRunUrl, projectName, pipelineName)
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
klog.V(3).Info("Jenkins-url: " + baseUrl)
baseUrl := fmt.Sprintf(devops.Jenkins().Server+SearchPipelineRunUrl, projectName, pipelineName)
klog.V(4).Info("Jenkins-url: " + baseUrl)
res, err := sendJenkinsRequest(baseUrl+req.URL.RawQuery, req)
if err != nil {
@@ -162,8 +182,12 @@ func SearchPipelineRuns(projectName, pipelineName string, req *http.Request) ([]
}
func GetBranchPipelineRun(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetPipeBranchRunUrl, projectName, pipelineName, branchName, runId)
log.Info("Jenkins-url: " + baseUrl)
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetPipeBranchRunUrl, projectName, pipelineName, branchName, runId)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -175,7 +199,12 @@ func GetBranchPipelineRun(projectName, pipelineName, branchName, runId string, r
}
func GetPipelineRunNodesbyBranch(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetBranchPipeRunNodesUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
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)
log.Info("Jenkins-url: " + baseUrl)
res, err := sendJenkinsRequest(baseUrl, req)
@@ -188,8 +217,12 @@ func GetPipelineRunNodesbyBranch(projectName, pipelineName, branchName, runId st
}
func GetBranchStepLog(projectName, pipelineName, branchName, runId, nodeId, stepId string, req *http.Request) ([]byte, http.Header, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetBranchStepLogUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId, stepId)
log.Info("Jenkins-url: " + baseUrl)
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)
resBody, header, err := jenkinsClient(baseUrl, req)
if err != nil {
@@ -201,8 +234,12 @@ func GetBranchStepLog(projectName, pipelineName, branchName, runId, nodeId, step
}
func GetStepLog(projectName, pipelineName, runId, nodeId, stepId string, req *http.Request) ([]byte, http.Header, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetStepLogUrl+req.URL.RawQuery, projectName, pipelineName, runId, nodeId, stepId)
log.Info("Jenkins-url: " + baseUrl)
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)
resBody, header, err := jenkinsClient(baseUrl, req)
if err != nil {
@@ -211,12 +248,15 @@ func GetStepLog(projectName, pipelineName, runId, nodeId, stepId string, req *ht
}
return resBody, header, err
}
func GetSCMServers(scmId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetSCMServersUrl, scmId)
log.Info("Jenkins-url: " + baseUrl)
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)
if err != nil {
@@ -227,6 +267,11 @@ func GetSCMServers(scmId string, req *http.Request) ([]byte, error) {
}
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())
}
requestBody, err := ioutil.ReadAll(req.Body)
if err != nil {
log.Error(err)
@@ -244,6 +289,7 @@ func CreateSCMServers(scmId string, req *http.Request) ([]byte, error) {
log.Error(err)
return nil, err
}
var servers []*SCMServer
_ = json.Unmarshal(byteServers, &servers)
for _, server := range servers {
@@ -252,8 +298,9 @@ func CreateSCMServers(scmId string, req *http.Request) ([]byte, error) {
}
}
req.Body = ioutil.NopCloser(bytes.NewReader(requestBody))
baseUrl := fmt.Sprintf(jenkins.Server+CreateSCMServersUrl, scmId)
log.Info("Jenkins-url: " + baseUrl)
baseUrl := fmt.Sprintf(devops.Jenkins().Server+CreateSCMServersUrl, scmId)
req.Method = http.MethodPost
resBody, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -264,8 +311,12 @@ func CreateSCMServers(scmId string, req *http.Request) ([]byte, error) {
}
func Validate(scmId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+ValidateUrl, scmId)
log.Info("Jenkins-url: " + baseUrl)
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)
@@ -278,8 +329,12 @@ func Validate(scmId string, req *http.Request) ([]byte, error) {
}
func GetSCMOrg(scmId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetSCMOrgUrl+req.URL.RawQuery, scmId)
log.Info("Jenkins-url: " + baseUrl)
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetSCMOrgUrl+req.URL.RawQuery, scmId)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -291,8 +346,12 @@ func GetSCMOrg(scmId string, req *http.Request) ([]byte, error) {
}
func GetOrgRepo(scmId, organizationId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetOrgRepoUrl+req.URL.RawQuery, scmId, organizationId)
log.Info("Jenkins-url: " + baseUrl)
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)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -304,8 +363,12 @@ func GetOrgRepo(scmId, organizationId string, req *http.Request) ([]byte, error)
}
func StopBranchPipeline(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+StopBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
log.Info("Jenkins-url: " + baseUrl)
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)
req.Method = http.MethodPut
res, err := sendJenkinsRequest(baseUrl, req)
@@ -318,8 +381,12 @@ func StopBranchPipeline(projectName, pipelineName, branchName, runId string, req
}
func StopPipeline(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+StopPipelineUrl+req.URL.RawQuery, projectName, pipelineName, runId)
log.Info("Jenkins-url: " + baseUrl)
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)
req.Method = http.MethodPut
res, err := sendJenkinsRequest(baseUrl, req)
@@ -332,8 +399,12 @@ func StopPipeline(projectName, pipelineName, runId string, req *http.Request) ([
}
func ReplayBranchPipeline(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+ReplayBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
log.Info("Jenkins-url: " + baseUrl)
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)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -345,8 +416,12 @@ func ReplayBranchPipeline(projectName, pipelineName, branchName, runId string, r
}
func ReplayPipeline(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+ReplayPipelineUrl+req.URL.RawQuery, projectName, pipelineName, runId)
log.Info("Jenkins-url: " + baseUrl)
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+ReplayPipelineUrl+req.URL.RawQuery, projectName, pipelineName, runId)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -358,8 +433,12 @@ func ReplayPipeline(projectName, pipelineName, runId string, req *http.Request)
}
func GetBranchRunLog(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetBranchRunLogUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
log.Info("Jenkins-url: " + baseUrl)
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)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -371,8 +450,12 @@ func GetBranchRunLog(projectName, pipelineName, branchName, runId string, req *h
}
func GetRunLog(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetRunLogUrl+req.URL.RawQuery, projectName, pipelineName, runId)
log.Info("Jenkins-url: " + baseUrl)
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)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -384,8 +467,12 @@ func GetRunLog(projectName, pipelineName, runId string, req *http.Request) ([]by
}
func GetBranchArtifacts(projectName, pipelineName, branchName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetBranchArtifactsUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
log.Info("Jenkins-url: " + baseUrl)
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)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -397,8 +484,12 @@ func GetBranchArtifacts(projectName, pipelineName, branchName, runId string, req
}
func GetArtifacts(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetArtifactsUrl+req.URL.RawQuery, projectName, pipelineName, runId)
log.Info("Jenkins-url: " + baseUrl)
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)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -410,8 +501,12 @@ func GetArtifacts(projectName, pipelineName, runId string, req *http.Request) ([
}
func GetPipeBranch(projectName, pipelineName string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetPipeBranchUrl, projectName, pipelineName)
log.Info("Jenkins-url: " + baseUrl)
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetPipeBranchUrl, projectName, pipelineName)
res, err := sendJenkinsRequest(baseUrl+req.URL.RawQuery, req)
if err != nil {
@@ -423,8 +518,12 @@ func GetPipeBranch(projectName, pipelineName string, req *http.Request) ([]byte,
}
func SubmitBranchInputStep(projectName, pipelineName, branchName, runId, nodeId, stepId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+CheckBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId, stepId)
log.Info("Jenkins-url: " + baseUrl)
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)
newBody, err := getInputReqBody(req.Body)
if err != nil {
@@ -442,8 +541,12 @@ func SubmitBranchInputStep(projectName, pipelineName, branchName, runId, nodeId,
}
func SubmitInputStep(projectName, pipelineName, runId, nodeId, stepId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+CheckPipelineUrl+req.URL.RawQuery, projectName, pipelineName, runId, nodeId, stepId)
log.Info("Jenkins-url: " + baseUrl)
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)
newBody, err := getInputReqBody(req.Body)
if err != nil {
@@ -500,8 +603,12 @@ func parseBody(body io.Reader) (newReqBody io.ReadCloser) {
}
func GetConsoleLog(projectName, pipelineName string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetConsoleLogUrl+req.URL.RawQuery, projectName, pipelineName)
log.Info("Jenkins-url: " + baseUrl)
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)
resBody, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -513,8 +620,12 @@ func GetConsoleLog(projectName, pipelineName string, req *http.Request) ([]byte,
}
func ScanBranch(projectName, pipelineName string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+ScanBranchUrl+req.URL.RawQuery, projectName, pipelineName)
log.Info("Jenkins-url: " + baseUrl)
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)
resBody, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -526,8 +637,12 @@ func ScanBranch(projectName, pipelineName string, req *http.Request) ([]byte, er
}
func RunBranchPipeline(projectName, pipelineName, branchName string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+RunBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName)
log.Info("Jenkins-url: " + baseUrl)
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+RunBranchPipelineUrl+req.URL.RawQuery, projectName, pipelineName, branchName)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -539,8 +654,11 @@ func RunBranchPipeline(projectName, pipelineName, branchName string, req *http.R
}
func RunPipeline(projectName, pipelineName string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+RunPipelineUrl+req.URL.RawQuery, projectName, pipelineName)
log.Info("Jenkins-url: " + baseUrl)
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)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -552,8 +670,12 @@ func RunPipeline(projectName, pipelineName string, req *http.Request) ([]byte, e
}
func GetCrumb(req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server + GetCrumbUrl)
log.Info("Jenkins-url: " + baseUrl)
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 {
@@ -564,10 +686,13 @@ func GetCrumb(req *http.Request) ([]byte, error) {
return res, err
}
func CheckScriptCompile(req *http.Request) ([]byte, error) {
baseUrl := jenkins.Server + CheckScriptCompileUrl
log.Info("Jenkins-url: " + baseUrl)
req.SetBasicAuth(jenkins.Requester.BasicAuth.Username, jenkins.Requester.BasicAuth.Password)
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)
if err != nil {
@@ -578,41 +703,111 @@ func CheckScriptCompile(req *http.Request) ([]byte, error) {
return resBody, err
}
func CheckCron(req *http.Request) (*CheckCronRes, error) {
newurl, err := url.Parse(jenkins.Server + CheckCronUrl + req.URL.RawQuery)
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)
}
newUrl, err := url.Parse(baseUrl)
if err != nil {
log.Error(err)
return nil, err
}
newUrl.RawQuery = newUrl.Query().Encode()
reqJenkins := &http.Request{
Method: http.MethodGet,
URL: newurl,
Header: http.Header{},
URL: newUrl,
Header: req.Header,
}
var res = new(CheckCronRes)
client := &http.Client{Timeout: 30 * time.Second}
reqJenkins.SetBasicAuth(jenkins.Requester.BasicAuth.Username, jenkins.Requester.BasicAuth.Password)
resp, err := client.Do(reqJenkins)
if resp != nil && resp.StatusCode != http.StatusOK {
resBody, _ := getRespBody(resp)
return &CheckCronRes{
Result: "error",
Message: string(resBody),
}, err
}
if err != nil {
log.Error(err)
return res, err
return nil, err
}
defer resp.Body.Close()
doc, err := goquery.NewDocumentFromReader(resp.Body)
if err != nil {
log.Error(err)
return res, 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 {
log.Error(err)
return nil, err
}
}
return res, err
}
func parseCronJobTime(msg string) (string, string, error) {
times := strings.Split(msg, ";")
lastTmp := strings.SplitN(times[0], " ", 2)
lastTime := strings.SplitN(lastTmp[1], " UTC", 2)
lastUinx, err := time.Parse(cronJobLayout, lastTime[0])
if err != nil {
log.Error(err)
return "", "", err
}
last := lastUinx.Format(time.RFC3339)
nextTmp := strings.SplitN(times[1], " ", 3)
nextTime := strings.SplitN(nextTmp[2], " UTC", 2)
nextUinx, err := time.Parse(cronJobLayout, nextTime[0])
if err != nil {
log.Error(err)
return "", "", err
}
next := nextUinx.Format(time.RFC3339)
return last, next, nil
}
func GetPipelineRun(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetPipelineRunUrl, projectName, pipelineName, runId)
log.Info("Jenkins-url: " + baseUrl)
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetPipelineRunUrl, projectName, pipelineName, runId)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -624,8 +819,12 @@ func GetPipelineRun(projectName, pipelineName, runId string, req *http.Request)
}
func GetBranchPipeline(projectName, pipelineName, branchName string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetBranchPipeUrl, projectName, pipelineName, branchName)
log.Info("Jenkins-url: " + baseUrl)
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetBranchPipeUrl, projectName, pipelineName, branchName)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -637,8 +836,12 @@ func GetBranchPipeline(projectName, pipelineName, branchName string, req *http.R
}
func GetPipelineRunNodes(projectName, pipelineName, runId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetPipeRunNodesUrl+req.URL.RawQuery, projectName, pipelineName, runId)
log.Info("Jenkins-url: " + baseUrl)
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)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -650,8 +853,12 @@ func GetPipelineRunNodes(projectName, pipelineName, runId string, req *http.Requ
}
func GetBranchNodeSteps(projectName, pipelineName, branchName, runId, nodeId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetBranchNodeStepsUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId)
log.Info("Jenkins-url: " + baseUrl)
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server+GetBranchNodeStepsUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId, nodeId)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -663,8 +870,12 @@ func GetBranchNodeSteps(projectName, pipelineName, branchName, runId, nodeId str
}
func GetNodeSteps(projectName, pipelineName, runId, nodeId string, req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server+GetNodeStepsUrl+req.URL.RawQuery, projectName, pipelineName, runId, nodeId)
log.Info("Jenkins-url: " + baseUrl)
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)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -676,8 +887,12 @@ func GetNodeSteps(projectName, pipelineName, runId, nodeId string, req *http.Req
}
func ToJenkinsfile(req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server + ToJenkinsfileUrl)
log.Info("Jenkins-url: " + baseUrl)
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server + ToJenkinsfileUrl)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -689,8 +904,12 @@ func ToJenkinsfile(req *http.Request) ([]byte, error) {
}
func ToJson(req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprintf(jenkins.Server + ToJsonUrl)
log.Info("Jenkins-url: " + baseUrl)
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprintf(devops.Jenkins().Server + ToJsonUrl)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -702,8 +921,12 @@ func ToJson(req *http.Request) ([]byte, error) {
}
func GetNotifyCommit(req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprint(jenkins.Server, GetNotifyCommitUrl, req.URL.RawQuery)
log.Info("Jenkins-url: " + baseUrl)
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
baseUrl := fmt.Sprint(devops.Jenkins().Server, GetNotifyCommitUrl, req.URL.RawQuery)
req.Method = "GET"
res, err := sendJenkinsRequest(baseUrl, req)
@@ -716,8 +939,12 @@ func GetNotifyCommit(req *http.Request) ([]byte, error) {
}
func GithubWebhook(req *http.Request) ([]byte, error) {
baseUrl := fmt.Sprint(jenkins.Server, GithubWebhookUrl, req.URL.RawQuery)
log.Info("Jenkins-url: " + baseUrl)
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)
res, err := sendJenkinsRequest(baseUrl, req)
if err != nil {
@@ -729,8 +956,6 @@ func GithubWebhook(req *http.Request) ([]byte, error) {
}
func GetBranchNodesDetail(projectName, pipelineName, branchName, runId string, req *http.Request) ([]NodesDetail, error) {
getNodesUrl := fmt.Sprintf(jenkins.Server+GetBranchPipeRunNodesUrl+req.URL.RawQuery, projectName, pipelineName, branchName, runId)
log.Info("getNodesUrl: " + getNodesUrl)
var wg sync.WaitGroup
var nodesDetails []NodesDetail
stepChan := make(chan *NodesStepsIndex, channelMaxCapacity)
@@ -776,8 +1001,6 @@ func GetBranchNodesDetail(projectName, pipelineName, branchName, runId string, r
}
func GetNodesDetail(projectName, pipelineName, runId string, req *http.Request) ([]NodesDetail, error) {
getNodesUrl := fmt.Sprintf(jenkins.Server+GetPipeRunNodesUrl+req.URL.RawQuery, projectName, pipelineName, runId)
log.Info("getNodesUrl: " + getNodesUrl)
var wg sync.WaitGroup
var nodesDetails []NodesDetail
stepChan := make(chan *NodesStepsIndex, channelMaxCapacity)

View File

@@ -0,0 +1,36 @@
package devops
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"}},
}
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)
}
}
}

View File

@@ -755,14 +755,21 @@ type Crumb struct {
type CheckScript struct {
Column int `json:"column,omitempty" description:"column e.g. 0"`
Line int `json:"line,omitempty" description:"line e.g. 0"`
Message string `json:"message,omitempty" description:"message e.g. success"`
Status string `json:"status,omitempty" description:"status e.g. success"`
Message string `json:"message,omitempty" description:"message e.g. unexpected char: '#'"`
Status string `json:"status,omitempty" description:"status e.g. fail"`
}
// CheckCron
type CronData struct {
PipelineName string `json:"pipelineName,omitempty" description:"Pipeline name, if pipeline haven't created, not required'"`
Cron string `json:"cron" description:"Cron script data."`
}
type CheckCronRes struct {
Result string `json:"result,omitempty" description:"result"`
Message string `json:"message,omitempty" description:"message"`
Result string `json:"result,omitempty" description:"result e.g. ok, error"`
Message string `json:"message,omitempty" description:"message"`
LastTime string `json:"lastTime,omitempty" description:"last run time."`
NextTime string `json:"nextTime,omitempty" description:"next run time."`
}
// GetPipelineRun
@@ -1035,7 +1042,7 @@ type NodeSteps struct {
// CheckScriptCompile
type ReqScript struct {
Value string `json:"value,omitempty" description:"check value"`
Value string `json:"value,omitempty" description:"Pipeline script data"`
}
// ToJenkinsfile requests

View File

@@ -24,25 +24,25 @@ import (
"kubesphere.io/kubesphere/pkg/db"
"kubesphere.io/kubesphere/pkg/gojenkins"
"kubesphere.io/kubesphere/pkg/gojenkins/utils"
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins"
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql"
cs "kubesphere.io/kubesphere/pkg/simple/client"
"net/http"
"strings"
)
func CreateProjectCredential(projectId, username string, credentialRequest *JenkinsCredential) (string, error) {
jenkinsClient := admin_jenkins.Client()
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
devops, err := cs.ClientSets().Devops()
if err != nil {
return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
}
err := checkJenkinsCredentialExists(projectId, credentialRequest.Domain, credentialRequest.Id)
jenkinsClient := devops.Jenkins()
err = checkJenkinsCredentialExists(projectId, credentialRequest.Domain, credentialRequest.Id)
if err != nil {
glog.Errorf("%+v", err)
return "", err
}
switch credentialRequest.Type {
case CredentialTypeUsernamePassword:
if credentialRequest.UsernamePasswordCredential == nil {
@@ -144,12 +144,12 @@ func CreateProjectCredential(projectId, username string, credentialRequest *Jenk
}
func UpdateProjectCredential(projectId, credentialId string, credentialRequest *JenkinsCredential) (string, error) {
jenkinsClient := admin_jenkins.Client()
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
devops, err := cs.ClientSets().Devops()
if err != nil {
return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
}
jenkinsClient := devops.Jenkins()
jenkinsCredential, err := jenkinsClient.GetCredentialInFolder(credentialRequest.Domain,
credentialId,
projectId)
@@ -238,20 +238,25 @@ func UpdateProjectCredential(projectId, credentialId string, credentialRequest *
}
func DeleteProjectCredential(projectId, credentialId string, credentialRequest *JenkinsCredential) (string, error) {
jenkinsClient := admin_jenkins.Client()
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
devops, err := cs.ClientSets().Devops()
if err != nil {
return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
}
dbClient := devops_mysql.OpenDatabase()
_, err := jenkinsClient.GetCredentialInFolder(credentialRequest.Domain,
jenkinsClient := devops.Jenkins()
dbClient, err := cs.ClientSets().MySQL()
if err != nil {
return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
}
_, err = jenkinsClient.GetCredentialInFolder(credentialRequest.Domain,
credentialId,
projectId)
if err != nil {
glog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
id, err := jenkinsClient.DeleteCredentialInFolder(credentialRequest.Domain, credentialId, projectId)
if err != nil {
glog.Errorf("%+v", err)
@@ -277,13 +282,16 @@ func DeleteProjectCredential(projectId, credentialId string, credentialRequest *
}
func GetProjectCredential(projectId, credentialId, domain, getContent string) (*JenkinsCredential, error) {
jenkinsClient := admin_jenkins.Client()
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
jenkinsClient := devops.Jenkins()
dbClient, err := cs.ClientSets().MySQL()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
dbClient := devops_mysql.OpenDatabase()
jenkinsResponse, err := jenkinsClient.GetCredentialInFolder(domain,
credentialId,
projectId)
@@ -352,13 +360,16 @@ func GetProjectCredential(projectId, credentialId, domain, getContent string) (*
}
func GetProjectCredentials(projectId, domain string) ([]*JenkinsCredential, error) {
jenkinsClient := admin_jenkins.Client()
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
devops, err := cs.ClientSets().Devops()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
jenkinsClient := devops.Jenkins()
dbClient, err := cs.ClientSets().MySQL()
if err != nil {
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
dbClient := devops_mysql.OpenDatabase()
jenkinsCredentialResponses, err := jenkinsClient.GetCredentialsInFolder(domain, projectId)
if err != nil {
glog.Errorf("%+v", err)
@@ -380,9 +391,13 @@ func GetProjectCredentials(projectId, domain string) ([]*JenkinsCredential, erro
}
func insertCredentialToDb(projectId, credentialId, domain, username string) error {
dbClient := devops_mysql.OpenDatabase()
dbClient, err := cs.ClientSets().MySQL()
if err != nil {
return err
}
projectCredential := NewProjectCredential(projectId, credentialId, domain, username)
_, err := dbClient.InsertInto(ProjectCredentialTableName).Columns(ProjectCredentialColumns...).
_, err = dbClient.InsertInto(ProjectCredentialTableName).Columns(ProjectCredentialColumns...).
Record(projectCredential).Exec()
if err != nil {
glog.Errorf("%+v", err)
@@ -392,12 +407,13 @@ func insertCredentialToDb(projectId, credentialId, domain, username string) erro
}
func checkJenkinsCredentialExists(projectId, domain, credentialId string) error {
jenkinsClient := admin_jenkins.Client()
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
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)

View File

@@ -19,14 +19,17 @@ import (
"github.com/gocraft/dbr"
"github.com/golang/glog"
"kubesphere.io/kubesphere/pkg/db"
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql"
cs "kubesphere.io/kubesphere/pkg/simple/client"
"net/http"
)
func GetProject(projectId string) (*DevOpsProject, error) {
dbconn := devops_mysql.OpenDatabase()
dbconn, err := cs.ClientSets().MySQL()
if err != nil {
return nil, err
}
project := &DevOpsProject{}
err := dbconn.Select(DevOpsProjectColumns...).
err = dbconn.Select(DevOpsProjectColumns...).
From(DevOpsProjectTableName).
Where(db.Eq(DevOpsProjectIdColumn, projectId)).
LoadOne(project)
@@ -43,7 +46,11 @@ func GetProject(projectId string) (*DevOpsProject, error) {
}
func UpdateProject(project *DevOpsProject) (*DevOpsProject, error) {
dbconn := devops_mysql.OpenDatabase()
dbconn, err := cs.ClientSets().MySQL()
if err != nil {
return nil, err
}
query := dbconn.Update(DevOpsProjectTableName)
if !govalidator.IsNull(project.Description) {
query.Set(DevOpsProjectDescriptionColumn, project.Description)
@@ -65,7 +72,7 @@ func UpdateProject(project *DevOpsProject) (*DevOpsProject, error) {
}
}
newProject := &DevOpsProject{}
err := dbconn.Select(DevOpsProjectColumns...).
err = dbconn.Select(DevOpsProjectColumns...).
From(DevOpsProjectTableName).
Where(db.Eq(DevOpsProjectIdColumn, project.ProjectId)).
LoadOne(newProject)

View File

@@ -14,22 +14,24 @@ package devops
import (
"fmt"
"k8s.io/klog"
"net/http"
"github.com/emicklei/go-restful"
"github.com/gocraft/dbr"
"github.com/golang/glog"
"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/params"
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins"
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql"
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 := devops_mysql.OpenDatabase()
dbconn, err := cs.ClientSets().MySQL()
if err != nil {
return nil, err
}
memberships := make([]*DevOpsProjectMembership, 0)
var sqconditions []dbr.Builder
sqconditions = append(sqconditions, db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId))
@@ -59,14 +61,14 @@ 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 {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
}
count, err := query.Count()
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
}
result := make([]interface{}, 0)
@@ -78,35 +80,46 @@ func GetProjectMembers(projectId string, conditions *params.Conditions, orderBy
}
func GetProjectMember(projectId, username string) (*DevOpsProjectMembership, error) {
dbconn := devops_mysql.OpenDatabase()
dbconn, err := cs.ClientSets().MySQL()
if err != nil {
return nil, err
}
member := &DevOpsProjectMembership{}
err := dbconn.Select(DevOpsProjectMembershipColumns...).
err = dbconn.Select(DevOpsProjectMembershipColumns...).
From(DevOpsProjectMembershipTableName).
Where(db.And(db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
db.Eq(DevOpsProjectMembershipUsernameColumn, username))).
LoadOne(&member)
if err != nil && err != dbr.ErrNotFound {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
}
if err == dbr.ErrNotFound {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusNotFound, err.Error())
}
return member, nil
}
func AddProjectMember(projectId, operator string, member *DevOpsProjectMembership) (*DevOpsProjectMembership, error) {
dbconn := devops_mysql.OpenDatabase()
jenkinsClient := admin_jenkins.Client()
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")
glog.Error(err)
klog.Error(err)
return nil, restful.NewError(http.StatusServiceUnavailable, err.Error())
}
membership := &DevOpsProjectMembership{}
err := dbconn.Select(DevOpsProjectMembershipColumns...).
err = dbconn.Select(DevOpsProjectMembershipColumns...).
From(DevOpsProjectMembershipTableName).
Where(db.And(
db.Eq(DevOpsProjectMembershipUsernameColumn, member.Username),
@@ -114,18 +127,18 @@ func AddProjectMember(projectId, operator string, member *DevOpsProjectMembershi
// 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)
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusBadRequest, err.Error())
}
if err != nil && err != db.ErrNotFound {
glog.Errorf("%+v", err)
if err != db.ErrNotFound {
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
}
globalRole, err := jenkinsClient.GetGlobalRole(JenkinsAllUserRoleName)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
if globalRole == nil {
@@ -133,33 +146,33 @@ func AddProjectMember(projectId, operator string, member *DevOpsProjectMembershi
GlobalRead: true,
}, true)
if err != nil {
glog.Errorf("failed to create jenkins global role %+v", err)
klog.Errorf("failed to create jenkins global role %+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
}
err = globalRole.AssignRole(member.Username)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
projectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, member.Role))
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
err = projectRole.AssignRole(member.Username)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
pipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, member.Role))
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
err = pipelineRole.AssignRole(member.Username)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
projectMembership := NewDevOpsProjectMemberShip(member.Username, projectId, member.Role, operator)
@@ -168,15 +181,15 @@ func AddProjectMember(projectId, operator string, member *DevOpsProjectMembershi
Columns(DevOpsProjectMembershipColumns...).
Record(projectMembership).Exec()
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
err = projectRole.UnAssignRole(member.Username)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
err = pipelineRole.UnAssignRole(member.Username)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
@@ -185,66 +198,82 @@ func AddProjectMember(projectId, operator string, member *DevOpsProjectMembershi
}
func UpdateProjectMember(projectId, operator string, member *DevOpsProjectMembership) (*DevOpsProjectMembership, error) {
dbconn := devops_mysql.OpenDatabase()
jenkinsClient := admin_jenkins.Client()
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
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())
}
oldMembership := &DevOpsProjectMembership{}
err := dbconn.Select(DevOpsProjectMembershipColumns...).
err = dbconn.Select(DevOpsProjectMembershipColumns...).
From(DevOpsProjectMembershipTableName).
Where(db.And(
db.Eq(DevOpsProjectMembershipUsernameColumn, member.Username),
db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
)).LoadOne(oldMembership)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusBadRequest, err.Error())
}
oldProjectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, oldMembership.Role))
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
err = oldProjectRole.UnAssignRole(member.Username)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
oldPipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, oldMembership.Role))
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
err = oldPipelineRole.UnAssignRole(member.Username)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
projectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, member.Role))
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
err = projectRole.AssignRole(member.Username)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
pipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, member.Role))
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
err = pipelineRole.AssignRole(member.Username)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
_, err = dbconn.Update(DevOpsProjectMembershipTableName).
Set(DevOpsProjectMembershipRoleColumn, member.Role).
Where(db.And(
@@ -252,9 +281,10 @@ func UpdateProjectMember(projectId, operator string, member *DevOpsProjectMember
db.Eq(DevOpsProjectMembershipUsernameColumn, member.Username),
)).Exec()
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
}
responseMembership := &DevOpsProjectMembership{}
err = dbconn.Select(DevOpsProjectMembershipColumns...).
From(DevOpsProjectMembershipTableName).
@@ -263,35 +293,42 @@ func UpdateProjectMember(projectId, operator string, member *DevOpsProjectMember
db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
)).LoadOne(responseMembership)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
}
return responseMembership, nil
}
func DeleteProjectMember(projectId, username string) (string, error) {
dbconn := devops_mysql.OpenDatabase()
jenkinsClient := admin_jenkins.Client()
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
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()
oldMembership := &DevOpsProjectMembership{}
err := dbconn.Select(DevOpsProjectMembershipColumns...).
err = dbconn.Select(DevOpsProjectMembershipColumns...).
From(DevOpsProjectMembershipTableName).
Where(db.And(
db.Eq(DevOpsProjectMembershipUsernameColumn, username),
db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
)).LoadOne(oldMembership)
if err != nil && err != db.ErrNotFound {
glog.Errorf("%+v", err)
return "", restful.NewError(http.StatusInternalServerError, err.Error())
}
if err == db.ErrNotFound {
glog.Warningf("user [%s] not found in project", username)
return username, nil
if err != nil {
if err != db.ErrNotFound {
klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusInternalServerError, err.Error())
} else if err == db.ErrNotFound {
klog.Warningf("user [%s] not found in project", username)
return username, nil
}
}
if oldMembership.Role == ProjectOwner {
count, err := dbconn.Select(DevOpsProjectMembershipProjectIdColumn).
From(DevOpsProjectMembershipTableName).
@@ -299,34 +336,35 @@ func DeleteProjectMember(projectId, username string) (string, error) {
db.Eq(DevOpsProjectMembershipProjectIdColumn, projectId),
db.Eq(DevOpsProjectMembershipRoleColumn, ProjectOwner))).Count()
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusInternalServerError, err.Error())
}
if count == 1 {
err = fmt.Errorf("project must has at least one admin")
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusBadRequest, err.Error())
}
}
oldProjectRole, err := jenkinsClient.GetProjectRole(GetProjectRoleName(projectId, oldMembership.Role))
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
err = oldProjectRole.UnAssignRole(username)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
oldPipelineRole, err := jenkinsClient.GetProjectRole(GetPipelineRoleName(projectId, oldMembership.Role))
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
err = oldPipelineRole.UnAssignRole(username)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
@@ -336,7 +374,7 @@ func DeleteProjectMember(projectId, username string) (string, error) {
db.Eq(DevOpsProjectMembershipUsernameColumn, username),
)).Exec()
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusInternalServerError, err.Error())
}
return username, nil

View File

@@ -19,7 +19,7 @@ import (
"github.com/golang/glog"
"github.com/kubesphere/sonargo/sonar"
"kubesphere.io/kubesphere/pkg/gojenkins"
"kubesphere.io/kubesphere/pkg/simple/client/sonarqube"
"kubesphere.io/kubesphere/pkg/simple/client"
"strconv"
"strings"
"time"
@@ -83,6 +83,7 @@ type MultiBranchPipeline struct {
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_triggeromitempty" mapstructure:"multibranch_job_trigger" description:"Pipeline tasks that need to be triggered when branch creation/deletion"`
}
type GitSource struct {
@@ -107,6 +108,11 @@ type GithubSource struct {
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"`
@@ -169,7 +175,7 @@ type RemoteTrigger struct {
}
func replaceXmlVersion(config, oldVersion, targetVersion string) string {
lines := strings.Split(string(config), "\n")
lines := strings.Split(config, "\n")
lines[0] = strings.Replace(lines[0], oldVersion, targetVersion, -1)
output := strings.Join(lines, "\n")
return output
@@ -837,6 +843,22 @@ func (s *SingleSvnSource) appendToEtree(source *etree.Element) *SingleSvnSource
return s
}
func (s *MultiBranchJobTrigger) appendToEtree(properties *etree.Element) *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
}
func (s *MultiBranchJobTrigger) fromEtree(properties *etree.Element) *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
}
func createMultiBranchPipelineConfigXml(projectName string, pipeline *MultiBranchPipeline) (string, error) {
doc := etree.NewDocument()
xmlString := `
@@ -869,6 +891,11 @@ func createMultiBranchPipelineConfigXml(projectName string, pipeline *MultiBranc
project := doc.SelectElement("org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject")
project.CreateElement("description").SetText(pipeline.Description)
if pipeline.MultiBranchJobTrigger != nil {
properties := project.SelectElement("properties")
pipeline.MultiBranchJobTrigger.appendToEtree(properties)
}
if pipeline.Discarder != nil {
discarder := project.CreateElement("orphanedItemStrategy")
discarder.CreateAttr("class", "com.cloudbees.hudson.plugins.folder.computed.DefaultOrphanedItemStrategy")
@@ -959,6 +986,14 @@ func parseMultiBranchPipelineConfigXml(config string) (*MultiBranchPipeline, err
if project == nil {
return nil, fmt.Errorf("can not parse mutibranch pipeline config")
}
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.Description = project.SelectElement("description").Text()
if discarder := project.SelectElement("orphanedItemStrategy"); discarder != nil {
@@ -1042,7 +1077,12 @@ func toCrontab(millis int64) string {
}
func getBuildSonarResults(build *gojenkins.Build) ([]*SonarStatus, error) {
sonarClient := sonarqube.Client()
sonarClient, err := client.ClientSets().SonarQube()
if err != nil {
return nil, err
}
actions := build.GetActions()
sonarStatuses := make([]*SonarStatus, 0)
for _, action := range actions {
@@ -1051,7 +1091,7 @@ func getBuildSonarResults(build *gojenkins.Build) ([]*SonarStatus, error) {
taskOptions := &sonargo.CeTaskOption{
Id: action.SonarTaskId,
}
ceTask, _, err := sonarClient.Ce.Task(taskOptions)
ceTask, _, err := sonarClient.SonarQube().Ce.Task(taskOptions)
if err != nil {
glog.Errorf("get sonar task error [%+v]", err)
continue
@@ -1062,7 +1102,7 @@ func getBuildSonarResults(build *gojenkins.Build) ([]*SonarStatus, error) {
AdditionalFields: SonarAdditionalFields,
MetricKeys: SonarMetricKeys,
}
measures, _, err := sonarClient.Measures.Component(measuresComponentOption)
measures, _, err := sonarClient.SonarQube().Measures.Component(measuresComponentOption)
if err != nil {
glog.Errorf("get sonar task error [%+v]", err)
continue
@@ -1077,7 +1117,7 @@ func getBuildSonarResults(build *gojenkins.Build) ([]*SonarStatus, error) {
S: "FILE_LINE",
Facets: "severities,types",
}
issuesSearch, _, err := sonarClient.Issues.Search(issuesSearchOption)
issuesSearch, _, err := sonarClient.SonarQube().Issues.Search(issuesSearchOption)
sonarStatus.Issues = issuesSearch
jenkinsAction := action
sonarStatus.JenkinsAction = &jenkinsAction

View File

@@ -16,43 +16,43 @@ package devops
import (
"fmt"
"github.com/emicklei/go-restful"
"github.com/golang/glog"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/gojenkins/utils"
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins"
cs "kubesphere.io/kubesphere/pkg/simple/client"
"net/http"
)
func CreateProjectPipeline(projectId string, pipeline *ProjectPipeline) (string, error) {
jenkinsClient := admin_jenkins.Client()
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
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 {
glog.Errorf("%+v", err)
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())
glog.Warning(err.Error())
klog.Warning(err.Error())
return "", restful.NewError(http.StatusConflict, err.Error())
}
if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
_, err = jenkinsClient.CreateJobInFolder(config, pipeline.Pipeline.Name, projectId)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
@@ -60,7 +60,7 @@ func CreateProjectPipeline(projectId string, pipeline *ProjectPipeline) (string,
case MultiBranchPipelineType:
config, err := createMultiBranchPipelineConfigXml(projectId, pipeline.MultiBranchPipeline)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusInternalServerError, err.Error())
}
@@ -68,18 +68,18 @@ func CreateProjectPipeline(projectId string, pipeline *ProjectPipeline) (string,
job, err := jenkinsClient.GetJob(pipeline.MultiBranchPipeline.Name, projectId)
if job != nil {
err := fmt.Errorf("job name [%s] has been used", job.GetName())
glog.Warning(err.Error())
klog.Warning(err.Error())
return "", restful.NewError(http.StatusConflict, err.Error())
}
if err != nil && utils.GetJenkinsStatusCode(err) != http.StatusNotFound {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
_, err = jenkinsClient.CreateJobInFolder(config, pipeline.MultiBranchPipeline.Name, projectId)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
@@ -87,52 +87,52 @@ func CreateProjectPipeline(projectId string, pipeline *ProjectPipeline) (string,
default:
err := fmt.Errorf("error unsupport job type")
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusBadRequest, err.Error())
}
}
func DeleteProjectPipeline(projectId string, pipelineId string) (string, error) {
jenkinsClient := admin_jenkins.Client()
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
devops, err := cs.ClientSets().Devops()
if err != nil {
return "", restful.NewError(http.StatusServiceUnavailable, err.Error())
}
_, err := jenkinsClient.DeleteJob(pipelineId, projectId)
jenkinsClient := devops.Jenkins()
_, err = jenkinsClient.DeleteJob(pipelineId, projectId)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
return pipelineId, nil
}
func UpdateProjectPipeline(projectId, pipelineId string, pipeline *ProjectPipeline) (string, error) {
jenkinsClient := admin_jenkins.Client()
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
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 {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusInternalServerError, err.Error())
}
job, err := jenkinsClient.GetJob(pipelineId, projectId)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
err = job.UpdateConfig(config)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
@@ -141,7 +141,7 @@ func UpdateProjectPipeline(projectId, pipelineId string, pipeline *ProjectPipeli
config, err := createMultiBranchPipelineConfigXml(projectId, pipeline.MultiBranchPipeline)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusInternalServerError, err.Error())
}
@@ -149,13 +149,13 @@ func UpdateProjectPipeline(projectId, pipelineId string, pipeline *ProjectPipeli
job, err := jenkinsClient.GetJob(pipelineId, projectId)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
err = job.UpdateConfig(config)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
@@ -163,33 +163,33 @@ func UpdateProjectPipeline(projectId, pipelineId string, pipeline *ProjectPipeli
default:
err := fmt.Errorf("error unsupport job type")
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return "", restful.NewError(http.StatusBadRequest, err.Error())
}
}
func GetProjectPipeline(projectId, pipelineId string) (*ProjectPipeline, error) {
jenkinsClient := admin_jenkins.Client()
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
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 {
glog.Errorf("%+v", err)
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 {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
pipeline, err := parsePipelineConfigXml(config)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
pipeline.Name = pipelineId
@@ -201,12 +201,12 @@ func GetProjectPipeline(projectId, pipelineId string) (*ProjectPipeline, error)
case "org.jenkinsci.plugins.workflow.multibranch.WorkflowMultiBranchProject":
config, err := job.GetConfig()
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
pipeline, err := parseMultiBranchPipelineConfigXml(config)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
pipeline.Name = pipelineId
@@ -216,50 +216,50 @@ func GetProjectPipeline(projectId, pipelineId string) (*ProjectPipeline, error)
}, nil
default:
err := fmt.Errorf("error unsupport job type")
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusBadRequest, err.Error())
}
}
func GetPipelineSonar(projectId, pipelineId string) ([]*SonarStatus, error) {
jenkinsClient := admin_jenkins.Client()
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
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 {
glog.Errorf("%+v", err)
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 {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} else if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, nil
}
sonarStatus, err := getBuildSonarResults(build)
if err != nil {
glog.Errorf("%+v", err)
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 {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} else if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, nil
}
sonarStatus, err = getBuildSonarResults(build)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusBadRequest, err.Error())
}
}
@@ -267,43 +267,43 @@ func GetPipelineSonar(projectId, pipelineId string) ([]*SonarStatus, error) {
}
func GetMultiBranchPipelineSonar(projectId, pipelineId, branchId string) ([]*SonarStatus, error) {
jenkinsClient := admin_jenkins.Client()
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
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 {
glog.Errorf("%+v", err)
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 {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} else if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, nil
}
sonarStatus, err := getBuildSonarResults(build)
if err != nil {
glog.Errorf("%+v", err)
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 {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
} else if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, nil
}
sonarStatus, err = getBuildSonarResults(build)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusBadRequest, err.Error())
}
}

View File

@@ -20,17 +20,17 @@ import (
func Test_NoScmPipelineConfig(t *testing.T) {
inputs := []*NoScmPipeline{
&NoScmPipeline{
{
Name: "",
Description: "for test",
Jenkinsfile: "node{echo 'hello'}",
},
&NoScmPipeline{
{
Name: "",
Description: "",
Jenkinsfile: "node{echo 'hello'}",
},
&NoScmPipeline{
{
Name: "",
Description: "",
Jenkinsfile: "node{echo 'hello'}",
@@ -55,7 +55,7 @@ func Test_NoScmPipelineConfig(t *testing.T) {
func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
inputs := []*NoScmPipeline{
&NoScmPipeline{
{
Name: "",
Description: "for test",
Jenkinsfile: "node{echo 'hello'}",
@@ -63,7 +63,7 @@ func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
"3", "5",
},
},
&NoScmPipeline{
{
Name: "",
Description: "for test",
Jenkinsfile: "node{echo 'hello'}",
@@ -71,7 +71,7 @@ func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
"3", "",
},
},
&NoScmPipeline{
{
Name: "",
Description: "for test",
Jenkinsfile: "node{echo 'hello'}",
@@ -79,7 +79,7 @@ func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
"", "21321",
},
},
&NoScmPipeline{
{
Name: "",
Description: "for test",
Jenkinsfile: "node{echo 'hello'}",
@@ -106,7 +106,7 @@ func Test_NoScmPipelineConfig_Discarder(t *testing.T) {
func Test_NoScmPipelineConfig_Param(t *testing.T) {
inputs := []*NoScmPipeline{
&NoScmPipeline{
{
Name: "",
Description: "for test",
Jenkinsfile: "node{echo 'hello'}",
@@ -119,7 +119,7 @@ func Test_NoScmPipelineConfig_Param(t *testing.T) {
},
},
},
&NoScmPipeline{
{
Name: "",
Description: "for test",
Jenkinsfile: "node{echo 'hello'}",
@@ -169,7 +169,7 @@ func Test_NoScmPipelineConfig_Param(t *testing.T) {
func Test_NoScmPipelineConfig_Trigger(t *testing.T) {
inputs := []*NoScmPipeline{
&NoScmPipeline{
{
Name: "",
Description: "for test",
Jenkinsfile: "node{echo 'hello'}",
@@ -178,7 +178,7 @@ func Test_NoScmPipelineConfig_Trigger(t *testing.T) {
},
},
&NoScmPipeline{
{
Name: "",
Description: "for test",
Jenkinsfile: "node{echo 'hello'}",
@@ -186,7 +186,7 @@ func Test_NoScmPipelineConfig_Trigger(t *testing.T) {
Token: "abc",
},
},
&NoScmPipeline{
{
Name: "",
Description: "for test",
Jenkinsfile: "node{echo 'hello'}",
@@ -218,28 +218,28 @@ func Test_NoScmPipelineConfig_Trigger(t *testing.T) {
func Test_MultiBranchPipelineConfig(t *testing.T) {
inputs := []*MultiBranchPipeline{
&MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "git",
GitSource: &GitSource{},
},
&MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "github",
GitHubSource: &GithubSource{},
},
&MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "single_svn",
SingleSvnSource: &SingleSvnSource{},
},
&MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
@@ -266,7 +266,7 @@ func Test_MultiBranchPipelineConfig(t *testing.T) {
func Test_MultiBranchPipelineConfig_Discarder(t *testing.T) {
inputs := []*MultiBranchPipeline{
&MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
@@ -296,7 +296,7 @@ func Test_MultiBranchPipelineConfig_Discarder(t *testing.T) {
func Test_MultiBranchPipelineConfig_TimerTrigger(t *testing.T) {
inputs := []*MultiBranchPipeline{
&MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
@@ -326,7 +326,7 @@ func Test_MultiBranchPipelineConfig_TimerTrigger(t *testing.T) {
func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
inputs := []*MultiBranchPipeline{
&MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
@@ -340,7 +340,7 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
DiscoverBranches: true,
},
},
&MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
@@ -361,7 +361,7 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
},
},
},
&MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
@@ -383,7 +383,7 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
},
},
&MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
@@ -398,7 +398,7 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
Includes: "tag/*",
},
},
&MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
@@ -432,7 +432,7 @@ func Test_MultiBranchPipelineConfig_Source(t *testing.T) {
func Test_MultiBranchPipelineCloneConfig(t *testing.T) {
inputs := []*MultiBranchPipeline{
&MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
@@ -448,7 +448,7 @@ func Test_MultiBranchPipelineCloneConfig(t *testing.T) {
},
},
},
&MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
@@ -493,7 +493,7 @@ func Test_MultiBranchPipelineCloneConfig(t *testing.T) {
func Test_MultiBranchPipelineRegexFilter(t *testing.T) {
inputs := []*MultiBranchPipeline{
&MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
@@ -505,7 +505,7 @@ func Test_MultiBranchPipelineRegexFilter(t *testing.T) {
RegexFilter: ".*",
},
},
&MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
@@ -542,3 +542,92 @@ func Test_MultiBranchPipelineRegexFilter(t *testing.T) {
}
}
func Test_MultiBranchPipelineMultibranchTrigger(t *testing.T) {
inputs := []*MultiBranchPipeline{
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "github",
GitHubSource: &GithubSource{
Owner: "kubesphere",
Repo: "devops",
CredentialId: "github",
ApiUri: "https://api.github.com",
DiscoverBranches: 1,
DiscoverPRFromOrigin: 2,
DiscoverPRFromForks: &DiscoverPRFromForks{
Strategy: 1,
Trust: 1,
},
RegexFilter: ".*",
},
MultiBranchJobTrigger: &MultiBranchJobTrigger{
CreateActionJobsToTrigger: "abc",
DeleteActionJobsToTrigger: "ddd",
},
},
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "github",
GitHubSource: &GithubSource{
Owner: "kubesphere",
Repo: "devops",
CredentialId: "github",
ApiUri: "https://api.github.com",
DiscoverBranches: 1,
DiscoverPRFromOrigin: 2,
DiscoverPRFromForks: &DiscoverPRFromForks{
Strategy: 1,
Trust: 1,
},
RegexFilter: ".*",
},
MultiBranchJobTrigger: &MultiBranchJobTrigger{
CreateActionJobsToTrigger: "abc",
},
},
{
Name: "",
Description: "for test",
ScriptPath: "Jenkinsfile",
SourceType: "github",
GitHubSource: &GithubSource{
Owner: "kubesphere",
Repo: "devops",
CredentialId: "github",
ApiUri: "https://api.github.com",
DiscoverBranches: 1,
DiscoverPRFromOrigin: 2,
DiscoverPRFromForks: &DiscoverPRFromForks{
Strategy: 1,
Trust: 1,
},
RegexFilter: ".*",
},
MultiBranchJobTrigger: &MultiBranchJobTrigger{
DeleteActionJobsToTrigger: "ddd",
},
},
}
for _, input := range inputs {
outputString, err := createMultiBranchPipelineConfigXml("", input)
if err != nil {
t.Fatalf("should not get error %+v", err)
}
output, err := parseMultiBranchPipelineConfigXml(outputString)
if err != nil {
t.Fatalf("should not get error %+v", err)
}
if !reflect.DeepEqual(input, output) {
t.Fatalf("input [%+v] output [%+v] should equal ", input, output)
}
}
}

View File

@@ -13,8 +13,7 @@ import (
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/apis/devops/v1alpha1"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/s2is3"
"kubesphere.io/kubesphere/pkg/simple/client"
"mime/multipart"
"net/http"
"reflect"
@@ -26,6 +25,11 @@ const (
)
func UploadS2iBinary(namespace, name, md5 string, fileHeader *multipart.FileHeader) (*v1alpha1.S2iBinary, error) {
s3Client, err := client.ClientSets().S3()
if err != nil {
return nil, err
}
binFile, err := fileHeader.Open()
if err != nil {
klog.Errorf("%+v", err)
@@ -66,7 +70,8 @@ func UploadS2iBinary(namespace, name, md5 string, fileHeader *multipart.FileHead
copy.Spec.Size = bytefmt.ByteSize(uint64(fileHeader.Size))
copy.Spec.FileName = fileHeader.Filename
copy.Spec.DownloadURL = fmt.Sprintf(GetS2iBinaryURL, namespace, name, copy.Spec.FileName)
s3session := s2is3.Session()
s3session := s3Client.Session()
if s3session == nil {
err := fmt.Errorf("could not connect to s2i s3")
klog.Error(err)
@@ -82,7 +87,7 @@ func UploadS2iBinary(namespace, name, md5 string, fileHeader *multipart.FileHead
uploader.LeavePartsOnError = true
})
_, err = uploader.Upload(&s3manager.UploadInput{
Bucket: s2is3.Bucket(),
Bucket: s3Client.Bucket(),
Key: aws.String(fmt.Sprintf("%s-%s", namespace, name)),
Body: binFile,
ContentMD5: aws.String(md5),
@@ -116,7 +121,7 @@ func UploadS2iBinary(namespace, name, md5 string, fileHeader *multipart.FileHead
copy.Spec.UploadTimeStamp = new(metav1.Time)
}
*copy.Spec.UploadTimeStamp = metav1.Now()
copy, err = k8s.KsClient().DevopsV1alpha1().S2iBinaries(namespace).Update(copy)
copy, err = client.ClientSets().K8s().KubeSphere().DevopsV1alpha1().S2iBinaries(namespace).Update(copy)
if err != nil {
klog.Error(err)
return nil, err
@@ -131,6 +136,11 @@ func UploadS2iBinary(namespace, name, md5 string, fileHeader *multipart.FileHead
}
func DownloadS2iBinary(namespace, name, fileName string) (string, error) {
s3Client, err := client.ClientSets().S3()
if err != nil {
return "", err
}
origin, err := informers.KsSharedInformerFactory().Devops().V1alpha1().S2iBinaries().Lister().S2iBinaries(namespace).Get(name)
if err != nil {
klog.Errorf("%+v", err)
@@ -146,14 +156,9 @@ func DownloadS2iBinary(namespace, name, fileName string) (string, error) {
klog.Error(err)
return "", err
}
s3Client := s2is3.Client()
if s3Client == nil {
err := fmt.Errorf("could not get s3 client")
klog.Error(err)
return "", err
}
req, _ := s3Client.GetObjectRequest(&s3.GetObjectInput{
Bucket: s2is3.Bucket(),
req, _ := 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)),
})
@@ -169,7 +174,7 @@ func DownloadS2iBinary(namespace, name, fileName string) (string, error) {
func SetS2iBinaryStatus(s2ibin *v1alpha1.S2iBinary, status string) (*v1alpha1.S2iBinary, error) {
copy := s2ibin.DeepCopy()
copy.Status.Phase = status
copy, err := k8s.KsClient().DevopsV1alpha1().S2iBinaries(s2ibin.Namespace).Update(copy)
copy, err := client.ClientSets().K8s().KubeSphere().DevopsV1alpha1().S2iBinaries(s2ibin.Namespace).Update(copy)
if err != nil {
klog.Error(err)
return nil, err
@@ -188,7 +193,7 @@ func SetS2iBinaryStatusWithRetry(s2ibin *v1alpha1.S2iBinary, status string) (*v1
return err
}
bin.Status.Phase = status
bin, err = k8s.KsClient().DevopsV1alpha1().S2iBinaries(s2ibin.Namespace).Update(bin)
bin, err = client.ClientSets().K8s().KubeSphere().DevopsV1alpha1().S2iBinaries(s2ibin.Namespace).Update(bin)
if err != nil {
klog.Error(err)
return err

View File

@@ -52,10 +52,11 @@ const (
GetConsoleLogUrl = "/job/%s/job/%s/indexing/consoleText"
ScanBranchUrl = "/job/%s/job/%s/build?"
GetCrumbUrl = "/crumbIssuer/api/json/"
CheckScriptCompileUrl = "/job/init-job/descriptorByName/org.jenkinsci.plugins.workflow.cps.CpsFlowDefinition/checkScriptCompile"
CheckCronUrl = "/job/init-job/descriptorByName/hudson.triggers.TimerTrigger/checkSpec?"
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"
)

View File

@@ -33,7 +33,7 @@ import (
"kubesphere.io/kubesphere/pkg/models/kubectl"
"kubesphere.io/kubesphere/pkg/models/resources"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
"sort"
@@ -650,7 +650,7 @@ func CreateClusterRoleBinding(username string, clusterRoleName string) error {
found, err := clusterRoleBindingLister.Get(username)
if apierrors.IsNotFound(err) {
_, err = k8s.Client().RbacV1().ClusterRoleBindings().Create(clusterRoleBinding)
_, err = client.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Create(clusterRoleBinding)
if err != nil {
glog.Errorln("create cluster role binding", err)
return err
@@ -665,14 +665,14 @@ func CreateClusterRoleBinding(username string, clusterRoleName string) error {
deletePolicy := metav1.DeletePropagationForeground
gracePeriodSeconds := int64(0)
deleteOption := &metav1.DeleteOptions{PropagationPolicy: &deletePolicy, GracePeriodSeconds: &gracePeriodSeconds}
err = k8s.Client().RbacV1().ClusterRoleBindings().Delete(found.Name, deleteOption)
err = client.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Delete(found.Name, deleteOption)
if err != nil {
glog.Errorln("delete cluster role binding", err)
return err
}
maxRetries := 3
for i := 0; i < maxRetries; i++ {
_, err = k8s.Client().RbacV1().ClusterRoleBindings().Create(clusterRoleBinding)
_, err = client.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Create(clusterRoleBinding)
if err == nil {
return nil
}
@@ -684,7 +684,7 @@ func CreateClusterRoleBinding(username string, clusterRoleName string) error {
if !k8sutil.ContainsUser(found.Subjects, username) {
found.Subjects = clusterRoleBinding.Subjects
_, err = k8s.Client().RbacV1().ClusterRoleBindings().Update(found)
_, err = client.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Update(found)
if err != nil {
glog.Errorln("update cluster role binding", err)
return err

View File

@@ -23,6 +23,7 @@ import (
"fmt"
"github.com/emicklei/go-restful"
"io/ioutil"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/db"
"kubesphere.io/kubesphere/pkg/informers"
@@ -30,10 +31,7 @@ import (
"kubesphere.io/kubesphere/pkg/models/kubeconfig"
"kubesphere.io/kubesphere/pkg/models/kubectl"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins"
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client/redis"
clientset "kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
"net/http"
@@ -45,9 +43,8 @@ import (
"github.com/dgrijalva/jwt-go"
"github.com/go-ldap/ldap"
"github.com/golang/glog"
rbacv1 "k8s.io/api/rbac/v1"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
ldapclient "kubesphere.io/kubesphere/pkg/simple/client/ldap"
@@ -81,25 +78,22 @@ func Init(email, password string, expireTime time.Duration, authRateLimit string
adminPassword = password
tokenExpireTime = expireTime
maxAuthFailed, authTimeInterval = parseAuthRateLimit(authRateLimit)
conn, err := ldapclient.Client()
conn, err := clientset.ClientSets().Ldap()
if err != nil {
return err
}
defer conn.Close()
err = checkAndCreateDefaultUser(conn)
if err != nil {
glog.Errorln("create default users", err)
klog.Errorln("create default users", err)
return err
}
err = checkAndCreateDefaultGroup(conn)
if err != nil {
glog.Errorln("create default groups", err)
klog.Errorln("create default groups", err)
return err
}
@@ -117,28 +111,28 @@ func parseAuthRateLimit(authRateLimit string) (int, time.Duration) {
maxCount, _ = strconv.Atoi(groups[1])
timeInterval, _ = time.ParseDuration(groups[2])
} else {
glog.Warning("invalid auth rate limit", authRateLimit)
klog.Warning("invalid auth rate limit", authRateLimit)
}
return maxCount, timeInterval
}
func checkAndCreateDefaultGroup(conn ldap.Client) error {
func checkAndCreateDefaultGroup(conn *ldapclient.LdapClient) error {
groupSearchRequest := ldap.NewSearchRequest(
ldapclient.GroupSearchBase,
conn.GroupSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=posixGroup))",
nil,
nil,
)
_, err := conn.Search(groupSearchRequest)
_, err := conn.Ldap().Search(groupSearchRequest)
if ldap.IsErrorWithCode(err, ldap.LDAPResultNoSuchObject) {
err = createGroupsBaseDN(conn)
if err != nil {
return fmt.Errorf("GroupBaseDN %s create failed: %s\n", ldapclient.GroupSearchBase, err)
return fmt.Errorf("GroupBaseDN %s create failed: %s\n", conn.GroupSearchBase(), err)
}
}
@@ -149,22 +143,22 @@ func checkAndCreateDefaultGroup(conn ldap.Client) error {
return nil
}
func checkAndCreateDefaultUser(conn ldap.Client) error {
func checkAndCreateDefaultUser(conn *ldapclient.LdapClient) error {
userSearchRequest := ldap.NewSearchRequest(
ldapclient.UserSearchBase,
conn.GroupSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=inetOrgPerson))",
[]string{"uid"},
nil,
)
result, err := conn.Search(userSearchRequest)
result, err := conn.Ldap().Search(userSearchRequest)
if ldap.IsErrorWithCode(err, ldap.LDAPResultNoSuchObject) {
err = createUserBaseDN(conn)
if err != nil {
return fmt.Errorf("UserBaseDN %s create failed: %s\n", ldapclient.UserSearchBase, err)
return fmt.Errorf("UserBaseDN %s create failed: %s\n", conn.UserSearchBase(), err)
}
}
@@ -182,7 +176,7 @@ func checkAndCreateDefaultUser(conn ldap.Client) error {
if result == nil || !containsUser(result.Entries, user) {
_, err = CreateUser(&user.User)
if err != nil && !ldap.IsErrorWithCode(err, ldap.LDAPResultEntryAlreadyExists) {
glog.Errorln("user init failed", user.Username, err)
klog.Errorln("user init failed", user.Username, err)
return fmt.Errorf("user %s init failed: %s\n", user.Username, err)
}
}
@@ -201,36 +195,33 @@ func containsUser(entries []*ldap.Entry, user initUser) bool {
return false
}
func createUserBaseDN(conn ldap.Client) error {
func createUserBaseDN(conn *ldapclient.LdapClient) error {
conn, err := ldapclient.Client()
if err != nil {
return err
}
defer conn.Close()
groupsCreateRequest := ldap.NewAddRequest(ldapclient.UserSearchBase, nil)
groupsCreateRequest := ldap.NewAddRequest(conn.UserSearchBase(), nil)
groupsCreateRequest.Attribute("objectClass", []string{"organizationalUnit", "top"})
groupsCreateRequest.Attribute("ou", []string{"Users"})
return conn.Add(groupsCreateRequest)
return conn.Ldap().Add(groupsCreateRequest)
}
func createGroupsBaseDN(conn ldap.Client) error {
groupsCreateRequest := ldap.NewAddRequest(ldapclient.GroupSearchBase, nil)
func createGroupsBaseDN(conn *ldapclient.LdapClient) error {
groupsCreateRequest := ldap.NewAddRequest(conn.GroupSearchBase(), nil)
groupsCreateRequest.Attribute("objectClass", []string{"organizationalUnit", "top"})
groupsCreateRequest.Attribute("ou", []string{"Groups"})
return conn.Add(groupsCreateRequest)
return conn.Ldap().Add(groupsCreateRequest)
}
// User login
func Login(username string, password string, ip string) (*models.Token, error) {
redisClient := redis.Client()
redisClient, err := clientset.ClientSets().Redis()
if err != nil {
return nil, err
}
records, err := redisClient.Keys(fmt.Sprintf("kubesphere:authfailed:%s:*", username)).Result()
if err != nil {
glog.Error(err)
klog.Error(err)
return nil, err
}
@@ -238,24 +229,21 @@ func Login(username string, password string, ip string) (*models.Token, error) {
return nil, restful.NewError(http.StatusTooManyRequests, "auth rate limit exceeded")
}
conn, err := ldapclient.Client()
conn, err := clientset.ClientSets().Ldap()
if err != nil {
glog.Error(err)
return nil, err
}
defer conn.Close()
defer conn.Ldap().Close()
userSearchRequest := ldap.NewSearchRequest(
ldapclient.UserSearchBase,
conn.UserSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(&(objectClass=inetOrgPerson)(|(uid=%s)(mail=%s)))", username, username),
[]string{"uid", "mail"},
nil,
)
result, err := conn.Search(userSearchRequest)
result, err := conn.Ldap().Search(userSearchRequest)
if err != nil {
return nil, err
@@ -270,10 +258,10 @@ func Login(username string, password string, ip string) (*models.Token, error) {
dn := result.Entries[0].DN
// bind as the user to verify their password
err = conn.Bind(dn, password)
err = conn.Ldap().Bind(dn, password)
if err != nil {
glog.Infoln("auth failed", username, err)
klog.Infoln("auth failed", username, err)
if ldap.IsErrorWithCode(err, ldap.LDAPResultInvalidCredentials) {
loginFailedRecord := fmt.Sprintf("kubesphere:authfailed:%s:%d", username, time.Now().UnixNano())
@@ -300,14 +288,20 @@ func Login(username string, password string, ip string) (*models.Token, error) {
func loginLog(uid, ip string) {
if ip != "" {
redisClient := redis.Client()
redisClient, err := clientset.ClientSets().Redis()
if err != nil {
return
}
redisClient.RPush(fmt.Sprintf("kubesphere:users:%s:login-log", uid), fmt.Sprintf("%s,%s", time.Now().UTC().Format("2006-01-02T15:04:05Z"), ip))
redisClient.LTrim(fmt.Sprintf("kubesphere:users:%s:login-log", uid), -10, -1)
}
}
func LoginLog(username string) ([]string, error) {
redisClient := redis.Client()
redisClient, err := clientset.ClientSets().Redis()
if err != nil {
return nil, err
}
data, err := redisClient.LRange(fmt.Sprintf("kubesphere:users:%s:login-log", username), -10, -1).Result()
@@ -320,13 +314,11 @@ func LoginLog(username string) ([]string, error) {
func ListUsers(conditions *params.Conditions, orderBy string, reverse bool, limit, offset int) (*models.PageableResponse, error) {
conn, err := ldapclient.Client()
conn, err := clientset.ClientSets().Ldap()
if err != nil {
return nil, err
}
defer conn.Close()
defer conn.Ldap().Close()
pageControl := ldap.NewControlPaging(1000)
@@ -356,17 +348,17 @@ func ListUsers(conditions *params.Conditions, orderBy string, reverse bool, limi
for {
userSearchRequest := ldap.NewSearchRequest(
ldapclient.UserSearchBase,
conn.UserSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
filter,
[]string{"uid", "mail", "description", "preferredLanguage", "createTimestamp"},
[]ldap.Control{pageControl},
)
response, err := conn.Search(userSearchRequest)
response, err := conn.Ldap().Search(userSearchRequest)
if err != nil {
glog.Errorln("search user", err)
klog.Errorln("search user", err)
return nil, err
}
@@ -461,26 +453,24 @@ func DescribeUser(username string) (*models.User, error) {
// Get user info only included email description & lang
func GetUserInfo(username string) (*models.User, error) {
conn, err := ldapclient.Client()
conn, err := clientset.ClientSets().Ldap()
if err != nil {
return nil, err
}
defer conn.Close()
defer conn.Ldap().Close()
userSearchRequest := ldap.NewSearchRequest(
ldapclient.UserSearchBase,
conn.UserSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(&(objectClass=inetOrgPerson)(uid=%s))", username),
[]string{"mail", "description", "preferredLanguage", "createTimestamp"},
nil,
)
result, err := conn.Search(userSearchRequest)
result, err := conn.Ldap().Search(userSearchRequest)
if err != nil {
glog.Errorln("search user", err)
klog.Errorln("search user", err)
return nil, err
}
@@ -500,23 +490,22 @@ func GetUserInfo(username string) (*models.User, error) {
}
func GetUserGroups(username string) ([]string, error) {
conn, err := ldapclient.Client()
conn, err := clientset.ClientSets().Ldap()
if err != nil {
return nil, err
}
defer conn.Close()
defer conn.Ldap().Close()
groupSearchRequest := ldap.NewSearchRequest(
ldapclient.GroupSearchBase,
conn.GroupSearchBase(),
ldap.ScopeBaseObject, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(&(objectClass=posixGroup)(memberUid=%s))", username),
nil,
nil,
)
result, err := conn.Search(groupSearchRequest)
result, err := conn.Ldap().Search(groupSearchRequest)
if err != nil {
return nil, err
@@ -533,7 +522,12 @@ func GetUserGroups(username string) ([]string, error) {
}
func getLastLoginTime(username string) string {
lastLogin, err := redis.Client().LRange(fmt.Sprintf("kubesphere:users:%s:login-log", username), -1, -1).Result()
redis, err := clientset.ClientSets().Redis()
if err != nil {
return ""
}
lastLogin, err := redis.LRange(fmt.Sprintf("kubesphere:users:%s:login-log", username), -1, -1).Result()
if err != nil {
return ""
@@ -547,13 +541,22 @@ func getLastLoginTime(username string) string {
}
func setAvatar(username, avatar string) error {
_, err := redis.Client().HMSet("kubesphere:users:avatar", map[string]interface{}{"username": avatar}).Result()
redis, err := clientset.ClientSets().Redis()
if err != nil {
return err
}
_, err = redis.HMSet("kubesphere:users:avatar", map[string]interface{}{"username": avatar}).Result()
return err
}
func getAvatar(username string) string {
redis, err := clientset.ClientSets().Redis()
if err != nil {
return ""
}
avatar, err := redis.Client().HMGet("kubesphere:users:avatar", username).Result()
avatar, err := redis.HMGet("kubesphere:users:avatar", username).Result()
if err != nil {
return ""
@@ -570,53 +573,54 @@ func getAvatar(username string) string {
func DeleteUser(username string) error {
conn, err := ldapclient.Client()
conn, err := clientset.ClientSets().Ldap()
if err != nil {
return err
}
defer conn.Ldap().Close()
defer conn.Close()
deleteRequest := ldap.NewDelRequest(fmt.Sprintf("uid=%s,%s", username, conn.UserSearchBase()), nil)
deleteRequest := ldap.NewDelRequest(fmt.Sprintf("uid=%s,%s", username, ldapclient.UserSearchBase), nil)
if err = conn.Del(deleteRequest); err != nil {
glog.Errorln("delete user", err)
if err = conn.Ldap().Del(deleteRequest); err != nil {
klog.Errorln("delete user", err)
return err
}
if err = deleteRoleBindings(username); err != nil {
glog.Errorln("delete user role bindings failed", username, err)
klog.Errorln("delete user role bindings failed", username, err)
}
if err := kubeconfig.DelKubeConfig(username); err != nil {
glog.Errorln("delete user kubeconfig failed", username, err)
klog.Errorln("delete user kubeconfig failed", username, err)
}
if err := kubectl.DelKubectlDeploy(username); err != nil {
glog.Errorln("delete user terminal pod failed", username, err)
klog.Errorln("delete user terminal pod failed", username, err)
}
devopsDb := devops_mysql.OpenDatabase()
jenkinsClient := admin_jenkins.Client()
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
return restful.NewError(http.StatusServiceUnavailable, err.Error())
devopsDb, err := clientset.ClientSets().MySQL()
if err != nil {
return err
}
dp, err := clientset.ClientSets().Devops()
if err != nil {
return err
}
jenkinsClient := dp.Jenkins()
_, err = devopsDb.DeleteFrom(devops.DevOpsProjectMembershipTableName).
Where(db.And(
db.Eq(devops.DevOpsProjectMembershipUsernameColumn, username),
)).Exec()
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return err
}
err = jenkinsClient.DeleteUserInProject(username)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return err
}
@@ -646,17 +650,17 @@ func deleteRoleBindings(username string) error {
length2 := len(roleBinding.Subjects)
if length2 == 0 {
deletePolicy := meta_v1.DeletePropagationForeground
err = k8s.Client().RbacV1().RoleBindings(roleBinding.Namespace).Delete(roleBinding.Name, &meta_v1.DeleteOptions{PropagationPolicy: &deletePolicy})
deletePolicy := metav1.DeletePropagationForeground
err = clientset.ClientSets().K8s().Kubernetes().RbacV1().RoleBindings(roleBinding.Namespace).Delete(roleBinding.Name, &metav1.DeleteOptions{PropagationPolicy: &deletePolicy})
if err != nil {
glog.Errorf("delete role binding %s %s %s failed: %v", username, roleBinding.Namespace, roleBinding.Name, err)
klog.Errorf("delete role binding %s %s %s failed: %v", username, roleBinding.Namespace, roleBinding.Name, err)
}
} else if length2 < length1 {
_, err = k8s.Client().RbacV1().RoleBindings(roleBinding.Namespace).Update(roleBinding)
_, err = clientset.ClientSets().K8s().Kubernetes().RbacV1().RoleBindings(roleBinding.Namespace).Update(roleBinding)
if err != nil {
glog.Errorf("update role binding %s %s %s failed: %v", username, roleBinding.Namespace, roleBinding.Name, err)
klog.Errorf("update role binding %s %s %s failed: %v", username, roleBinding.Namespace, roleBinding.Name, err)
}
}
}
@@ -679,19 +683,19 @@ func deleteRoleBindings(username string) error {
if length2 == 0 {
// delete if it's not workspace role binding
if isWorkspaceRoleBinding(clusterRoleBinding) {
_, err = k8s.Client().RbacV1().ClusterRoleBindings().Update(clusterRoleBinding)
_, err = clientset.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Update(clusterRoleBinding)
} else {
deletePolicy := meta_v1.DeletePropagationForeground
err = k8s.Client().RbacV1().ClusterRoleBindings().Delete(clusterRoleBinding.Name, &meta_v1.DeleteOptions{PropagationPolicy: &deletePolicy})
deletePolicy := metav1.DeletePropagationForeground
err = clientset.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Delete(clusterRoleBinding.Name, &metav1.DeleteOptions{PropagationPolicy: &deletePolicy})
}
if err != nil {
glog.Errorf("update cluster role binding %s failed:%s", clusterRoleBinding.Name, err)
klog.Errorf("update cluster role binding %s failed:%s", clusterRoleBinding.Name, err)
}
} else if length2 < length1 {
_, err = k8s.Client().RbacV1().ClusterRoleBindings().Update(clusterRoleBinding)
_, err = clientset.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Update(clusterRoleBinding)
if err != nil {
glog.Errorf("update cluster role binding %s failed:%s", clusterRoleBinding.Name, err)
klog.Errorf("update cluster role binding %s failed:%s", clusterRoleBinding.Name, err)
}
}
@@ -707,27 +711,26 @@ func isWorkspaceRoleBinding(clusterRoleBinding *rbacv1.ClusterRoleBinding) bool
func UserCreateCheck(check string) (exist bool, err error) {
// bind root DN
conn, err := ldapclient.Client()
conn, err := clientset.ClientSets().Ldap()
if err != nil {
return false, err
}
defer conn.Close()
defer conn.Ldap().Close()
// search for the given username
userSearchRequest := ldap.NewSearchRequest(
ldapclient.UserSearchBase,
conn.UserSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(&(objectClass=inetOrgPerson)(|(uid=%s)(mail=%s)))", check, check),
[]string{"uid", "mail"},
nil,
)
result, err := conn.Search(userSearchRequest)
result, err := conn.Ldap().Search(userSearchRequest)
if err != nil {
glog.Errorln("search user", err)
klog.Errorln("search user", err)
return false, err
}
@@ -740,26 +743,24 @@ func CreateUser(user *models.User) (*models.User, error) {
user.Password = strings.TrimSpace(user.Password)
user.Description = strings.TrimSpace(user.Description)
conn, err := ldapclient.Client()
conn, err := clientset.ClientSets().Ldap()
if err != nil {
return nil, err
}
defer conn.Close()
defer conn.Ldap().Close()
userSearchRequest := ldap.NewSearchRequest(
ldapclient.UserSearchBase,
conn.UserSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(&(objectClass=inetOrgPerson)(|(uid=%s)(mail=%s)))", user.Username, user.Email),
[]string{"uid", "mail"},
nil,
)
result, err := conn.Search(userSearchRequest)
result, err := conn.Ldap().Search(userSearchRequest)
if err != nil {
glog.Errorln("search user", err)
klog.Errorln("search user", err)
return nil, err
}
@@ -770,13 +771,13 @@ func CreateUser(user *models.User) (*models.User, error) {
maxUid, err := getMaxUid(conn)
if err != nil {
glog.Errorln("get max uid", err)
klog.Errorln("get max uid", err)
return nil, err
}
maxUid += 1
userCreateRequest := ldap.NewAddRequest(fmt.Sprintf("uid=%s,%s", user.Username, ldapclient.UserSearchBase), nil)
userCreateRequest := ldap.NewAddRequest(fmt.Sprintf("uid=%s,%s", user.Username, conn.UserSearchBase()), nil)
userCreateRequest.Attribute("objectClass", []string{"inetOrgPerson", "posixAccount", "top"})
userCreateRequest.Attribute("cn", []string{user.Username}) // RFC4519: common name(s) for which the entity is known by
userCreateRequest.Attribute("sn", []string{" "}) // RFC2256: last (family) name(s) for which the entity is known by
@@ -794,14 +795,14 @@ func CreateUser(user *models.User) (*models.User, error) {
}
if err := kubeconfig.CreateKubeConfig(user.Username); err != nil {
glog.Errorln("create user kubeconfig failed", user.Username, err)
klog.Errorln("create user kubeconfig failed", user.Username, err)
return nil, err
}
err = conn.Add(userCreateRequest)
err = conn.Ldap().Add(userCreateRequest)
if err != nil {
glog.Errorln("create user", err)
klog.Errorln("create user", err)
return nil, err
}
@@ -813,7 +814,7 @@ func CreateUser(user *models.User) (*models.User, error) {
err := CreateClusterRoleBinding(user.Username, user.ClusterRole)
if err != nil {
glog.Errorln("create cluster role binding filed", err)
klog.Errorln("create cluster role binding filed", err)
return nil, err
}
}
@@ -821,14 +822,14 @@ func CreateUser(user *models.User) (*models.User, error) {
return DescribeUser(user.Username)
}
func getMaxUid(conn ldap.Client) (int, error) {
userSearchRequest := ldap.NewSearchRequest(ldapclient.UserSearchBase,
func getMaxUid(conn *ldapclient.LdapClient) (int, error) {
userSearchRequest := ldap.NewSearchRequest(conn.UserSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=inetOrgPerson))",
[]string{"uidNumber"},
nil)
result, err := conn.Search(userSearchRequest)
result, err := conn.Ldap().Search(userSearchRequest)
if err != nil {
return 0, err
@@ -850,15 +851,15 @@ func getMaxUid(conn ldap.Client) (int, error) {
return maxUid, nil
}
func getMaxGid(conn ldap.Client) (int, error) {
func getMaxGid(conn *ldapclient.LdapClient) (int, error) {
groupSearchRequest := ldap.NewSearchRequest(ldapclient.GroupSearchBase,
groupSearchRequest := ldap.NewSearchRequest(conn.GroupSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=posixGroup))",
[]string{"gidNumber"},
nil)
result, err := conn.Search(groupSearchRequest)
result, err := conn.Ldap().Search(groupSearchRequest)
if err != nil {
return 0, err
@@ -882,38 +883,36 @@ func getMaxGid(conn ldap.Client) (int, error) {
func UpdateUser(user *models.User) (*models.User, error) {
conn, err := ldapclient.Client()
conn, err := clientset.ClientSets().Ldap()
if err != nil {
glog.Error(err)
klog.Error(err)
return nil, err
}
defer conn.Ldap().Close()
defer conn.Close()
dn := fmt.Sprintf("uid=%s,%s", user.Username, ldapclient.UserSearchBase)
dn := fmt.Sprintf("uid=%s,%s", user.Username, conn.UserSearchBase())
userModifyRequest := ldap.NewModifyRequest(dn, nil)
if user.Email != "" {
userSearchRequest := ldap.NewSearchRequest(
ldapclient.UserSearchBase,
conn.UserSearchBase(),
ldap.ScopeWholeSubtree, ldap.NeverDerefAliases, 0, 0, false,
fmt.Sprintf("(&(objectClass=inetOrgPerson)(mail=%s))", user.Email),
[]string{"uid", "mail"},
nil,
)
result, err := conn.Search(userSearchRequest)
result, err := conn.Ldap().Search(userSearchRequest)
if err != nil {
glog.Error(err)
klog.Error(err)
return nil, err
}
if len(result.Entries) > 1 {
err = ldap.NewError(ldap.ErrorDebugging, fmt.Errorf("email is duplicated: %s", user.Email))
glog.Error(err)
klog.Error(err)
return nil, err
}
if len(result.Entries) == 1 && result.Entries[0].GetAttributeValue("uid") != user.Username {
err = ldap.NewError(ldap.LDAPResultEntryAlreadyExists, fmt.Errorf("email is duplicated: %s", user.Email))
glog.Error(err)
klog.Error(err)
return nil, err
}
userModifyRequest.Replace("mail", []string{user.Email})
@@ -935,27 +934,30 @@ func UpdateUser(user *models.User) (*models.User, error) {
}
if err != nil {
glog.Error(err)
klog.Error(err)
return nil, err
}
err = conn.Modify(userModifyRequest)
err = conn.Ldap().Modify(userModifyRequest)
if err != nil {
glog.Error(err)
klog.Error(err)
return nil, err
}
err = CreateClusterRoleBinding(user.Username, user.ClusterRole)
if err != nil {
glog.Errorln("create cluster role binding filed", err)
klog.Errorln("create cluster role binding filed", err)
return nil, err
}
// clear auth failed record
if user.Password != "" {
redisClient := redis.Client()
redisClient, err := clientset.ClientSets().Redis()
if err != nil {
return nil, err
}
records, err := redisClient.Keys(fmt.Sprintf("kubesphere:authfailed:%s:*", user.Username)).Result()
@@ -969,19 +971,19 @@ func UpdateUser(user *models.User) (*models.User, error) {
func DeleteGroup(path string) error {
// bind root DN
conn, err := ldapclient.Client()
conn, err := clientset.ClientSets().Ldap()
if err != nil {
return err
}
defer conn.Close()
defer conn.Ldap().Close()
searchBase, cn := splitPath(path)
groupDeleteRequest := ldap.NewDelRequest(fmt.Sprintf("cn=%s,%s", cn, searchBase), nil)
err = conn.Del(groupDeleteRequest)
err = conn.Ldap().Del(groupDeleteRequest)
if err != nil {
glog.Errorln("delete user group", err)
klog.Errorln("delete user group", err)
return err
}
@@ -990,18 +992,16 @@ func DeleteGroup(path string) error {
func CreateGroup(group *models.Group) (*models.Group, error) {
conn, err := ldapclient.Client()
conn, err := clientset.ClientSets().Ldap()
if err != nil {
return nil, err
}
defer conn.Close()
defer conn.Ldap().Close()
maxGid, err := getMaxGid(conn)
if err != nil {
glog.Errorln("get max gid", err)
klog.Errorln("get max gid", err)
return nil, err
}
@@ -1026,10 +1026,10 @@ func CreateGroup(group *models.Group) (*models.Group, error) {
groupCreateRequest.Attribute("memberUid", group.Members)
}
err = conn.Add(groupCreateRequest)
err = conn.Ldap().Add(groupCreateRequest)
if err != nil {
glog.Errorln("create group", err)
klog.Errorln("create group", err)
return nil, err
}
@@ -1041,11 +1041,11 @@ func CreateGroup(group *models.Group) (*models.Group, error) {
func UpdateGroup(group *models.Group) (*models.Group, error) {
// bind root DN
conn, err := ldapclient.Client()
conn, err := clientset.ClientSets().Ldap()
if err != nil {
return nil, err
}
defer conn.Close()
defer conn.Ldap().Close()
old, err := DescribeGroup(group.Path)
@@ -1073,10 +1073,10 @@ func UpdateGroup(group *models.Group) (*models.Group, error) {
groupUpdateRequest.Replace("memberUid", group.Members)
}
err = conn.Modify(groupUpdateRequest)
err = conn.Ldap().Modify(groupUpdateRequest)
if err != nil {
glog.Errorln("update group", err)
klog.Errorln("update group", err)
return nil, err
}
@@ -1086,17 +1086,15 @@ func UpdateGroup(group *models.Group) (*models.Group, error) {
func ChildList(path string) ([]models.Group, error) {
// bind root DN
conn, err := ldapclient.Client()
conn, err := clientset.ClientSets().Ldap()
if err != nil {
return nil, err
}
defer conn.Close()
defer conn.Ldap().Close()
var groupSearchRequest *ldap.SearchRequest
if path == "" {
groupSearchRequest = ldap.NewSearchRequest(ldapclient.GroupSearchBase,
groupSearchRequest = ldap.NewSearchRequest(conn.GroupSearchBase(),
ldap.ScopeSingleLevel, ldap.NeverDerefAliases, 0, 0, false,
"(&(objectClass=posixGroup))",
[]string{"cn", "gidNumber", "memberUid", "description"},
@@ -1110,7 +1108,7 @@ func ChildList(path string) ([]models.Group, error) {
nil)
}
result, err := conn.Search(groupSearchRequest)
result, err := conn.Ldap().Search(groupSearchRequest)
if err != nil {
return nil, err
@@ -1133,7 +1131,7 @@ func ChildList(path string) ([]models.Group, error) {
[]string{""},
nil)
result, err = conn.Search(childSearchRequest)
result, err = conn.Ldap().Search(childSearchRequest)
if err != nil {
return nil, err
@@ -1158,13 +1156,11 @@ func DescribeGroup(path string) (*models.Group, error) {
searchBase, cn := splitPath(path)
conn, err := ldapclient.Client()
conn, err := clientset.ClientSets().Ldap()
if err != nil {
return nil, err
}
defer conn.Close()
defer conn.Ldap().Close()
groupSearchRequest := ldap.NewSearchRequest(searchBase,
ldap.ScopeSingleLevel, ldap.NeverDerefAliases, 0, 0, false,
@@ -1172,10 +1168,10 @@ func DescribeGroup(path string) (*models.Group, error) {
[]string{"cn", "gidNumber", "memberUid", "description"},
nil)
result, err := conn.Search(groupSearchRequest)
result, err := conn.Ldap().Search(groupSearchRequest)
if err != nil {
glog.Errorln("search group", err)
klog.Errorln("search group", err)
return nil, err
}

View File

@@ -19,7 +19,7 @@ package iam
import (
"fmt"
ldapclient "kubesphere.io/kubesphere/pkg/simple/client/ldap"
"kubesphere.io/kubesphere/pkg/simple/client"
"regexp"
"strings"
)
@@ -44,6 +44,10 @@ func convertDNToPath(dn string) string {
}
func splitPath(path string) (searchBase string, cn string) {
ldapClient, err := client.ClientSets().Ldap()
if err != nil {
return "", ""
}
paths := strings.Split(path, ":")
length := len(paths)
@@ -60,12 +64,12 @@ func splitPath(path string) (searchBase string, cn string) {
basePath[i], basePath[j] = basePath[j], basePath[i]
}
searchBase = fmt.Sprintf("%s,%s", strings.Join(basePath, ","), ldapclient.GroupSearchBase)
searchBase = fmt.Sprintf("%s,%s", strings.Join(basePath, ","), ldapClient.GroupSearchBase())
} else if length == 2 {
searchBase = fmt.Sprintf("cn=%s,%s", paths[0], ldapclient.GroupSearchBase)
searchBase = fmt.Sprintf("cn=%s,%s", paths[0], ldapClient.GroupSearchBase())
cn = paths[1]
} else {
searchBase = ldapclient.GroupSearchBase
searchBase = ldapClient.GroupSearchBase()
if paths[0] == "" {
cn = "*"
} else {

View File

@@ -29,7 +29,7 @@ import (
"fmt"
"gopkg.in/yaml.v2"
"io/ioutil"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client"
"math/big"
rd "math/rand"
"time"
@@ -217,7 +217,7 @@ func createKubeConfig(username string) (string, error) {
return "", err
}
base64ServerCa := base64.StdEncoding.EncodeToString(serverCa)
tmpClusterInfo := clusterInfo{CertificateAuthorityData: base64ServerCa, Server: k8s.KubeConfig.Host}
tmpClusterInfo := clusterInfo{CertificateAuthorityData: base64ServerCa, Server: client.ClientSets().K8s().Master()}
tmpCluster := cluster{Cluster: tmpClusterInfo, Name: clusterName}
tmpKubeConfig.Clusters = append(tmpKubeConfig.Clusters, tmpCluster)
@@ -244,7 +244,7 @@ func createKubeConfig(username string) (string, error) {
}
func CreateKubeConfig(username string) error {
k8sClient := k8s.Client()
k8sClient := client.ClientSets().K8s().Kubernetes()
configName := fmt.Sprintf("kubeconfig-%s", username)
_, err := k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Get(configName, metaV1.GetOptions{})
@@ -255,7 +255,7 @@ func CreateKubeConfig(username string) error {
return err
}
data := map[string]string{"config": string(config)}
data := map[string]string{"config": config}
configMap := v1.ConfigMap{TypeMeta: metaV1.TypeMeta{Kind: "Configmap", APIVersion: "v1"}, ObjectMeta: metaV1.ObjectMeta{Name: configName}, Data: data}
_, err = k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Create(&configMap)
if err != nil && !errors.IsAlreadyExists(err) {
@@ -269,7 +269,7 @@ func CreateKubeConfig(username string) error {
}
func GetKubeConfig(username string) (string, error) {
k8sClient := k8s.Client()
k8sClient := client.ClientSets().K8s().Kubernetes()
configName := fmt.Sprintf("kubeconfig-%s", username)
configMap, err := k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Get(configName, metaV1.GetOptions{})
if err != nil {
@@ -284,10 +284,7 @@ func GetKubeConfig(username string) (string, error) {
glog.Error(err)
return "", err
}
masterURL := k8s.KubeConfig.Host
if host := k8s.MasterURL; host != "" {
masterURL = host
}
masterURL := client.ClientSets().K8s().Master()
for i, cluster := range kubeConfig.Clusters {
cluster.Cluster.Server = masterURL
kubeConfig.Clusters[i] = cluster
@@ -301,7 +298,7 @@ func GetKubeConfig(username string) (string, error) {
}
func DelKubeConfig(username string) error {
k8sClient := k8s.Client()
k8sClient := client.ClientSets().K8s().Kubernetes()
configName := fmt.Sprintf("kubeconfig-%s", username)
_, err := k8sClient.CoreV1().ConfigMaps(constants.KubeSphereControlNamespace).Get(configName, metaV1.GetOptions{})
if errors.IsNotFound(err) {

View File

@@ -21,7 +21,7 @@ package kubectl
import (
"fmt"
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client"
"math/rand"
"os"
@@ -49,7 +49,7 @@ func init() {
}
func GetKubectlPod(username string) (models.PodInfo, error) {
k8sClient := k8s.Client()
k8sClient := client.ClientSets().K8s().Kubernetes()
deployName := fmt.Sprintf("kubectl-%s", username)
deploy, err := k8sClient.AppsV1().Deployments(namespace).Get(deployName, metav1.GetOptions{})
if err != nil {
@@ -97,7 +97,7 @@ func selectCorrectPod(namespace string, pods []v1.Pod) (kubectlPod v1.Pod, err e
}
func CreateKubectlDeploy(username string) error {
k8sClient := k8s.Client()
k8sClient := client.ClientSets().K8s().Kubernetes()
deployName := fmt.Sprintf("kubectl-%s", username)
configName := fmt.Sprintf("kubeconfig-%s", username)
_, err := k8sClient.AppsV1().Deployments(namespace).Get(deployName, metav1.GetOptions{})
@@ -140,7 +140,7 @@ func CreateKubectlDeploy(username string) error {
}
func DelKubectlDeploy(username string) error {
k8sClient := k8s.Client()
k8sClient := client.ClientSets().K8s().Kubernetes()
deployName := fmt.Sprintf("kubectl-%s", username)
_, err := k8sClient.AppsV1().Deployments(namespace).Get(deployName, metav1.GetOptions{})
if errors.IsNotFound(err) {

View File

@@ -23,320 +23,69 @@ import (
"k8s.io/apimachinery/pkg/labels"
"kubesphere.io/kubesphere/pkg/constants"
"kubesphere.io/kubesphere/pkg/informers"
"reflect"
"kubesphere.io/kubesphere/pkg/utils/stringutils"
"strconv"
"strings"
"time"
)
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
}
func in(value interface{}, container interface{}) int {
if container == nil {
return -1
}
containerValue := reflect.ValueOf(container)
switch reflect.TypeOf(container).Kind() {
case reflect.Slice, reflect.Array:
for i := 0; i < containerValue.Len(); i++ {
if containerValue.Index(i).Interface() == value {
return i
}
}
case reflect.Map:
if containerValue.MapIndex(reflect.ValueOf(value)).IsValid() {
return -1
}
default:
return -1
}
return -1
}
func getWorkloadName(name string, kind string) string {
if kind == "ReplicaSet" {
lastIndex := strings.LastIndex(name, "-")
if lastIndex >= 0 {
return name[:lastIndex]
}
}
return name
}
func matchLabel(label string, labelsMatch []string) bool {
var result = false
for _, labelMatch := range labelsMatch {
if strings.Compare(label, labelMatch) == 0 {
result = true
break
}
}
return result
}
func queryLabel(label string, labelsQuery []string) bool {
var result = false
for _, labelQuery := range labelsQuery {
if strings.Contains(label, labelQuery) {
result = true
break
}
}
return result
}
func QueryWorkspace(workspaceMatch string, workspaceQuery string) (bool, []string) {
if workspaceMatch == "" && workspaceQuery == "" {
return false, nil
}
// list namespaces that match search conditions
func MatchNamespace(nsFilter []string, nsQuery []string, wsFilter []string, wsQuery []string) (bool, []string) {
nsLister := informers.SharedInformerFactory().Core().V1().Namespaces().Lister()
nsList, err := nsLister.List(labels.Everything())
if err != nil {
glog.Error("failed to list namespace, error: ", err)
glog.Errorf("failed to list namespace, error: %s", err)
return true, nil
}
var namespaces []string
var hasMatch = false
var workspacesMatch []string
if workspaceMatch != "" {
workspacesMatch = strings.Split(strings.Replace(workspaceMatch, ",", " ", -1), " ")
hasMatch = true
}
var hasQuery = false
var workspacesQuery []string
if workspaceQuery != "" {
workspacesQuery = strings.Split(strings.ToLower(strings.Replace(workspaceQuery, ",", " ", -1)), " ")
hasQuery = true
// if no search condition is set on both namespace and workspace,
// then return all namespaces
if nsQuery == nil && nsFilter == nil && wsQuery == nil && wsFilter == nil {
for _, ns := range nsList {
namespaces = append(namespaces, ns.Name)
}
return false, namespaces
}
for _, ns := range nsList {
labels := ns.GetLabels()
_, ok := labels[constants.WorkspaceLabelKey]
if ok {
var namespaceCanAppend = true
if hasMatch {
if !matchLabel(labels[constants.WorkspaceLabelKey], workspacesMatch) {
namespaceCanAppend = false
}
}
if hasQuery {
if !queryLabel(strings.ToLower(labels[constants.WorkspaceLabelKey]), workspacesQuery) {
namespaceCanAppend = false
}
}
if namespaceCanAppend {
namespaces = append(namespaces, ns.GetName())
}
}
}
return true, namespaces
}
func MatchNamespace(namespaceMatch string, namespaceFilled bool, namespaces []string) (bool, []string) {
if namespaceMatch == "" {
return namespaceFilled, namespaces
}
namespacesMatch := strings.Split(strings.Replace(namespaceMatch, ",", " ", -1), " ")
if namespaceFilled {
return true, intersection(namespacesMatch, namespaces)
}
return true, namespacesMatch
}
func GetNamespaceCreationTimeMap(namespaces []string) (bool, map[string]string) {
namespaceWithCreationTime := make(map[string]string)
nsLister := informers.SharedInformerFactory().Core().V1().Namespaces().Lister()
if len(namespaces) == 0 {
nsList, err := nsLister.List(labels.Everything())
if err != nil {
glog.Error("failed to list namespace, error: ", err)
return true, namespaceWithCreationTime
}
for _, ns := range nsList {
if stringutils.StringIn(ns.Name, nsFilter) ||
stringutils.StringIn(ns.Annotations[constants.WorkspaceLabelKey], wsFilter) ||
containsIn(ns.Name, nsQuery) ||
containsIn(ns.Annotations[constants.WorkspaceLabelKey], wsQuery) {
namespaces = append(namespaces, ns.Name)
}
}
// if namespaces is equal to nil, indicates no namespace matched
// it causes the query to return no result
return namespaces == nil, namespaces
}
func containsIn(str string, subStrs []string) bool {
for _, sub := range subStrs {
if strings.Contains(str, sub) {
return true
}
}
return false
}
func MakeNamespaceCreationTimeMap(namespaces []string) map[string]string {
namespaceWithCreationTime := make(map[string]string)
nsLister := informers.SharedInformerFactory().Core().V1().Namespaces().Lister()
for _, item := range namespaces {
ns, err := nsLister.Get(item)
if err != nil {
glog.Error("failed to get namespace, error: ", err)
// the ns doesn't exist
continue
}
namespaceWithCreationTime[ns.Name] = strconv.FormatInt(ns.CreationTimestamp.UnixNano()/int64(time.Millisecond), 10)
}
return true, namespaceWithCreationTime
}
func QueryWorkload(workloadMatch string, workloadQuery string, namespaces []string) (bool, []string) {
if workloadMatch == "" && workloadQuery == "" {
return false, nil
}
podLister := informers.SharedInformerFactory().Core().V1().Pods().Lister()
podList, err := podLister.List(labels.Everything())
if err != nil {
glog.Error("failed to list pods, error: ", err)
return true, nil
}
var pods []string
var hasMatch = false
var workloadsMatch []string
if workloadMatch != "" {
workloadsMatch = strings.Split(strings.Replace(workloadMatch, ",", " ", -1), " ")
hasMatch = true
}
var hasQuery = false
var workloadsQuery []string
if workloadQuery != "" {
workloadsQuery = strings.Split(strings.ToLower(strings.Replace(workloadQuery, ",", " ", -1)), " ")
hasQuery = true
}
if namespaces == nil {
for _, pod := range podList {
/*if len(pod.ObjectMeta.OwnerReferences) > 0 {
glog.Infof("List Pod %v:%v:%v", pod.Name, pod.ObjectMeta.OwnerReferences[0].Name, pod.ObjectMeta.OwnerReferences[0].Kind)
}*/
if len(pod.ObjectMeta.OwnerReferences) > 0 {
var podCanAppend = true
workloadName := getWorkloadName(pod.ObjectMeta.OwnerReferences[0].Name, pod.ObjectMeta.OwnerReferences[0].Kind)
if hasMatch {
if !matchLabel(workloadName, workloadsMatch) {
podCanAppend = false
}
}
if hasQuery {
if !queryLabel(strings.ToLower(workloadName), workloadsQuery) {
podCanAppend = false
}
}
if podCanAppend {
pods = append(pods, pod.Name)
}
}
}
} else {
for _, pod := range podList {
/*if len(pod.ObjectMeta.OwnerReferences) > 0 {
glog.Infof("List Pod %v:%v:%v", pod.Name, pod.ObjectMeta.OwnerReferences[0].Name, pod.ObjectMeta.OwnerReferences[0].Kind)
}*/
if len(pod.ObjectMeta.OwnerReferences) > 0 && in(pod.Namespace, namespaces) >= 0 {
var podCanAppend = true
workloadName := getWorkloadName(pod.ObjectMeta.OwnerReferences[0].Name, pod.ObjectMeta.OwnerReferences[0].Kind)
if hasMatch {
if !matchLabel(workloadName, workloadsMatch) {
podCanAppend = false
}
}
if hasQuery {
if !queryLabel(strings.ToLower(workloadName), workloadsQuery) {
podCanAppend = false
}
}
if podCanAppend {
pods = append(pods, pod.Name)
}
}
}
}
return true, pods
}
func MatchPod(podMatch string, podFilled bool, pods []string) (bool, []string) {
if podMatch == "" {
return podFilled, pods
}
podsMatch := strings.Split(strings.Replace(podMatch, ",", " ", -1), " ")
if podFilled {
return true, intersection(podsMatch, pods)
}
return true, podsMatch
}
func MatchContainer(containerMatch string) (bool, []string) {
if containerMatch == "" {
return false, nil
}
return true, strings.Split(strings.Replace(containerMatch, ",", " ", -1), " ")
}
func GetWorkspaceOfNamesapce(namespace string) string {
var workspace string
workspace = ""
nsLister := informers.SharedInformerFactory().Core().V1().Namespaces().Lister()
nsList, err := nsLister.List(labels.Everything())
if err != nil {
glog.Error("failed to list namespace, error: ", err)
return workspace
}
for _, ns := range nsList {
if ns.GetName() == namespace {
labels := ns.GetLabels()
_, ok := labels[constants.WorkspaceLabelKey]
if ok {
workspace = labels[constants.WorkspaceLabelKey]
}
}
}
return workspace
return namespaceWithCreationTime
}

View File

@@ -20,6 +20,7 @@ package metrics
import (
"github.com/golang/glog"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/informers"
"kubesphere.io/kubesphere/pkg/simple/client/kubesphere"
"net/url"
@@ -36,7 +37,7 @@ import (
"k8s.io/apimachinery/pkg/labels"
"kubesphere.io/kubesphere/pkg/models/workspaces"
client "kubesphere.io/kubesphere/pkg/simple/client/prometheus"
cs "kubesphere.io/kubesphere/pkg/simple/client"
)
var jsonIter = jsoniter.ConfigCompatibleWithStandardLibrary
@@ -136,10 +137,15 @@ func getAllWorkspaceNames(formatedMetric *FormatedMetric) map[string]int {
func getAllWorkspaces() map[string]int {
client, err := cs.ClientSets().Prometheus()
if err != nil {
return nil
}
paramValues := make(url.Values)
paramValues.Set("query", WorkspaceNamespaceLabelRule)
params := paramValues.Encode()
res := client.SendMonitoringRequest(client.PrometheusEndpoint, client.DefaultQueryType, params)
res := client.SendSecondaryMonitoringRequest(DefaultQueryType, params)
metric := ReformatJson(res, "", map[string]string{"workspace": "workspace"})
@@ -234,7 +240,13 @@ func unifyMetricHistoryTimeRange(fmtMetrics *FormatedMetric) {
}
}
func AssembleSpecificWorkloadMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string, bool) {
func AssembleSpecificWorkloadMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string, bool) {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return "", "", false
}
nsName := monitoringRequest.NsName
wlName := monitoringRequest.WorkloadName
@@ -244,7 +256,7 @@ func AssembleSpecificWorkloadMetricRequestInfo(monitoringRequest *client.Monitor
paramValues := monitoringRequest.Params
params := makeRequestParamString(rule, paramValues)
res := client.SendMonitoringRequest(client.PrometheusEndpoint, client.DefaultQueryType, params)
res := client.SendMonitoringRequest(DefaultQueryType, params)
podNamesFilter := getPodNameRegexInWorkload(res, podsFilter)
@@ -255,7 +267,7 @@ func AssembleSpecificWorkloadMetricRequestInfo(monitoringRequest *client.Monitor
return queryType, params, rule == ""
}
func AssembleAllWorkloadMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string) {
func AssembleAllWorkloadMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string) {
queryType := monitoringRequest.QueryType
paramValues := monitoringRequest.Params
@@ -266,7 +278,7 @@ func AssembleAllWorkloadMetricRequestInfo(monitoringRequest *client.MonitoringRe
return queryType, params
}
func AssemblePodMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string, bool) {
func AssemblePodMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string, bool) {
queryType := monitoringRequest.QueryType
paramValues := monitoringRequest.Params
@@ -276,7 +288,7 @@ func AssemblePodMetricRequestInfo(monitoringRequest *client.MonitoringRequestPar
return queryType, params, rule == ""
}
func AssemblePVCMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string, bool) {
func AssemblePVCMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string, bool) {
queryType := monitoringRequest.QueryType
paramValues := monitoringRequest.Params
@@ -318,14 +330,20 @@ func AddNodeAddressMetric(nodeMetric *FormatedMetric, nodeAddress *map[string][]
}
}
func MonitorContainer(monitoringRequest *client.MonitoringRequestParams, metricName string) *FormatedMetric {
func MonitorContainer(monitoringRequest *MonitoringRequestParams, metricName string) *FormatedMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return nil
}
queryType, params := AssembleContainerMetricRequestInfo(monitoringRequest, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params)
metricsStr := client.SendMonitoringRequest(queryType, params)
res := ReformatJson(metricsStr, metricName, map[string]string{MetricLevelContainerName: ""})
return res
}
func AssembleContainerMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string) {
func AssembleContainerMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string) {
queryType := monitoringRequest.QueryType
paramValues := monitoringRequest.Params
@@ -335,7 +353,7 @@ func AssembleContainerMetricRequestInfo(monitoringRequest *client.MonitoringRequ
return queryType, params
}
func AssembleNamespaceMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string) {
func AssembleNamespaceMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string) {
queryType := monitoringRequest.QueryType
paramValues := monitoringRequest.Params
@@ -345,7 +363,7 @@ func AssembleNamespaceMetricRequestInfo(monitoringRequest *client.MonitoringRequ
return queryType, params
}
func AssembleNamespaceMetricRequestInfoByNamesapce(monitoringRequest *client.MonitoringRequestParams, namespace string, metricName string) (string, string) {
func AssembleNamespaceMetricRequestInfoByNamesapce(monitoringRequest *MonitoringRequestParams, namespace string, metricName string) (string, string) {
queryType := monitoringRequest.QueryType
paramValues := monitoringRequest.Params
@@ -356,7 +374,7 @@ func AssembleNamespaceMetricRequestInfoByNamesapce(monitoringRequest *client.Mon
return queryType, params
}
func AssembleSpecificWorkspaceMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, namespaceList []string, workspace string, metricName string) (string, string) {
func AssembleSpecificWorkspaceMetricRequestInfo(monitoringRequest *MonitoringRequestParams, namespaceList []string, workspace string, metricName string) (string, string) {
nsFilter := "^(" + strings.Join(namespaceList, "|") + ")$"
@@ -368,7 +386,7 @@ func AssembleSpecificWorkspaceMetricRequestInfo(monitoringRequest *client.Monito
return queryType, params
}
func AssembleAllWorkspaceMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, namespaceList []string, metricName string) (string, string) {
func AssembleAllWorkspaceMetricRequestInfo(monitoringRequest *MonitoringRequestParams, namespaceList []string, metricName string) (string, string) {
var nsFilter = "^()$"
if namespaceList != nil {
@@ -418,7 +436,7 @@ func filterNamespace(nsFilter string, namespaceList []string) []string {
return newNSlist
}
func MonitorAllWorkspaces(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric {
func MonitorAllWorkspaces(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
metricsFilter := monitoringRequest.MetricsFilter
if strings.Trim(metricsFilter, " ") == "" {
metricsFilter = ".*"
@@ -479,7 +497,13 @@ func MonitorAllWorkspaces(monitoringRequest *client.MonitoringRequestParams) *Fo
}
}
func collectWorkspaceMetric(monitoringRequest *client.MonitoringRequestParams, ws string, filterMetricsName []string, wgAll *sync.WaitGroup, wsAllch chan *[]FormatedMetric) {
func collectWorkspaceMetric(monitoringRequest *MonitoringRequestParams, ws string, filterMetricsName []string, wgAll *sync.WaitGroup, wsAllch chan *[]FormatedMetric) {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return
}
defer wgAll.Done()
var wg sync.WaitGroup
var ch = make(chan *FormatedMetric, ChannelMaxCapacity)
@@ -494,7 +518,7 @@ func collectWorkspaceMetric(monitoringRequest *client.MonitoringRequestParams, w
go func(metricName string) {
queryType, params := AssembleSpecificWorkspaceMetricRequestInfo(monitoringRequest, namespaceArray, ws, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params)
metricsStr := client.SendMonitoringRequest(queryType, params)
ch <- ReformatJson(metricsStr, metricName, map[string]string{ResultItemMetricResourceName: ws})
wg.Done()
}(metricName)
@@ -521,7 +545,12 @@ func collectWorkspaceMetric(monitoringRequest *client.MonitoringRequestParams, w
wsAllch <- &metricsArray
}
func GetClusterLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric {
func GetClusterLevelMetrics(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
return nil
}
metricsFilter := monitoringRequest.MetricsFilter
if metricsFilter == "" {
metricsFilter = ".*"
@@ -536,7 +565,7 @@ func GetClusterLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *
wg.Add(1)
go func(metricName string) {
queryType, params := AssembleClusterMetricRequestInfo(monitoringRequest, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params)
metricsStr := client.SendMonitoringRequest(queryType, params)
ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelCluster: "local"})
wg.Done()
}(metricName)
@@ -560,7 +589,12 @@ func GetClusterLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *
}
}
func GetNodeLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric {
func GetNodeLevelMetrics(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
return nil
}
metricsFilter := monitoringRequest.MetricsFilter
if metricsFilter == "" {
metricsFilter = ".*"
@@ -575,7 +609,7 @@ func GetNodeLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *For
wg.Add(1)
go func(metricName string) {
queryType, params := AssembleNodeMetricRequestInfo(monitoringRequest, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params)
metricsStr := client.SendMonitoringRequest(queryType, params)
ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelNode: ""})
wg.Done()
}(metricName)
@@ -599,7 +633,13 @@ func GetNodeLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *For
}
}
func GetWorkspaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric {
func GetWorkspaceLevelMetrics(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return nil
}
metricsFilter := monitoringRequest.MetricsFilter
if metricsFilter == "" {
metricsFilter = ".*"
@@ -638,7 +678,7 @@ func GetWorkspaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
go func(metricName string, namespace string) {
queryType, params := AssembleNamespaceMetricRequestInfoByNamesapce(monitoringRequest, namespace, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params)
metricsStr := client.SendMonitoringRequest(queryType, params)
chForOneMetric <- ReformatJson(metricsStr, metricName, map[string]string{ResultItemMetricResourceName: namespace})
wgForOneMetric.Done()
}(metricName, ns)
@@ -682,7 +722,7 @@ func GetWorkspaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
wg.Add(1)
go func(metricName string, workspace string) {
queryType, params := AssembleSpecificWorkspaceMetricRequestInfo(monitoringRequest, namespaceArray, workspace, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params)
metricsStr := client.SendMonitoringRequest(queryType, params)
ch <- ReformatJson(metricsStr, metricName, map[string]string{ResultItemMetricResourceName: workspace})
wg.Done()
}(metricName, workspace)
@@ -699,7 +739,7 @@ func GetWorkspaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
go func(metricName string) {
queryType, params := AssembleAllWorkspaceMetricRequestInfo(monitoringRequest, nil, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params)
metricsStr := client.SendMonitoringRequest(queryType, params)
ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelWorkspace: "workspaces"})
wg.Done()
@@ -725,7 +765,13 @@ func GetWorkspaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
}
}
func GetNamespaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric {
func GetNamespaceLevelMetrics(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return nil
}
metricsFilter := monitoringRequest.MetricsFilter
if metricsFilter == "" {
metricsFilter = ".*"
@@ -741,7 +787,7 @@ func GetNamespaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
go func(metricName string) {
queryType, params := AssembleNamespaceMetricRequestInfo(monitoringRequest, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params)
metricsStr := client.SendMonitoringRequest(queryType, params)
rawResult := ReformatJson(metricsStr, metricName, map[string]string{MetricLevelNamespace: ""})
ch <- rawResult
@@ -768,7 +814,13 @@ func GetNamespaceLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
}
}
func GetWorkloadLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric {
func GetWorkloadLevelMetrics(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return nil
}
metricsFilter := monitoringRequest.MetricsFilter
if metricsFilter == "" {
metricsFilter = ".*"
@@ -784,7 +836,7 @@ func GetWorkloadLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
wg.Add(1)
go func(metricName string) {
queryType, params := AssembleAllWorkloadMetricRequestInfo(monitoringRequest, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params)
metricsStr := client.SendMonitoringRequest(queryType, params)
reformattedResult := ReformatJson(metricsStr, metricName, map[string]string{MetricLevelWorkload: ""})
// no need to append a null result
ch <- reformattedResult
@@ -801,7 +853,7 @@ func GetWorkloadLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
metricName = strings.TrimLeft(metricName, "workload_")
queryType, params, nullRule := AssembleSpecificWorkloadMetricRequestInfo(monitoringRequest, metricName)
if !nullRule {
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params)
metricsStr := client.SendMonitoringRequest(queryType, params)
fmtMetrics := ReformatJson(metricsStr, metricName, map[string]string{MetricLevelPodName: ""})
unifyMetricHistoryTimeRange(fmtMetrics)
ch <- fmtMetrics
@@ -829,7 +881,13 @@ func GetWorkloadLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
}
}
func GetPodLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric {
func GetPodLevelMetrics(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return nil
}
metricsFilter := monitoringRequest.MetricsFilter
if metricsFilter == "" {
metricsFilter = ".*"
@@ -845,7 +903,7 @@ func GetPodLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *Form
go func(metricName string) {
queryType, params, nullRule := AssemblePodMetricRequestInfo(monitoringRequest, metricName)
if !nullRule {
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params)
metricsStr := client.SendMonitoringRequest(queryType, params)
ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelPodName: ""})
} else {
ch <- nil
@@ -872,7 +930,13 @@ func GetPodLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *Form
}
}
func GetContainerLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric {
func GetContainerLevelMetrics(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return nil
}
metricsFilter := monitoringRequest.MetricsFilter
if metricsFilter == "" {
metricsFilter = ".*"
@@ -887,7 +951,7 @@ func GetContainerLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
wg.Add(1)
go func(metricName string) {
queryType, params := AssembleContainerMetricRequestInfo(monitoringRequest, metricName)
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params)
metricsStr := client.SendMonitoringRequest(queryType, params)
ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelContainerName: ""})
wg.Done()
}(metricName)
@@ -911,7 +975,13 @@ func GetContainerLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
}
}
func GetPVCLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric {
func GetPVCLevelMetrics(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return nil
}
metricsFilter := monitoringRequest.MetricsFilter
if metricsFilter == "" {
metricsFilter = ".*"
@@ -927,7 +997,7 @@ func GetPVCLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *Form
go func(metricName string) {
queryType, params, nullRule := AssemblePVCMetricRequestInfo(monitoringRequest, metricName)
if !nullRule {
metricsStr := client.SendMonitoringRequest(client.PrometheusEndpoint, queryType, params)
metricsStr := client.SendMonitoringRequest(queryType, params)
ch <- ReformatJson(metricsStr, metricName, map[string]string{MetricLevelPVC: ""})
} else {
ch <- nil
@@ -954,7 +1024,13 @@ func GetPVCLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *Form
}
}
func GetComponentLevelMetrics(monitoringRequest *client.MonitoringRequestParams) *FormatedLevelMetric {
func GetComponentLevelMetrics(monitoringRequest *MonitoringRequestParams) *FormatedLevelMetric {
client, err := cs.ClientSets().Prometheus()
if err != nil {
klog.Error(err)
return nil
}
metricsFilter := monitoringRequest.MetricsFilter
if metricsFilter == "" {
metricsFilter = ".*"
@@ -969,7 +1045,7 @@ func GetComponentLevelMetrics(monitoringRequest *client.MonitoringRequestParams)
wg.Add(1)
go func(metricName string) {
queryType, params := AssembleComponentRequestInfo(monitoringRequest, metricName)
metricsStr := client.SendMonitoringRequest(client.SecondaryPrometheusEndpoint, queryType, params)
metricsStr := client.SendMonitoringRequest(queryType, params)
formattedJson := ReformatJson(metricsStr, metricName, map[string]string{ResultItemMetricResourceName: monitoringRequest.ComponentName})
if metricName == EtcdServerList {
@@ -1175,7 +1251,7 @@ func getSpecificMetricItem(timestamp int64, metricName string, resource string,
return &nsMetrics
}
func AssembleClusterMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string) {
func AssembleClusterMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string) {
queryType := monitoringRequest.QueryType
paramValues := monitoringRequest.Params
rule := MakeClusterRule(metricName)
@@ -1184,7 +1260,7 @@ func AssembleClusterMetricRequestInfo(monitoringRequest *client.MonitoringReques
return queryType, params
}
func AssembleNodeMetricRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string) {
func AssembleNodeMetricRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string) {
queryType := monitoringRequest.QueryType
paramValues := monitoringRequest.Params
rule := MakeNodeRule(monitoringRequest.NodeId, monitoringRequest.ResourcesFilter, metricName)
@@ -1193,7 +1269,7 @@ func AssembleNodeMetricRequestInfo(monitoringRequest *client.MonitoringRequestPa
return queryType, params
}
func AssembleComponentRequestInfo(monitoringRequest *client.MonitoringRequestParams, metricName string) (string, string) {
func AssembleComponentRequestInfo(monitoringRequest *MonitoringRequestParams, metricName string) (string, string) {
queryType := monitoringRequest.QueryType
paramValues := monitoringRequest.Params
rule := MakeComponentRule(metricName)

View File

@@ -335,9 +335,11 @@ var PVCMetricsNames = []string{
"pvc_inodes_available",
"pvc_inodes_used",
"pvc_inodes_total",
"pvc_inodes_utilisation",
"pvc_bytes_available",
"pvc_bytes_used",
"pvc_bytes_total",
"pvc_bytes_utilisation",
}
var ComponentMetricsNames = []string{
@@ -695,24 +697,30 @@ var RulePromQLTmplMap = MetricMap{
"workspace_pod_abnormal_ratio": `count((kube_pod_info{node!="", namespace$1} unless on (pod, namespace) (kube_pod_status_phase{job="kube-state-metrics", phase="Succeeded"}>0) unless on (pod, namespace) ((kube_pod_status_ready{job="kube-state-metrics", condition="true"}>0) and on (pod, namespace) (kube_pod_status_phase{job="kube-state-metrics", phase="Running"}>0)) unless on (pod, namespace) (kube_pod_container_status_waiting_reason{job="kube-state-metrics", reason="ContainerCreating"}>0)) / sum(kube_pod_status_phase{phase!~"Succeeded", namespace!="", namespace$1}) * on (namespace) group_left(label_kubesphere_io_workspace)(kube_namespace_labels{label_kubesphere_io_workspace$2}))`,
// PVC
"pvc_inodes_available": `max (kubelet_volume_stats_inodes_free{namespace="$1",persistentvolumeclaim="$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_inodes_used": `max (kubelet_volume_stats_inodes_used{namespace="$1", persistentvolumeclaim="$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_inodes_total": `max (kubelet_volume_stats_inodes{namespace="$1", persistentvolumeclaim="$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_bytes_available": `max (kubelet_volume_stats_available_bytes{namespace="$1", persistentvolumeclaim="$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_bytes_used": `max (kubelet_volume_stats_used_bytes{namespace="$1", persistentvolumeclaim="$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_bytes_total": `max (kubelet_volume_stats_capacity_bytes{namespace="$1", persistentvolumeclaim="$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_inodes_available_ns": `max (kubelet_volume_stats_inodes_free{namespace="$1",persistentvolumeclaim=~"$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_inodes_used_ns": `max (kubelet_volume_stats_inodes_used{namespace="$1",persistentvolumeclaim=~"$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_inodes_total_ns": `max (kubelet_volume_stats_inodes{namespace="$1",persistentvolumeclaim=~"$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_bytes_available_ns": `max (kubelet_volume_stats_available_bytes{namespace="$1",persistentvolumeclaim=~"$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_bytes_used_ns": `max (kubelet_volume_stats_used_bytes{namespace="$1",persistentvolumeclaim=~"$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_bytes_total_ns": `max (kubelet_volume_stats_capacity_bytes{namespace="$1",persistentvolumeclaim=~"$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_inodes_available_sc": `max (kubelet_volume_stats_inodes_free)by(namespace,persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info{storageclass="$1"}`,
"pvc_inodes_used_sc": `max (kubelet_volume_stats_inodes_used)by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info{storageclass="$1"}`,
"pvc_inodes_total_sc": `max (kubelet_volume_stats_inodes)by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info{storageclass="$1"}`,
"pvc_bytes_available_sc": `max (kubelet_volume_stats_available_bytes)by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info{storageclass="$1"}`,
"pvc_bytes_used_sc": `max (kubelet_volume_stats_used_bytes)by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info{storageclass="$1"}`,
"pvc_bytes_total_sc": `max (kubelet_volume_stats_capacity_bytes)by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info{storageclass="$1"}`,
"pvc_inodes_available": `max (kubelet_volume_stats_inodes_free{namespace="$1",persistentvolumeclaim="$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_inodes_used": `max (kubelet_volume_stats_inodes_used{namespace="$1", persistentvolumeclaim="$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_inodes_total": `max (kubelet_volume_stats_inodes{namespace="$1", persistentvolumeclaim="$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_inodes_utilisation": `max (kubelet_volume_stats_inodes_used{namespace="$1", persistentvolumeclaim="$2"}/kubelet_volume_stats_inodes{namespace="$1", persistentvolumeclaim="$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_bytes_available": `max (kubelet_volume_stats_available_bytes{namespace="$1", persistentvolumeclaim="$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_bytes_used": `max (kubelet_volume_stats_used_bytes{namespace="$1", persistentvolumeclaim="$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_bytes_total": `max (kubelet_volume_stats_capacity_bytes{namespace="$1", persistentvolumeclaim="$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_bytes_utilisation": `max (kubelet_volume_stats_used_bytes{namespace="$1", persistentvolumeclaim="$2"}/kubelet_volume_stats_capacity_bytes{namespace="$1", persistentvolumeclaim="$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_inodes_available_ns": `max (kubelet_volume_stats_inodes_free{namespace="$1",persistentvolumeclaim=~"$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_inodes_used_ns": `max (kubelet_volume_stats_inodes_used{namespace="$1",persistentvolumeclaim=~"$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_inodes_total_ns": `max (kubelet_volume_stats_inodes{namespace="$1",persistentvolumeclaim=~"$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_inodes_utilisation_ns": `max (kubelet_volume_stats_inodes_used{namespace="$1", persistentvolumeclaim=~"$2"}/kubelet_volume_stats_inodes{namespace="$1", persistentvolumeclaim=~"$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_bytes_available_ns": `max (kubelet_volume_stats_available_bytes{namespace="$1",persistentvolumeclaim=~"$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_bytes_used_ns": `max (kubelet_volume_stats_used_bytes{namespace="$1",persistentvolumeclaim=~"$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_bytes_total_ns": `max (kubelet_volume_stats_capacity_bytes{namespace="$1",persistentvolumeclaim=~"$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_bytes_utilisation_ns": `max (kubelet_volume_stats_used_bytes{namespace="$1", persistentvolumeclaim=~"$2"}/kubelet_volume_stats_capacity_bytes{namespace="$1", persistentvolumeclaim=~"$2"})by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info`,
"pvc_inodes_available_sc": `max (kubelet_volume_stats_inodes_free)by(namespace,persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info{storageclass="$1"}`,
"pvc_inodes_used_sc": `max (kubelet_volume_stats_inodes_used)by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info{storageclass="$1"}`,
"pvc_inodes_total_sc": `max (kubelet_volume_stats_inodes)by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info{storageclass="$1"}`,
"pvc_inodes_utilisation_sc": `max (kubelet_volume_stats_inodes_used/kubelet_volume_stats_inodes)by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info{storageclass="$1"}`,
"pvc_bytes_available_sc": `max (kubelet_volume_stats_available_bytes)by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info{storageclass="$1"}`,
"pvc_bytes_used_sc": `max (kubelet_volume_stats_used_bytes)by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info{storageclass="$1"}`,
"pvc_bytes_total_sc": `max (kubelet_volume_stats_capacity_bytes)by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info{storageclass="$1"}`,
"pvc_bytes_utilisation_sc": `max (kubelet_volume_stats_used_bytes/kubelet_volume_stats_capacity_bytes)by(namespace, persistentvolumeclaim)*on(namespace, persistentvolumeclaim)group_left(storageclass)kube_persistentvolumeclaim_info{storageclass="$1"}`,
// component
"etcd_server_list": `label_replace(up{job="etcd"}, "node_ip", "$1", "instance", "(.*):.*")`,

View File

@@ -22,8 +22,6 @@ import (
"strings"
"k8s.io/api/core/v1"
prom "kubesphere.io/kubesphere/pkg/simple/client/prometheus"
)
func GetNamespacesWithMetrics(namespaces []*v1.Namespace) []*v1.Namespace {
@@ -34,10 +32,10 @@ func GetNamespacesWithMetrics(namespaces []*v1.Namespace) []*v1.Namespace {
nsFilter := "^(" + strings.Join(nsNameList, "|") + ")$"
var timeRelateParams = make(url.Values)
params := prom.MonitoringRequestParams{
params := MonitoringRequestParams{
ResourcesFilter: nsFilter,
Params: timeRelateParams,
QueryType: prom.DefaultQueryType,
QueryType: DefaultQueryType,
MetricsFilter: "namespace_cpu_usage|namespace_memory_usage_wo_cache|namespace_pod_count",
}

View File

@@ -0,0 +1,33 @@
package metrics
import "net/url"
const (
DefaultQueryStep = "10m"
DefaultQueryTimeout = "10s"
RangeQueryType = "query_range?"
DefaultQueryType = "query?"
)
type MonitoringRequestParams struct {
Params url.Values
QueryType string
SortMetricName string
SortType string
PageNum string
LimitNum string
Tp string
MetricsFilter string
ResourcesFilter string
MetricsName string
WorkloadName string
NodeId string
WsName string
NsName string
PodName string
PVCName string
StorageClassName string
ContainerName string
WorkloadKind string
ComponentName string
}

View File

@@ -19,7 +19,7 @@ package nodes
import (
"fmt"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client"
"math"
"strings"
"time"
@@ -36,7 +36,7 @@ import (
func DrainNode(nodename string) (err error) {
k8sclient := k8s.Client()
k8sclient := client.ClientSets().K8s().Kubernetes()
node, err := k8sclient.CoreV1().Nodes().Get(nodename, metav1.GetOptions{})
if err != nil {
return err
@@ -68,7 +68,7 @@ func DrainNode(nodename string) (err error) {
func drainEviction(nodename string, donech chan bool, errch chan error) {
k8sclient := k8s.Client()
k8sclient := client.ClientSets().K8s().Kubernetes()
var options metav1.ListOptions
pods := make([]v1.Pod, 0)
options.FieldSelector = "spec.nodeName=" + nodename
@@ -107,7 +107,6 @@ func drainEviction(nodename string, donech chan bool, errch chan error) {
//create eviction
getPodFn := func(namespace, name string) (*v1.Pod, error) {
k8sclient := k8s.Client()
return k8sclient.CoreV1().Pods(namespace).Get(name, metav1.GetOptions{})
}
evicerr := evictPods(pods, 0, getPodFn)
@@ -118,9 +117,7 @@ func drainEviction(nodename string, donech chan bool, errch chan error) {
glog.Fatal(evicerr)
errch <- err
}
}
}
func getPodSource(pod *v1.Pod) (string, error) {
@@ -159,7 +156,7 @@ func containDaemonset(pod v1.Pod, daemonsetList appsv1.DaemonSetList) bool {
func evictPod(pod v1.Pod, GracePeriodSeconds int) error {
k8sclient := k8s.Client()
k8sclient := client.ClientSets().K8s().Kubernetes()
deleteOptions := &metav1.DeleteOptions{}
if GracePeriodSeconds >= 0 {
gracePeriodSeconds := int64(GracePeriodSeconds)

View File

@@ -24,7 +24,7 @@ import (
"io/ioutil"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/runtime"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client"
"sort"
"k8s.io/apimachinery/pkg/labels"
@@ -253,7 +253,7 @@ func createRouterService(namespace string, routerType corev1.ServiceType, annota
return nil, fmt.Errorf("service template not loaded")
}
k8sClient := k8s.Client()
k8sClient := client.ClientSets().K8s().Kubernetes()
service := obj.(*corev1.Service)
@@ -277,7 +277,7 @@ func createRouterService(namespace string, routerType corev1.ServiceType, annota
func updateRouterService(namespace string, routerType corev1.ServiceType, annotations map[string]string) (*corev1.Service, error) {
k8sClient := k8s.Client()
k8sClient := client.ClientSets().K8s().Kubernetes()
service, err := getRouterService(namespace)
if err != nil {
@@ -309,7 +309,7 @@ func deleteRouterService(namespace string) (*corev1.Service, error) {
return service, err
}
k8sClient := k8s.Client()
k8sClient := client.ClientSets().K8s().Kubernetes()
// delete controller service
serviceName := constants.IngressControllerPrefix + namespace
@@ -333,7 +333,7 @@ func createOrUpdateRouterWorkload(namespace string, publishService bool, service
deployName := constants.IngressControllerPrefix + namespace
k8sClient := k8s.Client()
k8sClient := client.ClientSets().K8s().Kubernetes()
deployment, err := k8sClient.ExtensionsV1beta1().Deployments(constants.IngressControllerNamespace).Get(deployName, meta_v1.GetOptions{})
createDeployment := true
@@ -403,7 +403,7 @@ func createOrUpdateRouterWorkload(namespace string, publishService bool, service
}
func deleteRouterWorkload(namespace string) error {
k8sClient := k8s.Client()
k8sClient := client.ClientSets().K8s().Kubernetes()
deleteOptions := meta_v1.DeleteOptions{}
// delete controller deployment

View File

@@ -21,7 +21,6 @@ import (
"fmt"
"github.com/emicklei/go-restful"
"github.com/gocraft/dbr"
"github.com/golang/glog"
"k8s.io/klog"
"kubesphere.io/kubesphere/pkg/db"
"kubesphere.io/kubesphere/pkg/gojenkins"
@@ -29,8 +28,7 @@ import (
"kubesphere.io/kubesphere/pkg/models"
"kubesphere.io/kubesphere/pkg/models/devops"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/simple/client/admin_jenkins"
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql"
cs "kubesphere.io/kubesphere/pkg/simple/client"
"net/http"
"sync"
)
@@ -42,7 +40,11 @@ type DevOpsProjectRoleResponse struct {
func ListDevopsProjects(workspace, username string, conditions *params.Conditions, orderBy string, reverse bool, limit int, offset int) (*models.PageableResponse, error) {
dbconn := devops_mysql.OpenDatabase()
dbconn, err := cs.ClientSets().MySQL()
if err != nil {
klog.Error(err)
return nil, err
}
query := dbconn.Select(devops.GetColumnsFromStructWithPrefix(devops.DevOpsProjectTableName, devops.DevOpsProject{})...).
From(devops.DevOpsProjectTableName)
@@ -87,14 +89,14 @@ 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 {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
}
count, err := query.Count()
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
}
@@ -107,7 +109,11 @@ func ListDevopsProjects(workspace, username string, conditions *params.Condition
}
func GetDevOpsProjectsCount(username string) (uint32, error) {
dbconn := devops_mysql.OpenDatabase()
dbconn, err := cs.ClientSets().MySQL()
if err != nil {
klog.Error(err)
return 0, err
}
query := dbconn.Select(devops.GetColumnsFromStructWithPrefix(devops.DevOpsProjectTableName, devops.DevOpsProject{})...).
From(devops.DevOpsProjectTableName)
@@ -137,20 +143,27 @@ func GetDevOpsProjectsCount(username string) (uint32, error) {
func DeleteDevOpsProject(projectId, username string) error {
err := devops.CheckProjectUserInRole(username, projectId, []string{devops.ProjectOwner})
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return restful.NewError(http.StatusForbidden, err.Error())
}
gojenkins := admin_jenkins.Client()
if gojenkins == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
dp, err := cs.ClientSets().Devops()
if err != nil {
klog.Error(err)
return restful.NewError(http.StatusServiceUnavailable, err.Error())
}
devopsdb := devops_mysql.OpenDatabase()
_, err = gojenkins.DeleteJob(projectId)
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 {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
@@ -159,22 +172,22 @@ func DeleteDevOpsProject(projectId, username string) error {
roleNames = append(roleNames, devops.GetProjectRoleName(projectId, role))
roleNames = append(roleNames, devops.GetPipelineRoleName(projectId, role))
}
err = gojenkins.DeleteProjectRoles(roleNames...)
err = jenkins.DeleteProjectRoles(roleNames...)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
_, err = devopsdb.DeleteFrom(devops.DevOpsProjectMembershipTableName).
Where(db.Eq(devops.DevOpsProjectMembershipProjectIdColumn, projectId)).Exec()
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
_, err = devopsdb.Update(devops.DevOpsProjectTableName).
Set(devops.StatusColumn, devops.StatusDeleted).
Where(db.Eq(devops.DevOpsProjectIdColumn, projectId)).Exec()
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
project := &devops.DevOpsProject{}
@@ -183,7 +196,7 @@ func DeleteDevOpsProject(projectId, username string) error {
Where(db.Eq(devops.DevOpsProjectIdColumn, projectId)).
LoadOne(project)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
return nil
@@ -191,17 +204,24 @@ func DeleteDevOpsProject(projectId, username string) error {
func CreateDevopsProject(username string, workspace string, req *devops.DevOpsProject) (*devops.DevOpsProject, error) {
jenkinsClient := admin_jenkins.Client()
if jenkinsClient == nil {
err := fmt.Errorf("could not connect to jenkins")
glog.Error(err)
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())
}
devopsdb := devops_mysql.OpenDatabase()
project := devops.NewDevOpsProject(req.Name, req.Description, username, req.Extra, workspace)
_, err := jenkinsClient.CreateFolder(project.ProjectId, project.Description)
_, err = jenkinsClient.CreateFolder(project.ProjectId, project.Description)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
@@ -229,14 +249,14 @@ func CreateDevopsProject(username string, workspace string, req *devops.DevOpsPr
close(addRoleCh)
for addRoleResponse := range addRoleCh {
if addRoleResponse.Err != nil {
glog.Errorf("%+v", addRoleResponse.Err)
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 {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
if globalRole == nil {
@@ -244,41 +264,41 @@ func CreateDevopsProject(username string, workspace string, req *devops.DevOpsPr
GlobalRead: true,
}, true)
if err != nil {
glog.Error("failed to create jenkins global role")
klog.Error("failed to create jenkins global role")
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
}
err = globalRole.AssignRole(username)
if err != nil {
glog.Errorf("%+v", err)
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 {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
err = projectRole.AssignRole(username)
if err != nil {
glog.Errorf("%+v", err)
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 {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
err = pipelineRole.AssignRole(username)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(utils.GetJenkinsStatusCode(err), err.Error())
}
_, err = devopsdb.InsertInto(devops.DevOpsProjectTableName).
Columns(devops.DevOpsProjectColumns...).Record(project).Exec()
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
}
@@ -286,7 +306,7 @@ func CreateDevopsProject(username string, workspace string, req *devops.DevOpsPr
_, err = devopsdb.InsertInto(devops.DevOpsProjectMembershipTableName).
Columns(devops.DevOpsProjectMembershipColumns...).Record(projectMembership).Exec()
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusInternalServerError, err.Error())
}
return project, nil
@@ -295,7 +315,7 @@ func CreateDevopsProject(username string, workspace string, req *devops.DevOpsPr
func GetUserDevopsSimpleRules(username, projectId string) ([]models.SimpleRule, error) {
role, err := devops.GetProjectUserRole(username, projectId)
if err != nil {
glog.Errorf("%+v", err)
klog.Errorf("%+v", err)
return nil, restful.NewError(http.StatusForbidden, err.Error())
}
return GetDevopsRoleSimpleRules(role), nil

View File

@@ -25,7 +25,7 @@ import (
"kubesphere.io/kubesphere/pkg/models"
ws "kubesphere.io/kubesphere/pkg/models/workspaces"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client"
"strconv"
)
@@ -44,7 +44,7 @@ func CreateNamespace(workspaceName string, namespace *v1.Namespace, username str
namespace.Labels[constants.WorkspaceLabelKey] = workspaceName
return k8s.Client().CoreV1().Namespaces().Create(namespace)
return client.ClientSets().K8s().Kubernetes().CoreV1().Namespaces().Create(namespace)
}
func DescribeWorkspace(username, workspaceName string) (*v1alpha1.Workspace, error) {

View File

@@ -29,7 +29,7 @@ import (
"k8s.io/api/core/v1"
"k8s.io/client-go/kubernetes/scheme"
"k8s.io/client-go/tools/remotecommand"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client"
)
// PtyHandler is what remotecommand expects from a pty
@@ -179,11 +179,9 @@ func HandleTerminalSession(session sockjs.Session) {
// Executed cmd in the container specified in request and connects it up with the ptyHandler (a session)
func startProcess(namespace, podName, containerName string, cmd []string, ptyHandler PtyHandler) error {
k8sClient := k8s.Client()
cfg, err := k8s.Config()
if err != nil {
return err
}
k8sClient := client.ClientSets().K8s().Kubernetes()
cfg := client.ClientSets().K8s().Config()
req := k8sClient.CoreV1().RESTClient().Post().
Resource("pods").
@@ -290,10 +288,6 @@ func NewSession(shell, namespace, podName, containerName string) (string, error)
sizeChan: make(chan remotecommand.TerminalSize),
}
if err != nil {
return "", err
}
go WaitingForConnection(shell, namespace, podName, containerName, sessionId)
return sessionId, nil

View File

@@ -19,7 +19,7 @@ package workloads
import (
"fmt"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
"kubesphere.io/kubesphere/pkg/simple/client"
"strings"
"time"
@@ -31,7 +31,7 @@ import (
const retryTimes = 3
func JobReRun(namespace, jobName string) error {
k8sClient := k8s.Client()
k8sClient := client.ClientSets().K8s().Kubernetes()
job, err := k8sClient.BatchV1().Jobs(namespace).Get(jobName, metav1.GetOptions{})
if err != nil {
return err
@@ -71,7 +71,7 @@ func JobReRun(namespace, jobName string) error {
}
func deleteJob(namespace, job string) error {
k8sClient := k8s.Client()
k8sClient := client.ClientSets().K8s().Kubernetes()
deletePolicy := metav1.DeletePropagationBackground
err := k8sClient.BatchV1().Jobs(namespace).Delete(job, &metav1.DeleteOptions{PropagationPolicy: &deletePolicy})
return err

View File

@@ -30,8 +30,7 @@ import (
"kubesphere.io/kubesphere/pkg/models/iam"
"kubesphere.io/kubesphere/pkg/models/resources"
"kubesphere.io/kubesphere/pkg/params"
"kubesphere.io/kubesphere/pkg/simple/client/devops_mysql"
"kubesphere.io/kubesphere/pkg/simple/client/k8s"
clientset "kubesphere.io/kubesphere/pkg/simple/client"
"kubesphere.io/kubesphere/pkg/utils/k8sutil"
"kubesphere.io/kubesphere/pkg/utils/sliceutil"
"strings"
@@ -41,7 +40,7 @@ import (
"errors"
"k8s.io/api/rbac/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
meta_v1 "k8s.io/apimachinery/pkg/apis/meta/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/labels"
)
@@ -67,13 +66,13 @@ func Namespaces(workspaceName string) ([]*core.Namespace, error) {
}
func DeleteNamespace(workspace string, namespaceName string) error {
namespace, err := k8s.Client().CoreV1().Namespaces().Get(namespaceName, meta_v1.GetOptions{})
namespace, err := clientset.ClientSets().K8s().Kubernetes().CoreV1().Namespaces().Get(namespaceName, metav1.GetOptions{})
if err != nil {
return err
}
if namespace.Labels[constants.WorkspaceLabelKey] == workspace {
deletePolicy := meta_v1.DeletePropagationForeground
return k8s.Client().CoreV1().Namespaces().Delete(namespaceName, &meta_v1.DeleteOptions{PropagationPolicy: &deletePolicy})
deletePolicy := metav1.DeletePropagationForeground
return clientset.ClientSets().K8s().Kubernetes().CoreV1().Namespaces().Delete(namespaceName, &metav1.DeleteOptions{PropagationPolicy: &deletePolicy})
} else {
return errors.New("resource not found")
}
@@ -134,7 +133,7 @@ func CreateWorkspaceRoleBinding(workspace, username string, role string) error {
if !k8sutil.ContainsUser(workspaceRoleBinding.Subjects, username) {
workspaceRoleBinding = workspaceRoleBinding.DeepCopy()
workspaceRoleBinding.Subjects = append(workspaceRoleBinding.Subjects, v1.Subject{APIGroup: "rbac.authorization.k8s.io", Kind: "User", Name: username})
_, err = k8s.Client().RbacV1().ClusterRoleBindings().Update(workspaceRoleBinding)
_, err = clientset.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Update(workspaceRoleBinding)
if err != nil {
log.Errorf("update workspace role binding failed: %+v", err)
return err
@@ -165,14 +164,17 @@ func DeleteWorkspaceRoleBinding(workspace, username string, role string) error {
}
}
workspaceRoleBinding, err = k8s.Client().RbacV1().ClusterRoleBindings().Update(workspaceRoleBinding)
workspaceRoleBinding, err = clientset.ClientSets().K8s().Kubernetes().RbacV1().ClusterRoleBindings().Update(workspaceRoleBinding)
return err
}
func GetDevOpsProjects(workspaceName string) ([]string, error) {
dbconn := devops_mysql.OpenDatabase()
dbconn, err := clientset.ClientSets().MySQL()
if err != nil {
return nil, err
}
query := dbconn.Select(devops.DevOpsProjectIdColumn).
From(devops.DevOpsProjectTableName).
@@ -236,7 +238,10 @@ func GetAllProjectNums() (int, error) {
}
func GetAllDevOpsProjectsNums() (int, error) {
dbconn := devops_mysql.OpenDatabase()
dbconn, err := clientset.ClientSets().MySQL()
if err != nil {
return 0, err
}
query := dbconn.Select(devops.DevOpsProjectIdColumn).
From(devops.DevOpsProjectTableName).