Merge branch 'master' into monitoring-fix
This commit is contained in:
@@ -148,6 +148,11 @@ func getWorkLoads(namespace string, clusterRoles []openpitrix.ClusterRole) (*wor
|
||||
item, err := informers.SharedInformerFactory().Apps().V1().Deployments().Lister().Deployments(namespace).Get(name)
|
||||
|
||||
if err != nil {
|
||||
// app not ready
|
||||
if errors.IsNotFound(err) {
|
||||
continue
|
||||
}
|
||||
glog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -159,6 +164,11 @@ func getWorkLoads(namespace string, clusterRoles []openpitrix.ClusterRole) (*wor
|
||||
name := strings.Split(workLoadName, openpitrix.DaemonSuffix)[0]
|
||||
item, err := informers.SharedInformerFactory().Apps().V1().DaemonSets().Lister().DaemonSets(namespace).Get(name)
|
||||
if err != nil {
|
||||
// app not ready
|
||||
if errors.IsNotFound(err) {
|
||||
continue
|
||||
}
|
||||
glog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
works.Daemonsets = append(works.Daemonsets, *item)
|
||||
@@ -169,6 +179,11 @@ func getWorkLoads(namespace string, clusterRoles []openpitrix.ClusterRole) (*wor
|
||||
name := strings.Split(workLoadName, openpitrix.StateSuffix)[0]
|
||||
item, err := informers.SharedInformerFactory().Apps().V1().StatefulSets().Lister().StatefulSets(namespace).Get(name)
|
||||
if err != nil {
|
||||
// app not ready
|
||||
if errors.IsNotFound(err) {
|
||||
continue
|
||||
}
|
||||
glog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
works.Statefulsets = append(works.Statefulsets, *item)
|
||||
|
||||
@@ -1025,9 +1025,9 @@ type ReqJson struct {
|
||||
|
||||
// ToJenkinsfile response
|
||||
type ResJenkinsfile struct {
|
||||
Status string `json:"status,omitempty" description:"status"`
|
||||
Status string `json:"status,omitempty" description:"status e.g. ok"`
|
||||
Data struct {
|
||||
Result string `json:"result,omitempty" description:"result"`
|
||||
Result string `json:"result,omitempty" description:"result e.g. success"`
|
||||
Jenkinsfile string `json:"jenkinsfile,omitempty" description:"jenkinsfile"`
|
||||
Errors []struct {
|
||||
Location []string `json:"location,omitempty" description:"err location"`
|
||||
@@ -1041,9 +1041,9 @@ type ReqJenkinsfile struct {
|
||||
}
|
||||
|
||||
type ResJson struct {
|
||||
Status string `json:"status,omitempty" description:"status"`
|
||||
Status string `json:"status,omitempty" description:"status e.g. ok"`
|
||||
Data struct {
|
||||
Result string `json:"result,omitempty" description:"result"`
|
||||
Result string `json:"result,omitempty" description:"result e.g. success"`
|
||||
JSON struct {
|
||||
Pipeline struct {
|
||||
Stages []interface{} `json:"stages,omitempty" description:"stages"`
|
||||
|
||||
@@ -24,7 +24,7 @@ type DevOpsProjectMembership struct {
|
||||
Username string `json:"username" description:"member's username,username can uniquely identify a user"`
|
||||
ProjectId string `json:"project_id" db:"project_id" description:"the devops projects which project membership belongs to"`
|
||||
Role string `json:"role" description:"devops project membership's role type. e.g. owner '"`
|
||||
Status string `json:"status" description:"Desperated, status of project membership"`
|
||||
Status string `json:"status" description:"Desperated, status of project membership. e.g. active "`
|
||||
GrantBy string `json:"grand_by,omitempty" description:"Username of the user who assigned the role"`
|
||||
}
|
||||
|
||||
|
||||
@@ -52,7 +52,7 @@ func UpdateProject(project *DevOpsProject) (*DevOpsProject, error) {
|
||||
query.Set(DevOpsProjectExtraColumn, project.Extra)
|
||||
}
|
||||
if !govalidator.IsNull(project.Name) {
|
||||
query.Set(DevOpsProjectNameColumn, project.Extra)
|
||||
query.Set(DevOpsProjectNameColumn, project.Name)
|
||||
}
|
||||
if len(query.UpdateStmt.Value) > 0 {
|
||||
_, err := query.
|
||||
|
||||
@@ -56,10 +56,12 @@ import (
|
||||
)
|
||||
|
||||
var (
|
||||
adminEmail string
|
||||
adminPassword string
|
||||
tokenExpireTime time.Duration
|
||||
initUsers []initUser
|
||||
adminEmail string
|
||||
adminPassword string
|
||||
tokenExpireTime time.Duration
|
||||
maxAuthFailed int
|
||||
authTimeInterval time.Duration
|
||||
initUsers []initUser
|
||||
)
|
||||
|
||||
type initUser struct {
|
||||
@@ -68,14 +70,17 @@ type initUser struct {
|
||||
}
|
||||
|
||||
const (
|
||||
userInitFile = "/etc/ks-iam/users.json"
|
||||
userInitFile = "/etc/ks-iam/users.json"
|
||||
authRateLimitRegex = `(\d+)/(\d+[s|m|h])`
|
||||
defaultMaxAuthFailed = 5
|
||||
defaultAuthTimeInterval = 30 * time.Minute
|
||||
)
|
||||
|
||||
func Init(email, password string, t time.Duration) error {
|
||||
func Init(email, password string, expireTime time.Duration, authRateLimit string) error {
|
||||
adminEmail = email
|
||||
adminPassword = password
|
||||
tokenExpireTime = t
|
||||
|
||||
tokenExpireTime = expireTime
|
||||
maxAuthFailed, authTimeInterval = parseAuthRateLimit(authRateLimit)
|
||||
conn, err := ldapclient.Client()
|
||||
|
||||
if err != nil {
|
||||
@@ -101,6 +106,23 @@ func Init(email, password string, t time.Duration) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func parseAuthRateLimit(authRateLimit string) (int, time.Duration) {
|
||||
regex := regexp.MustCompile(authRateLimitRegex)
|
||||
groups := regex.FindStringSubmatch(authRateLimit)
|
||||
|
||||
maxCount := defaultMaxAuthFailed
|
||||
timeInterval := defaultAuthTimeInterval
|
||||
|
||||
if len(groups) == 3 {
|
||||
maxCount, _ = strconv.Atoi(groups[1])
|
||||
timeInterval, _ = time.ParseDuration(groups[2])
|
||||
} else {
|
||||
glog.Warning("invalid auth rate limit", authRateLimit)
|
||||
}
|
||||
|
||||
return maxCount, timeInterval
|
||||
}
|
||||
|
||||
func checkAndCreateDefaultGroup(conn ldap.Client) error {
|
||||
|
||||
groupSearchRequest := ldap.NewSearchRequest(
|
||||
@@ -203,9 +225,23 @@ func createGroupsBaseDN(conn ldap.Client) error {
|
||||
// User login
|
||||
func Login(username string, password string, ip string) (*models.Token, error) {
|
||||
|
||||
redisClient := redis.Client()
|
||||
|
||||
records, err := redisClient.Keys(fmt.Sprintf("kubesphere:authfailed:%s:*", username)).Result()
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if len(records) >= maxAuthFailed {
|
||||
return nil, restful.NewError(http.StatusTooManyRequests, "auth rate limit exceeded")
|
||||
}
|
||||
|
||||
conn, err := ldapclient.Client()
|
||||
|
||||
if err != nil {
|
||||
glog.Error(err)
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -237,7 +273,13 @@ func Login(username string, password string, ip string) (*models.Token, error) {
|
||||
err = conn.Bind(dn, password)
|
||||
|
||||
if err != nil {
|
||||
glog.Errorln("auth error", username, err)
|
||||
glog.Infoln("auth failed", username, err)
|
||||
|
||||
if ldap.IsErrorWithCode(err, ldap.LDAPResultInvalidCredentials) {
|
||||
loginFailedRecord := fmt.Sprintf("kubesphere:authfailed:%s:%d", username, time.Now().UnixNano())
|
||||
redisClient.Set(loginFailedRecord, "", authTimeInterval)
|
||||
}
|
||||
|
||||
return nil, err
|
||||
}
|
||||
|
||||
@@ -876,6 +918,17 @@ func UpdateUser(user *models.User) (*models.User, error) {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// clear auth failed record
|
||||
if user.Password != "" {
|
||||
redisClient := redis.Client()
|
||||
|
||||
records, err := redisClient.Keys(fmt.Sprintf("kubesphere:authfailed:%s:*", user.Username)).Result()
|
||||
|
||||
if err == nil {
|
||||
redisClient.Del(records...)
|
||||
}
|
||||
}
|
||||
|
||||
return GetUserInfo(user.Username)
|
||||
}
|
||||
func DeleteGroup(path string) error {
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
package resources
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"kubesphere.io/kubesphere/pkg/constants"
|
||||
"kubesphere.io/kubesphere/pkg/informers"
|
||||
"kubesphere.io/kubesphere/pkg/params"
|
||||
@@ -45,6 +46,11 @@ func (*nodeSearcher) match(match map[string]string, item *v1.Node) bool {
|
||||
if !sliceutil.HasString(names, item.Name) {
|
||||
return false
|
||||
}
|
||||
case Role:
|
||||
labelKey := fmt.Sprintf("node-role.kubernetes.io/%s", v)
|
||||
if _, ok := item.Labels[labelKey]; !ok {
|
||||
return false
|
||||
}
|
||||
case Keyword:
|
||||
if !strings.Contains(item.Name, v) && !searchFuzzy(item.Labels, "", v) && !searchFuzzy(item.Annotations, "", v) {
|
||||
return false
|
||||
|
||||
@@ -61,6 +61,7 @@ const (
|
||||
Label = "label"
|
||||
OwnerKind = "ownerKind"
|
||||
OwnerName = "ownerName"
|
||||
Role = "role"
|
||||
CreateTime = "createTime"
|
||||
UpdateTime = "updateTime"
|
||||
LastScheduleTime = "lastScheduleTime"
|
||||
|
||||
Reference in New Issue
Block a user