mirror of
https://github.com/kubeshark/kubeshark.git
synced 2026-02-14 18:09:51 +00:00
Compare commits
59 Commits
28.0-dev24
...
29.0-dev0
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
51658db0bd | ||
|
|
b2a4af8600 | ||
|
|
60e7890e23 | ||
|
|
f19c2f08c3 | ||
|
|
d8c0132a98 | ||
|
|
c5a36a494a | ||
|
|
a54cb917d0 | ||
|
|
30a85a4b92 | ||
|
|
cdbacff996 | ||
|
|
cf127c781c | ||
|
|
852a5ff045 | ||
|
|
0ef16bd55a | ||
|
|
de42de9d62 | ||
|
|
026745ac8e | ||
|
|
5e07924aca | ||
|
|
77078e78d1 | ||
|
|
727d75bccc | ||
|
|
d987bb17d2 | ||
|
|
89946041a1 | ||
|
|
b919c93f28 | ||
|
|
eac751190d | ||
|
|
2bc2051a46 | ||
|
|
89ad4e0f3a | ||
|
|
72f4753620 | ||
|
|
4badaadcc1 | ||
|
|
3f01f20f0c | ||
|
|
1fbb00f8f0 | ||
|
|
da7d3590fc | ||
|
|
256006ca3e | ||
|
|
213528c619 | ||
|
|
8b47dba05d | ||
|
|
5e5d5de91a | ||
|
|
680ea71958 | ||
|
|
5fb5dbbbf5 | ||
|
|
b3fe448ff1 | ||
|
|
101a54e8da | ||
|
|
3308cab826 | ||
|
|
5fdd8288f4 | ||
|
|
4cb32b40e6 | ||
|
|
afa81c7ec2 | ||
|
|
e84c7d3310 | ||
|
|
7d0a90cb78 | ||
|
|
24f79922e9 | ||
|
|
c3995009ee | ||
|
|
6e9fe2986e | ||
|
|
603240fedb | ||
|
|
e61871a68e | ||
|
|
379af59f07 | ||
|
|
ef9afe31a4 | ||
|
|
dca636b0fd | ||
|
|
9b72cc7aa6 | ||
|
|
d3c023b3ba | ||
|
|
5f2a4deb19 | ||
|
|
91f290987e | ||
|
|
2f3215b71a | ||
|
|
2e87a01346 | ||
|
|
453003bf14 | ||
|
|
80ca377668 | ||
|
|
d21297bc9c |
@@ -24,7 +24,6 @@
|
||||
"redactHeaderContent": "User-Header[REDACTED]",
|
||||
"redactBodyContent": "{ \"User\": \"[REDACTED]\" }",
|
||||
"regexMaskingBodyContent": "[REDACTED]",
|
||||
"minimumEntries": 25,
|
||||
"greenFilterColor": "rgb(210, 250, 210)",
|
||||
"redFilterColor": "rgb(250, 214, 220)",
|
||||
"bodyJsonClass": ".hljs",
|
||||
|
||||
@@ -25,14 +25,16 @@ export function resizeToNormalMizu() {
|
||||
}
|
||||
|
||||
export function verifyMinimumEntries() {
|
||||
const minimumEntries = Cypress.env('minimumEntries');
|
||||
it(`Making sure that mizu shows at least ${minimumEntries} entries`, async function () {
|
||||
const entriesSent = Cypress.env('entriesCount');
|
||||
const minimumEntries = Math.round((0.75 * entriesSent));
|
||||
|
||||
it(`Making sure that mizu shows at least ${minimumEntries} entries`, function () {
|
||||
cy.get('#total-entries').then(number => {
|
||||
const getNum = () => {
|
||||
const numOfEntries = number.text();
|
||||
return parseInt(numOfEntries);
|
||||
return parseInt(number.text());
|
||||
};
|
||||
cy.wrap({there: getNum}).invoke('there').should('be.gte', minimumEntries);
|
||||
|
||||
cy.wrap({num: getNum}).invoke('num').should('be.gt', minimumEntries);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
import {findLineAndCheck, getExpectedDetailsDict} from "../testHelpers/StatusBarHelper";
|
||||
import {verifyMinimumEntries} from "../testHelpers/TrafficHelper";
|
||||
|
||||
it('check', function () {
|
||||
const podName = Cypress.env('name'), namespace = Cypress.env('namespace');
|
||||
@@ -9,8 +8,6 @@ it('check', function () {
|
||||
cy.visit(`http://localhost:${port}`);
|
||||
cy.wait('@statusTap').its('response.statusCode').should('match', /^2\d{2}/);
|
||||
|
||||
verifyMinimumEntries();
|
||||
|
||||
cy.get('.podsCount').trigger('mouseover');
|
||||
findLineAndCheck(getExpectedDetailsDict(podName, namespace));
|
||||
});
|
||||
|
||||
@@ -2,15 +2,12 @@ import {
|
||||
checkThatAllEntriesShown,
|
||||
isValueExistsInElement,
|
||||
resizeToHugeMizu,
|
||||
verifyMinimumEntries
|
||||
} from "../testHelpers/TrafficHelper";
|
||||
|
||||
it('Loading Mizu', function () {
|
||||
cy.visit(Cypress.env('testUrl'));
|
||||
});
|
||||
|
||||
verifyMinimumEntries();
|
||||
|
||||
checkEntries();
|
||||
|
||||
function checkEntries() {
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import {isValueExistsInElement, verifyMinimumEntries} from '../testHelpers/TrafficHelper';
|
||||
import {isValueExistsInElement} from '../testHelpers/TrafficHelper';
|
||||
|
||||
it('Loading Mizu', function () {
|
||||
cy.visit(Cypress.env('testUrl'));
|
||||
});
|
||||
|
||||
verifyMinimumEntries();
|
||||
|
||||
isValueExistsInElement(false, Cypress.env('redactHeaderContent'), '#tbody-Headers');
|
||||
isValueExistsInElement(false, Cypress.env('redactBodyContent'), Cypress.env('bodyJsonClass'));
|
||||
|
||||
@@ -1,10 +1,8 @@
|
||||
import {isValueExistsInElement, verifyMinimumEntries} from '../testHelpers/TrafficHelper';
|
||||
import {isValueExistsInElement} from '../testHelpers/TrafficHelper';
|
||||
|
||||
it('Loading Mizu', function () {
|
||||
cy.visit(Cypress.env('testUrl'));
|
||||
});
|
||||
|
||||
verifyMinimumEntries();
|
||||
|
||||
isValueExistsInElement(true, Cypress.env('redactHeaderContent'), '#tbody-Headers');
|
||||
isValueExistsInElement(true, Cypress.env('redactBodyContent'), Cypress.env('bodyJsonClass'));
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import {isValueExistsInElement, verifyMinimumEntries} from "../testHelpers/TrafficHelper";
|
||||
import {isValueExistsInElement} from "../testHelpers/TrafficHelper";
|
||||
|
||||
it('Loading Mizu', function () {
|
||||
cy.visit(Cypress.env('testUrl'));
|
||||
});
|
||||
|
||||
verifyMinimumEntries();
|
||||
|
||||
isValueExistsInElement(true, Cypress.env('regexMaskingBodyContent'), Cypress.env('bodyJsonClass'));
|
||||
|
||||
@@ -64,6 +64,8 @@ it('right side sanity test', function () {
|
||||
});
|
||||
});
|
||||
|
||||
serviceMapCheck();
|
||||
|
||||
checkIllegalFilter('invalid filter');
|
||||
|
||||
checkFilter({
|
||||
@@ -188,7 +190,7 @@ function checkFilter(filterDetails){
|
||||
const entriesForDeeperCheck = 5;
|
||||
|
||||
it(`checking the filter: ${name}`, function () {
|
||||
cy.get('#total-entries').then(number => {
|
||||
cy.get('#total-entries').should('not.have.text', '0').then(number => {
|
||||
const totalEntries = number.text();
|
||||
|
||||
// checks the hover on the last entry (the only one in DOM at the beginning)
|
||||
@@ -320,3 +322,42 @@ function checkOnlyLineNumberes(jsonItems, decodedText) {
|
||||
cy.get(`${Cypress.env('bodyJsonClass')} >`).should('have.length', 1).and('have.text', decodedText);
|
||||
cy.get(`${Cypress.env('bodyJsonClass')} > >`).should('have.length', jsonItems)
|
||||
}
|
||||
|
||||
function serviceMapCheck() {
|
||||
it('service map test', function () {
|
||||
cy.intercept(`${Cypress.env('testUrl')}/servicemap/get`).as('serviceMapRequest');
|
||||
cy.get('#total-entries').should('not.have.text', '0').then(() => {
|
||||
cy.get('#total-entries').invoke('text').then(entriesNum => {
|
||||
cy.get('[alt="service-map"]').click();
|
||||
cy.wait('@serviceMapRequest').then(({response}) => {
|
||||
const body = response.body;
|
||||
const nodeParams = {
|
||||
destination: 'httpbin.mizu-tests',
|
||||
source: '127.0.0.1'
|
||||
};
|
||||
serviceMapAPICheck(body, parseInt(entriesNum), nodeParams);
|
||||
cy.reload();
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function serviceMapAPICheck(body, entriesNum, nodeParams) {
|
||||
const {nodes, edges} = body;
|
||||
|
||||
expect(nodes.length).to.equal(Object.keys(nodeParams).length, `Expected nodes count`);
|
||||
|
||||
expect(edges.some(edge => edge.source.name === nodeParams.source)).to.be.true;
|
||||
expect(edges.some(edge => edge.destination.name === nodeParams.destination)).to.be.true;
|
||||
|
||||
let count = 0;
|
||||
edges.forEach(edge => {
|
||||
count += edge.count;
|
||||
if (edge.destination.name === nodeParams.destination) {
|
||||
expect(edge.source.name).to.equal(nodeParams.source);
|
||||
}
|
||||
});
|
||||
|
||||
expect(count).to.equal(entriesNum);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
module github.com/up9inc/mizu/tests
|
||||
module github.com/up9inc/mizu/acceptanceTests
|
||||
|
||||
go 1.17
|
||||
|
||||
|
||||
@@ -62,7 +62,7 @@ func TestTap(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
runCypressTests(t, "npx cypress run --spec \"cypress/integration/tests/UiTest.js\"")
|
||||
runCypressTests(t, fmt.Sprintf("npx cypress run --spec \"cypress/integration/tests/UiTest.js\" --env entriesCount=%d", entriesCount))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
package cmd
|
||||
|
||||
import (
|
||||
"github.com/creasty/defaults"
|
||||
"github.com/spf13/cobra"
|
||||
"github.com/up9inc/mizu/cli/config/configStructs"
|
||||
"github.com/up9inc/mizu/cli/telemetry"
|
||||
"github.com/up9inc/mizu/shared/logger"
|
||||
)
|
||||
|
||||
var checkCmd = &cobra.Command{
|
||||
@@ -17,4 +20,11 @@ var checkCmd = &cobra.Command{
|
||||
|
||||
func init() {
|
||||
rootCmd.AddCommand(checkCmd)
|
||||
|
||||
defaultCheckConfig := configStructs.CheckConfig{}
|
||||
if err := defaults.Set(&defaultCheckConfig); err != nil {
|
||||
logger.Log.Debug(err)
|
||||
}
|
||||
|
||||
checkCmd.Flags().Bool(configStructs.PreTapCheckName, defaultCheckConfig.PreTap, "Check pre-tap Mizu installation for potential problems")
|
||||
}
|
||||
|
||||
@@ -2,7 +2,11 @@ package cmd
|
||||
|
||||
import (
|
||||
"context"
|
||||
"embed"
|
||||
"fmt"
|
||||
rbac "k8s.io/api/rbac/v1"
|
||||
"k8s.io/apimachinery/pkg/runtime"
|
||||
"k8s.io/client-go/kubernetes/scheme"
|
||||
"regexp"
|
||||
|
||||
"github.com/up9inc/mizu/cli/apiserver"
|
||||
@@ -13,8 +17,13 @@ import (
|
||||
"github.com/up9inc/mizu/shared/semver"
|
||||
)
|
||||
|
||||
var (
|
||||
//go:embed permissionFiles
|
||||
embedFS embed.FS
|
||||
)
|
||||
|
||||
func runMizuCheck() {
|
||||
logger.Log.Infof("Mizu install checks\n===================")
|
||||
logger.Log.Infof("Mizu checks\n===================")
|
||||
|
||||
ctx, cancel := context.WithCancel(context.Background())
|
||||
defer cancel() // cancel will be called when this function exits
|
||||
@@ -25,17 +34,18 @@ func runMizuCheck() {
|
||||
checkPassed = checkKubernetesVersion(kubernetesVersion)
|
||||
}
|
||||
|
||||
var isInstallCommand bool
|
||||
if checkPassed {
|
||||
checkPassed, isInstallCommand = checkMizuMode(ctx, kubernetesProvider)
|
||||
}
|
||||
if config.Config.Check.PreTap {
|
||||
if checkPassed {
|
||||
checkPassed = checkK8sTapPermissions(ctx, kubernetesProvider)
|
||||
}
|
||||
} else {
|
||||
if checkPassed {
|
||||
checkPassed = checkK8sResources(ctx, kubernetesProvider)
|
||||
}
|
||||
|
||||
if checkPassed {
|
||||
checkPassed = checkK8sResources(ctx, kubernetesProvider, isInstallCommand)
|
||||
}
|
||||
|
||||
if checkPassed {
|
||||
checkPassed = checkServerConnection(kubernetesProvider)
|
||||
if checkPassed {
|
||||
checkPassed = checkServerConnection(kubernetesProvider)
|
||||
}
|
||||
}
|
||||
|
||||
if checkPassed {
|
||||
@@ -65,27 +75,6 @@ func checkKubernetesApi() (*kubernetes.Provider, *semver.SemVersion, bool) {
|
||||
return kubernetesProvider, kubernetesVersion, true
|
||||
}
|
||||
|
||||
func checkMizuMode(ctx context.Context, kubernetesProvider *kubernetes.Provider) (bool, bool) {
|
||||
logger.Log.Infof("\nmode\n--------------------")
|
||||
|
||||
if exist, err := kubernetesProvider.DoesDeploymentExist(ctx, config.Config.MizuResourcesNamespace, kubernetes.ApiServerPodName); err != nil {
|
||||
logger.Log.Errorf("%v can't check mizu command, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), err)
|
||||
return false, false
|
||||
} else if exist {
|
||||
logger.Log.Infof("%v mizu running with install command", fmt.Sprintf(uiUtils.Green, "√"))
|
||||
return true, true
|
||||
} else if exist, err = kubernetesProvider.DoesPodExist(ctx, config.Config.MizuResourcesNamespace, kubernetes.ApiServerPodName); err != nil {
|
||||
logger.Log.Errorf("%v can't check mizu command, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), err)
|
||||
return false, false
|
||||
} else if exist {
|
||||
logger.Log.Infof("%v mizu running with tap command", fmt.Sprintf(uiUtils.Green, "√"))
|
||||
return true, false
|
||||
} else {
|
||||
logger.Log.Infof("%v mizu is not running", fmt.Sprintf(uiUtils.Red, "✗"))
|
||||
return false, false
|
||||
}
|
||||
}
|
||||
|
||||
func checkKubernetesVersion(kubernetesVersion *semver.SemVersion) bool {
|
||||
logger.Log.Infof("\nkubernetes-version\n--------------------")
|
||||
|
||||
@@ -169,7 +158,7 @@ func checkPortForward(serverUrl string, kubernetesProvider *kubernetes.Provider)
|
||||
return nil
|
||||
}
|
||||
|
||||
func checkK8sResources(ctx context.Context, kubernetesProvider *kubernetes.Provider, isInstallCommand bool) bool {
|
||||
func checkK8sResources(ctx context.Context, kubernetesProvider *kubernetes.Provider) bool {
|
||||
logger.Log.Infof("\nk8s-components\n--------------------")
|
||||
|
||||
exist, err := kubernetesProvider.DoesNamespaceExist(ctx, config.Config.MizuResourcesNamespace)
|
||||
@@ -198,52 +187,27 @@ func checkK8sResources(ctx context.Context, kubernetesProvider *kubernetes.Provi
|
||||
exist, err = kubernetesProvider.DoesServiceExist(ctx, config.Config.MizuResourcesNamespace, kubernetes.ApiServerPodName)
|
||||
allResourcesExist = checkResourceExist(kubernetes.ApiServerPodName, "service", exist, err) && allResourcesExist
|
||||
|
||||
if isInstallCommand {
|
||||
allResourcesExist = checkInstallResourcesExist(ctx, kubernetesProvider) && allResourcesExist
|
||||
} else {
|
||||
allResourcesExist = checkTapResourcesExist(ctx, kubernetesProvider) && allResourcesExist
|
||||
}
|
||||
allResourcesExist = checkPodResourcesExist(ctx, kubernetesProvider) && allResourcesExist
|
||||
|
||||
return allResourcesExist
|
||||
}
|
||||
|
||||
func checkInstallResourcesExist(ctx context.Context, kubernetesProvider *kubernetes.Provider) bool {
|
||||
exist, err := kubernetesProvider.DoesRoleExist(ctx, config.Config.MizuResourcesNamespace, kubernetes.DaemonRoleName)
|
||||
installResourcesExist := checkResourceExist(kubernetes.DaemonRoleName, "role", exist, err)
|
||||
|
||||
exist, err = kubernetesProvider.DoesRoleBindingExist(ctx, config.Config.MizuResourcesNamespace, kubernetes.DaemonRoleBindingName)
|
||||
installResourcesExist = checkResourceExist(kubernetes.DaemonRoleBindingName, "role binding", exist, err) && installResourcesExist
|
||||
|
||||
exist, err = kubernetesProvider.DoesPersistentVolumeClaimExist(ctx, config.Config.MizuResourcesNamespace, kubernetes.PersistentVolumeClaimName)
|
||||
installResourcesExist = checkResourceExist(kubernetes.PersistentVolumeClaimName, "persistent volume claim", exist, err) && installResourcesExist
|
||||
|
||||
exist, err = kubernetesProvider.DoesDeploymentExist(ctx, config.Config.MizuResourcesNamespace, kubernetes.ApiServerPodName)
|
||||
installResourcesExist = checkResourceExist(kubernetes.ApiServerPodName, "deployment", exist, err) && installResourcesExist
|
||||
|
||||
return installResourcesExist
|
||||
}
|
||||
|
||||
func checkTapResourcesExist(ctx context.Context, kubernetesProvider *kubernetes.Provider) bool {
|
||||
exist, err := kubernetesProvider.DoesPodExist(ctx, config.Config.MizuResourcesNamespace, kubernetes.ApiServerPodName)
|
||||
tapResourcesExist := checkResourceExist(kubernetes.ApiServerPodName, "pod", exist, err)
|
||||
|
||||
if !tapResourcesExist {
|
||||
func checkPodResourcesExist(ctx context.Context, kubernetesProvider *kubernetes.Provider) bool {
|
||||
if pods, err := kubernetesProvider.ListPodsByAppLabel(ctx, config.Config.MizuResourcesNamespace, kubernetes.ApiServerPodName); err != nil {
|
||||
logger.Log.Errorf("%v error checking if '%v' pod is running, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), kubernetes.ApiServerPodName, err)
|
||||
return false
|
||||
}
|
||||
|
||||
if pod, err := kubernetesProvider.GetPod(ctx, config.Config.MizuResourcesNamespace, kubernetes.ApiServerPodName); err != nil {
|
||||
logger.Log.Errorf("%v error checking if '%v' pod exists, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), kubernetes.ApiServerPodName, err)
|
||||
} else if len(pods) == 0 {
|
||||
logger.Log.Errorf("%v '%v' pod doesn't exist", fmt.Sprintf(uiUtils.Red, "✗"), kubernetes.ApiServerPodName)
|
||||
return false
|
||||
} else if kubernetes.IsPodRunning(pod) {
|
||||
logger.Log.Infof("%v '%v' pod running", fmt.Sprintf(uiUtils.Green, "√"), kubernetes.ApiServerPodName)
|
||||
} else {
|
||||
} else if !kubernetes.IsPodRunning(&pods[0]) {
|
||||
logger.Log.Errorf("%v '%v' pod not running", fmt.Sprintf(uiUtils.Red, "✗"), kubernetes.ApiServerPodName)
|
||||
return false
|
||||
}
|
||||
|
||||
tapperRegex := regexp.MustCompile(fmt.Sprintf("^%s.*", kubernetes.TapperPodName))
|
||||
if pods, err := kubernetesProvider.ListAllPodsMatchingRegex(ctx, tapperRegex, []string{config.Config.MizuResourcesNamespace}); err != nil {
|
||||
logger.Log.Errorf("%v error listing '%v' pods, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), kubernetes.TapperPodName, err)
|
||||
logger.Log.Infof("%v '%v' pod running", fmt.Sprintf(uiUtils.Green, "√"), kubernetes.ApiServerPodName)
|
||||
|
||||
if pods, err := kubernetesProvider.ListPodsByAppLabel(ctx, config.Config.MizuResourcesNamespace, kubernetes.TapperPodName); err != nil {
|
||||
logger.Log.Errorf("%v error checking if '%v' pods are running, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), kubernetes.TapperPodName, err)
|
||||
return false
|
||||
} else {
|
||||
tappers := 0
|
||||
@@ -273,9 +237,81 @@ func checkResourceExist(resourceName string, resourceType string, exist bool, er
|
||||
} else if !exist {
|
||||
logger.Log.Errorf("%v '%v' %v doesn't exist", fmt.Sprintf(uiUtils.Red, "✗"), resourceName, resourceType)
|
||||
return false
|
||||
} else {
|
||||
logger.Log.Infof("%v '%v' %v exists", fmt.Sprintf(uiUtils.Green, "√"), resourceName, resourceType)
|
||||
}
|
||||
|
||||
logger.Log.Infof("%v '%v' %v exists", fmt.Sprintf(uiUtils.Green, "√"), resourceName, resourceType)
|
||||
return true
|
||||
}
|
||||
|
||||
func checkK8sTapPermissions(ctx context.Context, kubernetesProvider *kubernetes.Provider) bool {
|
||||
logger.Log.Infof("\nkubernetes-permissions\n--------------------")
|
||||
|
||||
var filePath string
|
||||
if config.Config.IsNsRestrictedMode() {
|
||||
filePath = "permissionFiles/permissions-ns-tap.yaml"
|
||||
} else {
|
||||
filePath = "permissionFiles/permissions-all-namespaces-tap.yaml"
|
||||
}
|
||||
|
||||
data, err := embedFS.ReadFile(filePath)
|
||||
if err != nil {
|
||||
logger.Log.Errorf("%v error while checking kubernetes permissions, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), err)
|
||||
return false
|
||||
}
|
||||
|
||||
obj, err := getDecodedObject(data)
|
||||
if err != nil {
|
||||
logger.Log.Errorf("%v error while checking kubernetes permissions, err: %v", fmt.Sprintf(uiUtils.Red, "✗"), err)
|
||||
return false
|
||||
}
|
||||
|
||||
var rules []rbac.PolicyRule
|
||||
if config.Config.IsNsRestrictedMode() {
|
||||
rules = obj.(*rbac.Role).Rules
|
||||
} else {
|
||||
rules = obj.(*rbac.ClusterRole).Rules
|
||||
}
|
||||
|
||||
return checkPermissions(ctx, kubernetesProvider, rules)
|
||||
}
|
||||
|
||||
func getDecodedObject(data []byte) (runtime.Object, error) {
|
||||
decode := scheme.Codecs.UniversalDeserializer().Decode
|
||||
|
||||
obj, _, err := decode(data, nil, nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return obj, nil
|
||||
}
|
||||
|
||||
func checkPermissions(ctx context.Context, kubernetesProvider *kubernetes.Provider, rules []rbac.PolicyRule) bool {
|
||||
permissionsExist := true
|
||||
|
||||
for _, rule := range rules {
|
||||
for _, group := range rule.APIGroups {
|
||||
for _, resource := range rule.Resources {
|
||||
for _, verb := range rule.Verbs {
|
||||
exist, err := kubernetesProvider.CanI(ctx, config.Config.MizuResourcesNamespace, resource, verb, group)
|
||||
permissionsExist = checkPermissionExist(group, resource, verb, exist, err) && permissionsExist
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return permissionsExist
|
||||
}
|
||||
|
||||
func checkPermissionExist(group string, resource string, verb string, exist bool, err error) bool {
|
||||
if err != nil {
|
||||
logger.Log.Errorf("%v error checking permission for %v %v in group '%v', err: %v", fmt.Sprintf(uiUtils.Red, "✗"), verb, resource, group, err)
|
||||
return false
|
||||
} else if !exist {
|
||||
logger.Log.Errorf("%v can't %v %v in group '%v'", fmt.Sprintf(uiUtils.Red, "✗"), verb, resource, group)
|
||||
return false
|
||||
}
|
||||
|
||||
logger.Log.Infof("%v can %v %v in group '%v'", fmt.Sprintf(uiUtils.Green, "√"), verb, resource, group)
|
||||
return true
|
||||
}
|
||||
|
||||
@@ -14,10 +14,10 @@ var installCmd = &cobra.Command{
|
||||
logger.Log.Infof("This command has been deprecated, please use helm as described below.\n\n")
|
||||
|
||||
logger.Log.Infof("To install stable build of Mizu on your cluster using helm, run the following command:")
|
||||
logger.Log.Infof(" helm install mizu mizu --repo https://static.up9.com/mizu/helm --namespace=mizu --create-namespace\n\n")
|
||||
logger.Log.Infof(" helm install mizu up9mizu --repo https://static.up9.com/mizu/helm --namespace=mizu --create-namespace\n\n")
|
||||
|
||||
logger.Log.Infof("To install development build of Mizu on your cluster using helm, run the following command:")
|
||||
logger.Log.Infof(" helm install mizu mizu --repo https://static.up9.com/mizu/helm-develop --namespace=mizu --create-namespace\n")
|
||||
logger.Log.Infof(" helm install mizu up9mizu --repo https://static.up9.com/mizu/helm-develop --namespace=mizu --create-namespace\n")
|
||||
|
||||
return nil
|
||||
},
|
||||
|
||||
@@ -22,6 +22,7 @@ const (
|
||||
|
||||
type ConfigStruct struct {
|
||||
Tap configStructs.TapConfig `yaml:"tap"`
|
||||
Check configStructs.CheckConfig `yaml:"check"`
|
||||
Version configStructs.VersionConfig `yaml:"version"`
|
||||
View configStructs.ViewConfig `yaml:"view"`
|
||||
Logs configStructs.LogsConfig `yaml:"logs"`
|
||||
|
||||
9
cli/config/configStructs/checkConfig.go
Normal file
9
cli/config/configStructs/checkConfig.go
Normal file
@@ -0,0 +1,9 @@
|
||||
package configStructs
|
||||
|
||||
const (
|
||||
PreTapCheckName = "pre-tap"
|
||||
)
|
||||
|
||||
type CheckConfig struct {
|
||||
PreTap bool `yaml:"pre-tap"`
|
||||
}
|
||||
@@ -85,4 +85,4 @@ By default Mizu requires cluster-wide permissions.
|
||||
If these are not available to the user, it is possible to run Mizu in namespace-restricted mode which has a reduced set of requirements.
|
||||
This is done by by setting the `mizu-resources-namespace` config option. See [configuration](CONFIGURATION.md) for instructions.
|
||||
|
||||
The different requirements are listed in [the example roles dir](../examples/roles)
|
||||
The different requirements are listed in [the permission templates dir](../cli/cmd/permissionFiles)
|
||||
|
||||
@@ -17,6 +17,7 @@ import (
|
||||
"github.com/up9inc/mizu/shared/semver"
|
||||
"github.com/up9inc/mizu/tap/api"
|
||||
v1 "k8s.io/api/apps/v1"
|
||||
auth "k8s.io/api/authorization/v1"
|
||||
core "k8s.io/api/core/v1"
|
||||
rbac "k8s.io/api/rbac/v1"
|
||||
k8serrors "k8s.io/apimachinery/pkg/api/errors"
|
||||
@@ -443,6 +444,26 @@ func (provider *Provider) CreateService(ctx context.Context, namespace string, s
|
||||
return provider.clientSet.CoreV1().Services(namespace).Create(ctx, &service, metav1.CreateOptions{})
|
||||
}
|
||||
|
||||
func (provider *Provider) CanI(ctx context.Context, namespace string, resource string, verb string, group string) (bool, error) {
|
||||
selfSubjectAccessReview := &auth.SelfSubjectAccessReview{
|
||||
Spec: auth.SelfSubjectAccessReviewSpec{
|
||||
ResourceAttributes: &auth.ResourceAttributes{
|
||||
Namespace: namespace,
|
||||
Resource: resource,
|
||||
Verb: verb,
|
||||
Group: group,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
response, err := provider.clientSet.AuthorizationV1().SelfSubjectAccessReviews().Create(ctx, selfSubjectAccessReview, metav1.CreateOptions{})
|
||||
if err != nil {
|
||||
return false, err
|
||||
}
|
||||
|
||||
return response.Status.Allowed, nil
|
||||
}
|
||||
|
||||
func (provider *Provider) DoesNamespaceExist(ctx context.Context, name string) (bool, error) {
|
||||
namespaceResource, err := provider.clientSet.CoreV1().Namespaces().Get(ctx, name, metav1.GetOptions{})
|
||||
return provider.doesResourceExist(namespaceResource, err)
|
||||
@@ -468,11 +489,6 @@ func (provider *Provider) DoesDeploymentExist(ctx context.Context, namespace str
|
||||
return provider.doesResourceExist(deploymentResource, err)
|
||||
}
|
||||
|
||||
func (provider *Provider) DoesPodExist(ctx context.Context, namespace string, name string) (bool, error) {
|
||||
podResource, err := provider.clientSet.CoreV1().Pods(namespace).Get(ctx, name, metav1.GetOptions{})
|
||||
return provider.doesResourceExist(podResource, err)
|
||||
}
|
||||
|
||||
func (provider *Provider) DoesServiceExist(ctx context.Context, namespace string, name string) (bool, error) {
|
||||
serviceResource, err := provider.clientSet.CoreV1().Services(namespace).Get(ctx, name, metav1.GetOptions{})
|
||||
return provider.doesResourceExist(serviceResource, err)
|
||||
@@ -829,7 +845,7 @@ func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespac
|
||||
if tls {
|
||||
mizuCmd = append(mizuCmd, "--tls")
|
||||
}
|
||||
|
||||
|
||||
if serviceMesh || tls {
|
||||
mizuCmd = append(mizuCmd, "--procfs", procfsMountPath)
|
||||
}
|
||||
@@ -939,24 +955,6 @@ func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespac
|
||||
sysfsVolumeMount := applyconfcore.VolumeMount().WithName(sysfsVolumeName).WithMountPath(sysfsMountPath).WithReadOnly(true)
|
||||
agentContainer.WithVolumeMounts(sysfsVolumeMount)
|
||||
|
||||
volumeName := ConfigMapName
|
||||
configMapVolume := applyconfcore.VolumeApplyConfiguration{
|
||||
Name: &volumeName,
|
||||
VolumeSourceApplyConfiguration: applyconfcore.VolumeSourceApplyConfiguration{
|
||||
ConfigMap: &applyconfcore.ConfigMapVolumeSourceApplyConfiguration{
|
||||
LocalObjectReferenceApplyConfiguration: applyconfcore.LocalObjectReferenceApplyConfiguration{
|
||||
Name: &volumeName,
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
mountPath := shared.ConfigDirPath
|
||||
configMapVolumeMount := applyconfcore.VolumeMountApplyConfiguration{
|
||||
Name: &volumeName,
|
||||
MountPath: &mountPath,
|
||||
}
|
||||
agentContainer.WithVolumeMounts(&configMapVolumeMount)
|
||||
|
||||
podSpec := applyconfcore.PodSpec()
|
||||
podSpec.WithHostNetwork(true)
|
||||
podSpec.WithDNSPolicy(core.DNSClusterFirstWithHostNet)
|
||||
@@ -967,7 +965,7 @@ func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespac
|
||||
podSpec.WithContainers(agentContainer)
|
||||
podSpec.WithAffinity(affinity)
|
||||
podSpec.WithTolerations(noExecuteToleration, noScheduleToleration)
|
||||
podSpec.WithVolumes(&configMapVolume, procfsVolume, sysfsVolume)
|
||||
podSpec.WithVolumes(procfsVolume, sysfsVolume)
|
||||
|
||||
podTemplate := applyconfcore.PodTemplateSpec()
|
||||
podTemplate.WithLabels(map[string]string{
|
||||
@@ -981,7 +979,7 @@ func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespac
|
||||
labelSelector.WithMatchLabels(map[string]string{"app": tapperPodName})
|
||||
|
||||
applyOptions := metav1.ApplyOptions{
|
||||
Force: true,
|
||||
Force: true,
|
||||
FieldManager: fieldManagerName,
|
||||
}
|
||||
|
||||
@@ -1040,6 +1038,15 @@ func (provider *Provider) ListAllRunningPodsMatchingRegex(ctx context.Context, r
|
||||
return matchingPods, nil
|
||||
}
|
||||
|
||||
func(provider *Provider) ListPodsByAppLabel(ctx context.Context, namespaces string, labelName string) ([]core.Pod, error) {
|
||||
pods, err := provider.clientSet.CoreV1().Pods(namespaces).List(ctx, metav1.ListOptions{LabelSelector: fmt.Sprintf("app=%s", labelName)})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return pods.Items, err
|
||||
}
|
||||
|
||||
func (provider *Provider) ListAllNamespaces(ctx context.Context) ([]core.Namespace, error) {
|
||||
namespaces, err := provider.clientSet.CoreV1().Namespaces().List(ctx, metav1.ListOptions{})
|
||||
if err != nil {
|
||||
|
||||
@@ -8,6 +8,7 @@ import {toast} from "react-toastify";
|
||||
import {useRecoilValue} from "recoil";
|
||||
import focusedEntryIdAtom from "../recoil/focusedEntryId";
|
||||
import Api from "../helpers/api";
|
||||
import queryAtom from "../recoil/query";
|
||||
|
||||
const useStyles = makeStyles(() => ({
|
||||
entryTitle: {
|
||||
@@ -82,6 +83,7 @@ const api = Api.getInstance();
|
||||
export const EntryDetailed = () => {
|
||||
|
||||
const focusedEntryId = useRecoilValue(focusedEntryIdAtom);
|
||||
const query = useRecoilValue(queryAtom);
|
||||
const [entryData, setEntryData] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
@@ -89,7 +91,7 @@ export const EntryDetailed = () => {
|
||||
setEntryData(null);
|
||||
(async () => {
|
||||
try {
|
||||
const entryData = await api.getEntry(focusedEntryId);
|
||||
const entryData = await api.getEntry(focusedEntryId, query);
|
||||
setEntryData(entryData);
|
||||
} catch (error) {
|
||||
if (error.response?.data?.type) {
|
||||
|
||||
Reference in New Issue
Block a user