Compare commits
3 Commits
module-l4-
...
bfl/feat/r
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6da48e9679 | ||
|
|
fe98eaf1ba | ||
|
|
2a54db6af3 |
@@ -266,7 +266,7 @@ spec:
|
|||||||
|
|
||||||
containers:
|
containers:
|
||||||
- name: api
|
- name: api
|
||||||
image: beclab/bfl:v0.4.35
|
image: beclab/bfl:v0.4.36
|
||||||
imagePullPolicy: IfNotPresent
|
imagePullPolicy: IfNotPresent
|
||||||
securityContext:
|
securityContext:
|
||||||
runAsUser: 1000
|
runAsUser: 1000
|
||||||
|
|||||||
@@ -2,8 +2,6 @@ package v1
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math"
|
|
||||||
"net/http"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
@@ -11,17 +9,12 @@ import (
|
|||||||
"bytetrade.io/web3os/bfl/pkg/api"
|
"bytetrade.io/web3os/bfl/pkg/api"
|
||||||
"bytetrade.io/web3os/bfl/pkg/api/response"
|
"bytetrade.io/web3os/bfl/pkg/api/response"
|
||||||
"bytetrade.io/web3os/bfl/pkg/apis"
|
"bytetrade.io/web3os/bfl/pkg/apis"
|
||||||
"bytetrade.io/web3os/bfl/pkg/apis/backend/v1/metrics"
|
|
||||||
iamV1alpha1 "bytetrade.io/web3os/bfl/pkg/apis/iam/v1alpha1"
|
|
||||||
"bytetrade.io/web3os/bfl/pkg/apis/iam/v1alpha1/operator"
|
"bytetrade.io/web3os/bfl/pkg/apis/iam/v1alpha1/operator"
|
||||||
monitov1alpha1 "bytetrade.io/web3os/bfl/pkg/apis/monitor/v1alpha1"
|
|
||||||
"bytetrade.io/web3os/bfl/pkg/apiserver/runtime"
|
"bytetrade.io/web3os/bfl/pkg/apiserver/runtime"
|
||||||
"bytetrade.io/web3os/bfl/pkg/app_service/v1"
|
"bytetrade.io/web3os/bfl/pkg/app_service/v1"
|
||||||
"bytetrade.io/web3os/bfl/pkg/client/clientset/v1alpha1"
|
"bytetrade.io/web3os/bfl/pkg/client/clientset/v1alpha1"
|
||||||
"bytetrade.io/web3os/bfl/pkg/constants"
|
"bytetrade.io/web3os/bfl/pkg/constants"
|
||||||
"bytetrade.io/web3os/bfl/pkg/utils"
|
|
||||||
"bytetrade.io/web3os/bfl/pkg/utils/certmanager"
|
"bytetrade.io/web3os/bfl/pkg/utils/certmanager"
|
||||||
"bytetrade.io/web3os/bfl/pkg/utils/k8sutil"
|
|
||||||
|
|
||||||
iamV1alpha2 "github.com/beclab/api/iam/v1alpha2"
|
iamV1alpha2 "github.com/beclab/api/iam/v1alpha2"
|
||||||
"github.com/emicklei/go-restful/v3"
|
"github.com/emicklei/go-restful/v3"
|
||||||
@@ -42,53 +35,6 @@ func New() *Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) handleGetIPAddress(req *restful.Request, resp *restful.Response) {
|
|
||||||
ctx := req.Request.Context()
|
|
||||||
master := req.QueryParameter("master")
|
|
||||||
|
|
||||||
var masterInternalIP string
|
|
||||||
|
|
||||||
if master == "true" {
|
|
||||||
ip, err := k8sutil.GetL4ProxyNodeIP(ctx, 10*time.Second)
|
|
||||||
if err != nil {
|
|
||||||
log.Warnf("no master hostIP: %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
if ip != nil && *ip != "" {
|
|
||||||
masterInternalIP = *ip
|
|
||||||
}
|
|
||||||
|
|
||||||
resp.Write([]byte(masterInternalIP))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
ipAddr := IPAddress{
|
|
||||||
IsNatted: constants.IsNatted,
|
|
||||||
Internal: utils.RemoteIp(req.Request),
|
|
||||||
}
|
|
||||||
|
|
||||||
if masterInternalIP != "" {
|
|
||||||
ipAddr.MasterInternalIP = masterInternalIP
|
|
||||||
}
|
|
||||||
|
|
||||||
// master external ip
|
|
||||||
masterExternalIP := k8sutil.GetMasterExternalIP(ctx)
|
|
||||||
if masterExternalIP == nil {
|
|
||||||
response.HandleError(resp, errors.New("no master external ip"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ipAddr.MasterExternalIP = *masterExternalIP
|
|
||||||
|
|
||||||
external := utils.GetMyExternalIPAddr()
|
|
||||||
if external == "" {
|
|
||||||
response.HandleInternalError(resp, errors.New("no external ip address"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
ipAddr.External = external
|
|
||||||
|
|
||||||
response.Success(resp, ipAddr)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Handler) handleUserInfo(req *restful.Request, resp *restful.Response) {
|
func (h *Handler) handleUserInfo(req *restful.Request, resp *restful.Response) {
|
||||||
var (
|
var (
|
||||||
isEphemeral bool
|
isEphemeral bool
|
||||||
@@ -154,50 +100,6 @@ func (h *Handler) handleUserInfo(req *restful.Request, resp *restful.Response) {
|
|||||||
response.Success(resp, uInfo)
|
response.Success(resp, uInfo)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) handleVerifyUserPassword(req *restful.Request, resp *restful.Response) {
|
|
||||||
var u iamV1alpha1.UserPassword
|
|
||||||
err := req.ReadEntity(&u)
|
|
||||||
if err != nil {
|
|
||||||
response.HandleBadRequest(resp, errors.Errorf("verify password: %v", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Info("verify user password")
|
|
||||||
|
|
||||||
if u.UserName == "" {
|
|
||||||
u.UserName = constants.Username
|
|
||||||
}
|
|
||||||
|
|
||||||
// the user's password must be provided
|
|
||||||
if u.Password == "" {
|
|
||||||
response.HandleBadRequest(resp, errors.New("verify password: no password provided"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data := map[string]string{
|
|
||||||
"username": u.UserName,
|
|
||||||
"password": u.Password,
|
|
||||||
"client_id": constants.KubeSphereClientID,
|
|
||||||
"client_secret": constants.KubeSphereClientSecret,
|
|
||||||
"grant_type": "password",
|
|
||||||
}
|
|
||||||
|
|
||||||
token, code, err := iamV1alpha1.RequestToken("", data)
|
|
||||||
if err != nil {
|
|
||||||
resp.WriteHeaderAndEntity(http.StatusOK, response.Header{
|
|
||||||
Code: code,
|
|
||||||
Message: err.Error(),
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
if token.AccessToken != "" {
|
|
||||||
response.SuccessNoData(resp)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
response.HandleUnauthorized(resp, errors.New(response.UnexpectedError))
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Handler) handleReDownloadCert(req *restful.Request, resp *restful.Response) {
|
func (h *Handler) handleReDownloadCert(req *restful.Request, resp *restful.Response) {
|
||||||
var (
|
var (
|
||||||
ctx = req.Request.Context()
|
ctx = req.Request.Context()
|
||||||
@@ -469,68 +371,3 @@ func (h *Handler) myapps(req *restful.Request, resp *restful.Response) {
|
|||||||
response.Success(resp, api.NewListResult(list))
|
response.Success(resp, api.NewListResult(list))
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) getClusterMetric(req *restful.Request, resp *restful.Response) {
|
|
||||||
prome, err := metrics.NewPrometheus(metrics.PrometheusEndpoint)
|
|
||||||
if err != nil {
|
|
||||||
response.HandleError(resp, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
opts := metrics.QueryOptions{
|
|
||||||
Level: metrics.LevelCluster,
|
|
||||||
}
|
|
||||||
|
|
||||||
metricsResult := prome.GetNamedMetrics(req.Request.Context(), []string{
|
|
||||||
"cluster_cpu_usage",
|
|
||||||
"cluster_cpu_total",
|
|
||||||
"cluster_disk_size_usage",
|
|
||||||
"cluster_disk_size_capacity",
|
|
||||||
"cluster_memory_total",
|
|
||||||
"cluster_memory_usage_wo_cache",
|
|
||||||
"cluster_net_bytes_transmitted",
|
|
||||||
"cluster_net_bytes_received",
|
|
||||||
}, time.Now(), opts)
|
|
||||||
|
|
||||||
var clusterMetrics monitov1alpha1.ClusterMetrics
|
|
||||||
for _, m := range metricsResult {
|
|
||||||
switch m.MetricName {
|
|
||||||
case "cluster_cpu_usage":
|
|
||||||
clusterMetrics.CPU.Usage = metrics.GetValue(&m)
|
|
||||||
case "cluster_cpu_total":
|
|
||||||
clusterMetrics.CPU.Total = metrics.GetValue(&m)
|
|
||||||
|
|
||||||
case "cluster_disk_size_usage":
|
|
||||||
clusterMetrics.Disk.Usage = metrics.GetValue(&m)
|
|
||||||
case "cluster_disk_size_capacity":
|
|
||||||
clusterMetrics.Disk.Total = metrics.GetValue(&m)
|
|
||||||
|
|
||||||
case "cluster_memory_total":
|
|
||||||
clusterMetrics.Memory.Total = metrics.GetValue(&m)
|
|
||||||
case "cluster_memory_usage_wo_cache":
|
|
||||||
clusterMetrics.Memory.Usage = metrics.GetValue(&m)
|
|
||||||
|
|
||||||
case "cluster_net_bytes_transmitted":
|
|
||||||
clusterMetrics.Net.Transmitted = metrics.GetValue(&m)
|
|
||||||
|
|
||||||
case "cluster_net_bytes_received":
|
|
||||||
clusterMetrics.Net.Received = metrics.GetValue(&m)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
roundToGB := func(v float64) float64 { return math.Round((v/1000000000.00)*100.00) / 100.00 }
|
|
||||||
fmtMetricsValue(&clusterMetrics.CPU, "Cores", func(v float64) float64 { return v })
|
|
||||||
fmtMetricsValue(&clusterMetrics.Memory, "GB", roundToGB)
|
|
||||||
fmtMetricsValue(&clusterMetrics.Disk, "GB", roundToGB)
|
|
||||||
|
|
||||||
response.Success(resp, clusterMetrics)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
func fmtMetricsValue(v *monitov1alpha1.MetricV, unit string, unitFunc func(float64) float64) {
|
|
||||||
v.Unit = unit
|
|
||||||
|
|
||||||
v.Usage = unitFunc(v.Usage)
|
|
||||||
v.Total = unitFunc(v.Total)
|
|
||||||
v.Ratio = math.Round((v.Usage / v.Total) * 100)
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -4,7 +4,6 @@ import (
|
|||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"bytetrade.io/web3os/bfl/pkg/api/response"
|
"bytetrade.io/web3os/bfl/pkg/api/response"
|
||||||
iamV1alpha1 "bytetrade.io/web3os/bfl/pkg/apis/iam/v1alpha1"
|
|
||||||
"bytetrade.io/web3os/bfl/pkg/apiserver/runtime"
|
"bytetrade.io/web3os/bfl/pkg/apiserver/runtime"
|
||||||
|
|
||||||
restfulspec "github.com/emicklei/go-restful-openapi/v2"
|
restfulspec "github.com/emicklei/go-restful-openapi/v2"
|
||||||
@@ -23,13 +22,6 @@ func AddContainer(c *restful.Container) error {
|
|||||||
|
|
||||||
handler := New()
|
handler := New()
|
||||||
|
|
||||||
ws.Route(ws.POST("/verify-password").
|
|
||||||
To(handler.handleVerifyUserPassword).
|
|
||||||
Doc("Verify user password.").
|
|
||||||
Reads(iamV1alpha1.UserPassword{}).
|
|
||||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
|
||||||
Returns(http.StatusOK, "", response.Response{}))
|
|
||||||
|
|
||||||
ws.Route(ws.GET("/user-info").
|
ws.Route(ws.GET("/user-info").
|
||||||
To(handler.handleUserInfo).
|
To(handler.handleUserInfo).
|
||||||
Doc("User information.").
|
Doc("User information.").
|
||||||
@@ -48,13 +40,6 @@ func AddContainer(c *restful.Container) error {
|
|||||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||||
Returns(http.StatusOK, "", response.Response{}))
|
Returns(http.StatusOK, "", response.Response{}))
|
||||||
|
|
||||||
ws.Route(ws.GET("/ip").
|
|
||||||
To(handler.handleGetIPAddress).
|
|
||||||
Doc("IP Address.").
|
|
||||||
Param(ws.QueryParameter("master", "get master nodeIP only").DataType("string").Required(false)).
|
|
||||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
|
||||||
Returns(http.StatusOK, "", response.Response{}))
|
|
||||||
|
|
||||||
ws.Route(ws.GET("/re-download-cert").
|
ws.Route(ws.GET("/re-download-cert").
|
||||||
To(handler.handleReDownloadCert).
|
To(handler.handleReDownloadCert).
|
||||||
Doc("Re-download ssl certificate").
|
Doc("Re-download ssl certificate").
|
||||||
@@ -67,12 +52,6 @@ func AddContainer(c *restful.Container) error {
|
|||||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
Metadata(restfulspec.KeyOpenAPITags, tags).
|
||||||
Returns(http.StatusOK, "", response.Response{}))
|
Returns(http.StatusOK, "", response.Response{}))
|
||||||
|
|
||||||
ws.Route(ws.GET("/cluster").
|
|
||||||
To(handler.getClusterMetric).
|
|
||||||
Doc("get the cluster current metrics ( cpu, memory, disk ).").
|
|
||||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
|
||||||
Returns(http.StatusOK, "", response.Response{}))
|
|
||||||
|
|
||||||
ws.Route(ws.GET("/config-system").
|
ws.Route(ws.GET("/config-system").
|
||||||
To(handler.HandleGetSysConfig).
|
To(handler.HandleGetSysConfig).
|
||||||
Doc("get user locale.").
|
Doc("get user locale.").
|
||||||
@@ -85,12 +64,6 @@ func AddContainer(c *restful.Container) error {
|
|||||||
wsWizard.Consumes(restful.MIME_JSON)
|
wsWizard.Consumes(restful.MIME_JSON)
|
||||||
wsWizard.Produces(restful.MIME_JSON)
|
wsWizard.Produces(restful.MIME_JSON)
|
||||||
|
|
||||||
wsWizard.Route(wsWizard.GET("/terminus-info").
|
|
||||||
To(handler.handleTerminusInfo).
|
|
||||||
Doc("terminus information.").
|
|
||||||
Metadata(restfulspec.KeyOpenAPITags, tags).
|
|
||||||
Returns(http.StatusOK, "", response.Response{}))
|
|
||||||
|
|
||||||
wsWizard.Route(wsWizard.GET("/olares-info").
|
wsWizard.Route(wsWizard.GET("/olares-info").
|
||||||
To(handler.handleOlaresInfo).
|
To(handler.handleOlaresInfo).
|
||||||
Doc("olares information.").
|
Doc("olares information.").
|
||||||
|
|||||||
@@ -1,43 +0,0 @@
|
|||||||
package v1alpha1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"bytetrade.io/web3os/bfl/pkg/api/response"
|
|
||||||
|
|
||||||
"github.com/emicklei/go-restful/v3"
|
|
||||||
"k8s.io/klog/v2"
|
|
||||||
)
|
|
||||||
|
|
||||||
const BackupCancelCode = 493
|
|
||||||
|
|
||||||
type handler struct {
|
|
||||||
}
|
|
||||||
|
|
||||||
func newHandler() *handler {
|
|
||||||
return &handler{}
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *handler) backupNew(req *restful.Request, resp *restful.Response) {
|
|
||||||
klog.Info("backup start callback")
|
|
||||||
for _, cb := range callbackHandlers {
|
|
||||||
err := cb.BackupNew()
|
|
||||||
if err != nil {
|
|
||||||
klog.Error("backup start response error, ", err)
|
|
||||||
resp.WriteError(BackupCancelCode, err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
response.SuccessNoData(resp)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *handler) backupFinish(req *restful.Request, resp *restful.Response) {
|
|
||||||
klog.Info("backup finished callback")
|
|
||||||
for _, cb := range callbackHandlers {
|
|
||||||
err := cb.BackupFinish()
|
|
||||||
if err != nil {
|
|
||||||
klog.Warning("backup finished callback error, ", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
response.SuccessNoData(resp)
|
|
||||||
}
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
package v1alpha1
|
|
||||||
|
|
||||||
import (
|
|
||||||
"net/http"
|
|
||||||
|
|
||||||
"bytetrade.io/web3os/bfl/pkg/api/response"
|
|
||||||
"bytetrade.io/web3os/bfl/pkg/apiserver/runtime"
|
|
||||||
|
|
||||||
restfulspec "github.com/emicklei/go-restful-openapi/v2"
|
|
||||||
"github.com/emicklei/go-restful/v3"
|
|
||||||
)
|
|
||||||
|
|
||||||
type CallbackHandler struct {
|
|
||||||
BackupNew func() error
|
|
||||||
BackupFinish func() error
|
|
||||||
}
|
|
||||||
|
|
||||||
var (
|
|
||||||
MODULE_TAGS = []string{"callbacks"}
|
|
||||||
|
|
||||||
callbackHandlers []*CallbackHandler
|
|
||||||
)
|
|
||||||
|
|
||||||
var ModuleVersion = runtime.ModuleVersion{Name: "callback", Version: "v1alpha1"}
|
|
||||||
|
|
||||||
func AddToContainer(c *restful.Container) error {
|
|
||||||
ws := runtime.NewWebService(ModuleVersion)
|
|
||||||
handler := newHandler()
|
|
||||||
|
|
||||||
ws.Route(ws.POST("/backup/new").
|
|
||||||
To(handler.backupNew).
|
|
||||||
Doc("Provide system backup phase-new to callback").
|
|
||||||
Metadata(restfulspec.KeyOpenAPITags, MODULE_TAGS).
|
|
||||||
Returns(http.StatusOK, "Success", response.Response{}))
|
|
||||||
|
|
||||||
ws.Route(ws.POST("/backup/finish").
|
|
||||||
To(handler.backupFinish).
|
|
||||||
Doc("Provide system backup phase-success / failed / canceled to callback").
|
|
||||||
Metadata(restfulspec.KeyOpenAPITags, MODULE_TAGS).
|
|
||||||
Returns(http.StatusOK, "Success", response.Response{}))
|
|
||||||
|
|
||||||
c.Add(ws)
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func AddBackupCallbackHandler(backupNew func() error, backupFinish func() error) {
|
|
||||||
callbackHandlers = append(callbackHandlers, &CallbackHandler{
|
|
||||||
BackupNew: backupNew,
|
|
||||||
BackupFinish: backupFinish,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
@@ -55,41 +55,6 @@ func New(ctrlClient client.Client) *Handler {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) handleUserLogin(req *restful.Request, resp *restful.Response) {
|
|
||||||
var u UserPassword
|
|
||||||
err := req.ReadEntity(&u)
|
|
||||||
if err != nil {
|
|
||||||
response.HandleBadRequest(resp, errors.Errorf("login user, read entity: %v", err))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
log.Infow("read user entity", "userPassword", u)
|
|
||||||
|
|
||||||
if u.UserName != constants.Username {
|
|
||||||
response.HandleBadRequest(resp, errors.New("login user: mismatch input username and userspace"))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
data := map[string]string{
|
|
||||||
"username": u.UserName,
|
|
||||||
"password": u.Password,
|
|
||||||
"client_id": constants.KubeSphereClientID,
|
|
||||||
"client_secret": constants.KubeSphereClientSecret,
|
|
||||||
"grant_type": "password",
|
|
||||||
}
|
|
||||||
|
|
||||||
token, code, err := RequestToken("", data)
|
|
||||||
if err != nil {
|
|
||||||
// response.HandleError(resp, errors.Errorf("login user, request token: %v", err))
|
|
||||||
resp.WriteHeaderAndEntity(http.StatusOK, response.Header{
|
|
||||||
Code: code,
|
|
||||||
Message: err.Error(),
|
|
||||||
})
|
|
||||||
return
|
|
||||||
}
|
|
||||||
response.Success(resp, token)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Handler) getRolesByUserName(ctx context.Context, name string) ([]string, error) {
|
func (h *Handler) getRolesByUserName(ctx context.Context, name string) ([]string, error) {
|
||||||
var globalRoleBindings iamV1alpha2.GlobalRoleBindingList
|
var globalRoleBindings iamV1alpha2.GlobalRoleBindingList
|
||||||
err := h.ctrlClient.List(ctx, &globalRoleBindings)
|
err := h.ctrlClient.List(ctx, &globalRoleBindings)
|
||||||
@@ -374,18 +339,6 @@ func RequestToken(token string, data map[string]string) (*TokenResponse, int, er
|
|||||||
return nil, -1, err
|
return nil, -1, err
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) isUserCreating() bool {
|
|
||||||
return h.userCreatingCount.Load() > 0
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Handler) lockUserCreating() {
|
|
||||||
h.userCreatingCount.Store(-1)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Handler) unlockUserCreating() {
|
|
||||||
h.userCreatingCount.Store(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (h *Handler) handleGetUserMetrics(req *restful.Request, resp *restful.Response) {
|
func (h *Handler) handleGetUserMetrics(req *restful.Request, resp *restful.Response) {
|
||||||
user := req.PathParameter("user")
|
user := req.PathParameter("user")
|
||||||
token := req.HeaderParameter(constants.UserAuthorizationTokenKey)
|
token := req.HeaderParameter(constants.UserAuthorizationTokenKey)
|
||||||
|
|||||||
@@ -41,11 +41,6 @@ type LoginRecord struct {
|
|||||||
LoginTime *int64 `json:"login_time"`
|
LoginTime *int64 `json:"login_time"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type UserPassword struct {
|
|
||||||
UserName string `json:"username,omitempty"`
|
|
||||||
Password string `json:"password"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type KubesphereError struct {
|
type KubesphereError struct {
|
||||||
Error string `json:"error"`
|
Error string `json:"error"`
|
||||||
ErrorDescription string `json:"error_description"`
|
ErrorDescription string `json:"error_description"`
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
package v1alpha1
|
package v1alpha1
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"errors"
|
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
"bytetrade.io/web3os/bfl/pkg/api/response"
|
"bytetrade.io/web3os/bfl/pkg/api/response"
|
||||||
@@ -32,7 +31,7 @@ var (
|
|||||||
userTags = []string{"users"}
|
userTags = []string{"users"}
|
||||||
)
|
)
|
||||||
|
|
||||||
func AddToContainer(c *restful.Container, addCallback func(func() error, func() error)) error {
|
func AddToContainer(c *restful.Container) error {
|
||||||
ws := runtime.NewWebService(ModuleVersion)
|
ws := runtime.NewWebService(ModuleVersion)
|
||||||
config, err := ctrl.GetConfig()
|
config, err := ctrl.GetConfig()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -85,22 +84,5 @@ func AddToContainer(c *restful.Container, addCallback func(func() error, func()
|
|||||||
Returns(http.StatusOK, "", response.Response{}))
|
Returns(http.StatusOK, "", response.Response{}))
|
||||||
|
|
||||||
c.Add(ws)
|
c.Add(ws)
|
||||||
|
|
||||||
// add user creating event to backup callback
|
|
||||||
addCallback(
|
|
||||||
func() error { // phase backup-new
|
|
||||||
if handler.isUserCreating() {
|
|
||||||
return errors.New("user createing")
|
|
||||||
}
|
|
||||||
|
|
||||||
handler.lockUserCreating()
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
|
|
||||||
func() error { // phase backup-finished
|
|
||||||
handler.unlockUserCreating()
|
|
||||||
return nil
|
|
||||||
},
|
|
||||||
)
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -243,12 +243,35 @@ func (h *Handler) handleActivate(req *restful.Request, resp *restful.Response) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// for owner user, use the reverse proxy config from the payload
|
||||||
|
// for non-owner user, reuse the owner's reverse proxy config
|
||||||
|
isOwner := userOp.GetUserAnnotation(user, constants.UserAnnotationOwnerRole) == constants.RoleOwner
|
||||||
|
|
||||||
reverseProxyConf := &ReverseProxyConfig{}
|
reverseProxyConf := &ReverseProxyConfig{}
|
||||||
|
if isOwner {
|
||||||
if payload.FRP.Host != "" {
|
if payload.FRP.Host != "" {
|
||||||
reverseProxyConf.EnableFRP = true
|
reverseProxyConf.EnableFRP = true
|
||||||
reverseProxyConf.FRPServer = payload.FRP.Host
|
reverseProxyConf.FRPServer = payload.FRP.Host
|
||||||
reverseProxyConf.FRPAuthMethod = FRPAuthMethodJWS
|
reverseProxyConf.FRPAuthMethod = FRPAuthMethodJWS
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
ownerUser, ownerErr := userOp.GetOwnerUser()
|
||||||
|
if ownerErr != nil {
|
||||||
|
err = fmt.Errorf("activate system: failed to get owner user for reverse proxy config: %v", ownerErr)
|
||||||
|
klog.Error(err)
|
||||||
|
response.HandleError(resp, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
ownerNamespace := fmt.Sprintf(constants.UserspaceNameFormat, ownerUser.Name)
|
||||||
|
ownerConf, ownerConfErr := GetReverseProxyConfigFromNamespace(ctx, ownerNamespace)
|
||||||
|
if ownerConfErr != nil {
|
||||||
|
err = fmt.Errorf("activate system: failed to get owner's reverse proxy config: %v", ownerConfErr)
|
||||||
|
klog.Error(err)
|
||||||
|
response.HandleError(resp, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
reverseProxyConf = ownerConf
|
||||||
|
}
|
||||||
// no matter whether the reverse proxy is enabled, we need to persist the configuration
|
// no matter whether the reverse proxy is enabled, we need to persist the configuration
|
||||||
// so that the configuration can be fetched by the frontend
|
// so that the configuration can be fetched by the frontend
|
||||||
// and the reverse proxy type can be set, enabling the ip watching mechanism to function normally
|
// and the reverse proxy type can be set, enabling the ip watching mechanism to function normally
|
||||||
|
|||||||
@@ -549,7 +549,11 @@ func (conf *ReverseProxyConfig) generateReverseProxyConfigMapData() map[string]s
|
|||||||
}
|
}
|
||||||
|
|
||||||
func GetReverseProxyConfig(ctx context.Context) (*ReverseProxyConfig, error) {
|
func GetReverseProxyConfig(ctx context.Context) (*ReverseProxyConfig, error) {
|
||||||
configData, err := k8sutil.GetConfigMapData(ctx, constants.Namespace, constants.ReverseProxyConfigMapName)
|
return GetReverseProxyConfigFromNamespace(ctx, constants.Namespace)
|
||||||
|
}
|
||||||
|
|
||||||
|
func GetReverseProxyConfigFromNamespace(ctx context.Context, namespace string) (*ReverseProxyConfig, error) {
|
||||||
|
configData, err := k8sutil.GetConfigMapData(ctx, namespace, constants.ReverseProxyConfigMapName)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "error getting configmap")
|
return nil, errors.Wrap(err, "error getting configmap")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
"bytetrade.io/web3os/bfl/internal/log"
|
"bytetrade.io/web3os/bfl/internal/log"
|
||||||
"bytetrade.io/web3os/bfl/pkg/api/response"
|
"bytetrade.io/web3os/bfl/pkg/api/response"
|
||||||
backendv1 "bytetrade.io/web3os/bfl/pkg/apis/backend/v1"
|
backendv1 "bytetrade.io/web3os/bfl/pkg/apis/backend/v1"
|
||||||
callbackV1alpha1 "bytetrade.io/web3os/bfl/pkg/apis/callback/v1alpha1"
|
|
||||||
|
|
||||||
iamV1alpha1 "bytetrade.io/web3os/bfl/pkg/apis/iam/v1alpha1"
|
iamV1alpha1 "bytetrade.io/web3os/bfl/pkg/apis/iam/v1alpha1"
|
||||||
monitov1alpha1 "bytetrade.io/web3os/bfl/pkg/apis/monitor/v1alpha1"
|
monitov1alpha1 "bytetrade.io/web3os/bfl/pkg/apis/monitor/v1alpha1"
|
||||||
@@ -114,8 +113,7 @@ func (s *APIServer) installAPIDocs() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func (s *APIServer) installModuleAPI() {
|
func (s *APIServer) installModuleAPI() {
|
||||||
urlruntime.Must(callbackV1alpha1.AddToContainer(s.container))
|
urlruntime.Must(iamV1alpha1.AddToContainer(s.container))
|
||||||
urlruntime.Must(iamV1alpha1.AddToContainer(s.container, callbackV1alpha1.AddBackupCallbackHandler))
|
|
||||||
urlruntime.Must(backendv1.AddContainer(s.container))
|
urlruntime.Must(backendv1.AddContainer(s.container))
|
||||||
urlruntime.Must(settingsV1alpha1.AddContainer(s.container))
|
urlruntime.Must(settingsV1alpha1.AddContainer(s.container))
|
||||||
urlruntime.Must(monitov1alpha1.AddContainer(s.container))
|
urlruntime.Must(monitov1alpha1.AddContainer(s.container))
|
||||||
|
|||||||
Reference in New Issue
Block a user