mirror of
https://github.com/kubeshark/kubeshark.git
synced 2025-09-04 12:05:35 +00:00
auth status route to api server (#342)
This commit is contained in:
@@ -34,3 +34,13 @@ func PostTappedPods(c *gin.Context) {
|
|||||||
func GetTappersCount(c *gin.Context) {
|
func GetTappersCount(c *gin.Context) {
|
||||||
c.JSON(http.StatusOK, providers.TappersCount)
|
c.JSON(http.StatusOK, providers.TappersCount)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetAuthStatus(c *gin.Context) {
|
||||||
|
authStatus, err := providers.GetAuthStatus()
|
||||||
|
if err != nil {
|
||||||
|
c.JSON(http.StatusInternalServerError, err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
c.JSON(http.StatusOK, authStatus)
|
||||||
|
}
|
||||||
|
29
agent/pkg/providers/auth_provider.go
Normal file
29
agent/pkg/providers/auth_provider.go
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
package providers
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/json"
|
||||||
|
"fmt"
|
||||||
|
"github.com/up9inc/mizu/shared"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
var authStatus *shared.AuthStatus
|
||||||
|
|
||||||
|
func GetAuthStatus() (*shared.AuthStatus, error) {
|
||||||
|
if authStatus == nil {
|
||||||
|
authStatus = &shared.AuthStatus{}
|
||||||
|
|
||||||
|
authStatusJson := os.Getenv(shared.AuthStatusEnvVar)
|
||||||
|
if authStatusJson == "" {
|
||||||
|
return authStatus, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
err := json.Unmarshal([]byte(authStatusJson), authStatus)
|
||||||
|
if err != nil {
|
||||||
|
authStatus = nil
|
||||||
|
return nil, fmt.Errorf("failed to marshal auth status, err: %v", err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return authStatus, nil
|
||||||
|
}
|
@@ -11,4 +11,6 @@ func StatusRoutes(ginApp *gin.Engine) {
|
|||||||
routeGroup.POST("/tappedPods", controllers.PostTappedPods)
|
routeGroup.POST("/tappedPods", controllers.PostTappedPods)
|
||||||
|
|
||||||
routeGroup.GET("/tappersCount", controllers.GetTappersCount)
|
routeGroup.GET("/tappersCount", controllers.GetTappersCount)
|
||||||
|
|
||||||
|
routeGroup.GET("/auth", controllers.GetAuthStatus)
|
||||||
}
|
}
|
||||||
|
@@ -23,14 +23,9 @@ const loginTimeoutInMin = 2
|
|||||||
var listenPorts = []int{3141, 4001, 5002, 6003, 7004, 8005, 9006, 10007}
|
var listenPorts = []int{3141, 4001, 5002, 6003, 7004, 8005, 9006, 10007}
|
||||||
|
|
||||||
func IsTokenExpired(tokenString string) (bool, error) {
|
func IsTokenExpired(tokenString string) (bool, error) {
|
||||||
token, _, err := new(jwt.Parser).ParseUnverified(tokenString, jwt.MapClaims{})
|
claims, err := getTokenClaims(tokenString)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return true, fmt.Errorf("failed to parse token, err: %v", err)
|
return true, err
|
||||||
}
|
|
||||||
|
|
||||||
claims, ok := token.Claims.(jwt.MapClaims)
|
|
||||||
if !ok {
|
|
||||||
return true, fmt.Errorf("can't convert token's claims to standard claims")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
expiry := time.Unix(int64(claims["exp"].(float64)), 0)
|
expiry := time.Unix(int64(claims["exp"].(float64)), 0)
|
||||||
@@ -38,6 +33,29 @@ func IsTokenExpired(tokenString string) (bool, error) {
|
|||||||
return time.Now().After(expiry), nil
|
return time.Now().After(expiry), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func GetTokenEmail(tokenString string) (string, error) {
|
||||||
|
claims, err := getTokenClaims(tokenString)
|
||||||
|
if err != nil {
|
||||||
|
return "", err
|
||||||
|
}
|
||||||
|
|
||||||
|
return claims["email"].(string), nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func getTokenClaims(tokenString string) (jwt.MapClaims, error) {
|
||||||
|
token, _, err := new(jwt.Parser).ParseUnverified(tokenString, jwt.MapClaims{})
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("failed to parse token, err: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
claims, ok := token.Claims.(jwt.MapClaims)
|
||||||
|
if !ok {
|
||||||
|
return nil, fmt.Errorf("can't convert token's claims to standard claims")
|
||||||
|
}
|
||||||
|
|
||||||
|
return claims, nil
|
||||||
|
}
|
||||||
|
|
||||||
func Login() error {
|
func Login() error {
|
||||||
token, loginErr := loginInteractively()
|
token, loginErr := loginInteractively()
|
||||||
if loginErr != nil {
|
if loginErr != nil {
|
||||||
|
@@ -3,6 +3,7 @@ package cmd
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/up9inc/mizu/cli/auth"
|
||||||
"path"
|
"path"
|
||||||
"regexp"
|
"regexp"
|
||||||
"strings"
|
"strings"
|
||||||
@@ -48,6 +49,12 @@ func RunMizuTap() {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
authStatus, err := getAuthStatus()
|
||||||
|
if err != nil {
|
||||||
|
logger.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error getting auth status: %v", errormessage.FormatError(err)))
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
var mizuValidationRules string
|
var mizuValidationRules string
|
||||||
if config.Config.Tap.EnforcePolicyFile != "" {
|
if config.Config.Tap.EnforcePolicyFile != "" {
|
||||||
mizuValidationRules, err = readValidationRules(config.Config.Tap.EnforcePolicyFile)
|
mizuValidationRules, err = readValidationRules(config.Config.Tap.EnforcePolicyFile)
|
||||||
@@ -103,7 +110,7 @@ func RunMizuTap() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
defer finishMizuExecution(kubernetesProvider)
|
defer finishMizuExecution(kubernetesProvider)
|
||||||
if err := createMizuResources(ctx, kubernetesProvider, mizuApiFilteringOptions, mizuValidationRules); err != nil {
|
if err := createMizuResources(ctx, kubernetesProvider, mizuApiFilteringOptions, mizuValidationRules, authStatus); err != nil {
|
||||||
logger.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error creating resources: %v", errormessage.FormatError(err)))
|
logger.Log.Errorf(uiUtils.Error, fmt.Sprintf("Error creating resources: %v", errormessage.FormatError(err)))
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -125,14 +132,14 @@ func readValidationRules(file string) (string, error) {
|
|||||||
return string(newContent), nil
|
return string(newContent), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func createMizuResources(ctx context.Context, kubernetesProvider *kubernetes.Provider, mizuApiFilteringOptions *api.TrafficFilteringOptions, mizuValidationRules string) error {
|
func createMizuResources(ctx context.Context, kubernetesProvider *kubernetes.Provider, mizuApiFilteringOptions *api.TrafficFilteringOptions, mizuValidationRules string, authStatus *shared.AuthStatus) error {
|
||||||
if !config.Config.IsNsRestrictedMode() {
|
if !config.Config.IsNsRestrictedMode() {
|
||||||
if err := createMizuNamespace(ctx, kubernetesProvider); err != nil {
|
if err := createMizuNamespace(ctx, kubernetesProvider); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := createMizuApiServer(ctx, kubernetesProvider, mizuApiFilteringOptions); err != nil {
|
if err := createMizuApiServer(ctx, kubernetesProvider, mizuApiFilteringOptions, authStatus); err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -153,7 +160,7 @@ func createMizuNamespace(ctx context.Context, kubernetesProvider *kubernetes.Pro
|
|||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
func createMizuApiServer(ctx context.Context, kubernetesProvider *kubernetes.Provider, mizuApiFilteringOptions *api.TrafficFilteringOptions) error {
|
func createMizuApiServer(ctx context.Context, kubernetesProvider *kubernetes.Provider, mizuApiFilteringOptions *api.TrafficFilteringOptions, authStatus *shared.AuthStatus) error {
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
state.mizuServiceAccountExists, err = createRBACIfNecessary(ctx, kubernetesProvider)
|
state.mizuServiceAccountExists, err = createRBACIfNecessary(ctx, kubernetesProvider)
|
||||||
@@ -175,6 +182,7 @@ func createMizuApiServer(ctx context.Context, kubernetesProvider *kubernetes.Pro
|
|||||||
ServiceAccountName: serviceAccountName,
|
ServiceAccountName: serviceAccountName,
|
||||||
IsNamespaceRestricted: config.Config.IsNsRestrictedMode(),
|
IsNamespaceRestricted: config.Config.IsNsRestrictedMode(),
|
||||||
MizuApiFilteringOptions: mizuApiFilteringOptions,
|
MizuApiFilteringOptions: mizuApiFilteringOptions,
|
||||||
|
AuthStatus: authStatus,
|
||||||
MaxEntriesDBSizeBytes: config.Config.Tap.MaxEntriesDBSizeBytes(),
|
MaxEntriesDBSizeBytes: config.Config.Tap.MaxEntriesDBSizeBytes(),
|
||||||
Resources: config.Config.Tap.ApiServerResources,
|
Resources: config.Config.Tap.ApiServerResources,
|
||||||
ImagePullPolicy: config.Config.ImagePullPolicy(),
|
ImagePullPolicy: config.Config.ImagePullPolicy(),
|
||||||
@@ -215,6 +223,22 @@ func getMizuApiFilteringOptions() (*api.TrafficFilteringOptions, error) {
|
|||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func getAuthStatus() (*shared.AuthStatus, error) {
|
||||||
|
if config.Config.Tap.Workspace == "" {
|
||||||
|
return &shared.AuthStatus{}, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
email, err := auth.GetTokenEmail(config.Config.Auth.Token)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &shared.AuthStatus{
|
||||||
|
Email: email,
|
||||||
|
Model: config.Config.Tap.Workspace,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
func updateMizuTappers(ctx context.Context, kubernetesProvider *kubernetes.Provider, mizuApiFilteringOptions *api.TrafficFilteringOptions) error {
|
func updateMizuTappers(ctx context.Context, kubernetesProvider *kubernetes.Provider, mizuApiFilteringOptions *api.TrafficFilteringOptions) error {
|
||||||
nodeToTappedPodIPMap := getNodeHostToTappedPodIpsMap(state.currentlyTappedPods)
|
nodeToTappedPodIPMap := getNodeHostToTappedPodIpsMap(state.currentlyTappedPods)
|
||||||
|
|
||||||
|
@@ -152,6 +152,7 @@ type ApiServerOptions struct {
|
|||||||
ServiceAccountName string
|
ServiceAccountName string
|
||||||
IsNamespaceRestricted bool
|
IsNamespaceRestricted bool
|
||||||
MizuApiFilteringOptions *api.TrafficFilteringOptions
|
MizuApiFilteringOptions *api.TrafficFilteringOptions
|
||||||
|
AuthStatus *shared.AuthStatus
|
||||||
MaxEntriesDBSizeBytes int64
|
MaxEntriesDBSizeBytes int64
|
||||||
Resources configStructs.Resources
|
Resources configStructs.Resources
|
||||||
ImagePullPolicy core.PullPolicy
|
ImagePullPolicy core.PullPolicy
|
||||||
@@ -162,6 +163,12 @@ func (provider *Provider) CreateMizuApiServerPod(ctx context.Context, opts *ApiS
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
marshaledAuthStatus, err := json.Marshal(opts.AuthStatus)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
configMapVolumeName := &core.ConfigMapVolumeSource{}
|
configMapVolumeName := &core.ConfigMapVolumeSource{}
|
||||||
configMapVolumeName.Name = mizu.ConfigMapName
|
configMapVolumeName.Name = mizu.ConfigMapName
|
||||||
configMapOptional := true
|
configMapOptional := true
|
||||||
@@ -217,6 +224,10 @@ func (provider *Provider) CreateMizuApiServerPod(ctx context.Context, opts *ApiS
|
|||||||
Name: shared.MizuFilteringOptionsEnvVar,
|
Name: shared.MizuFilteringOptionsEnvVar,
|
||||||
Value: string(marshaledFilteringOptions),
|
Value: string(marshaledFilteringOptions),
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
Name: shared.AuthStatusEnvVar,
|
||||||
|
Value: string(marshaledAuthStatus),
|
||||||
|
},
|
||||||
{
|
{
|
||||||
Name: shared.MaxEntriesDBSizeBytesEnvVar,
|
Name: shared.MaxEntriesDBSizeBytesEnvVar,
|
||||||
Value: strconv.FormatInt(opts.MaxEntriesDBSizeBytes, 10),
|
Value: strconv.FormatInt(opts.MaxEntriesDBSizeBytes, 10),
|
||||||
|
@@ -2,6 +2,7 @@ package shared
|
|||||||
|
|
||||||
const (
|
const (
|
||||||
MizuFilteringOptionsEnvVar = "SENSITIVE_DATA_FILTERING_OPTIONS"
|
MizuFilteringOptionsEnvVar = "SENSITIVE_DATA_FILTERING_OPTIONS"
|
||||||
|
AuthStatusEnvVar = "AUTH_STATUS"
|
||||||
HostModeEnvVar = "HOST_MODE"
|
HostModeEnvVar = "HOST_MODE"
|
||||||
NodeNameEnvVar = "NODE_NAME"
|
NodeNameEnvVar = "NODE_NAME"
|
||||||
TappedAddressesPerNodeDictEnvVar = "TAPPED_ADDRESSES_PER_HOST"
|
TappedAddressesPerNodeDictEnvVar = "TAPPED_ADDRESSES_PER_HOST"
|
||||||
|
@@ -56,6 +56,11 @@ type TLSLinkInfo struct {
|
|||||||
ResolvedSourceName string `json:"resolvedSourceName"`
|
ResolvedSourceName string `json:"resolvedSourceName"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type AuthStatus struct {
|
||||||
|
Email string `json:"email"`
|
||||||
|
Model string `json:"model"`
|
||||||
|
}
|
||||||
|
|
||||||
func CreateWebSocketStatusMessage(tappingStatus TapStatus) WebSocketStatusMessage {
|
func CreateWebSocketStatusMessage(tappingStatus TapStatus) WebSocketStatusMessage {
|
||||||
return WebSocketStatusMessage{
|
return WebSocketStatusMessage{
|
||||||
WebSocketMessageMetadata: &WebSocketMessageMetadata{
|
WebSocketMessageMetadata: &WebSocketMessageMetadata{
|
||||||
|
Reference in New Issue
Block a user