Compare commits

...

24 Commits

Author SHA1 Message Date
RoyUP9
d8c0132a98 Fixed location of pre tap permission files (#852) 2022-02-24 16:46:51 +02:00
RoyUP9
c5a36a494a Removed install check (#851)
* Removed install check

* Update cli/cmd/checkRunner.go

Co-authored-by: Igor Gov <iggvrv@gmail.com>

* no message

Co-authored-by: Igor Gov <iggvrv@gmail.com>
2022-02-24 16:08:36 +02:00
Adam Kol
a54cb917d0 Cypress: minimum entries check (#850) 2022-02-24 15:55:30 +02:00
RoyUP9
30a85a4b92 Added tap pre check (#848) 2022-02-24 11:48:42 +02:00
Adam Kol
cdbacff996 Cypress: Service Map test (#847) 2022-02-23 17:36:31 +02:00
RamiBerm
cf127c781c Dont mount config map on tappers (#849) 2022-02-23 14:40:47 +02:00
M. Mert Yıldıran
852a5ff045 Bring back the query argument of getEntry call which is accidentally removed with #631 (#842) 2022-02-23 13:29:47 +03:00
Igor Gov
371e513249 Remove config dependency from basenine init (#846)
* Remove config dependency from basenine init
2022-02-23 10:06:19 +02:00
Igor Gov
97cce32e3f Fix: service map component aware of agent config (#845)
* Fix: Service map component aware of mizu config
2022-02-23 09:35:05 +02:00
Igor Gov
d2e91b4ffa Fix: tapper tries to load agent config map (#844) 2022-02-23 09:20:19 +02:00
Alex Haiut
d5a42a66de apply install typo fix to develop (already in master) (#840)
Co-authored-by: gadotroee <55343099+gadotroee@users.noreply.github.com>
2022-02-22 16:02:33 +02:00
RoyUP9
f01962085a Return amqp tests (#841) 2022-02-22 15:35:20 +02:00
M. Mert Yıldıran
73f3e448cf Fix the issue in the WebSocket that's introduced by #819 (#839) 2022-02-22 15:27:50 +03:00
Igor Gov
58a17897cf Agent logs: output to stderr errors and above (#838)
* Agent logs: output to stderr errors and above
2022-02-22 14:02:51 +02:00
M. Mert Yıldıran
cf3106f636 Silence the logging that comes from Basenine and protocol dissectors (#835) 2022-02-21 18:08:16 +03:00
Andrey Pokhilko
a553a1b683 OAS: use resolved service names (#827)
* OAS service names to be resolved

* fix test
2022-02-21 17:20:59 +03:00
Igor Gov
2a6bbd66e6 Update relase template for Mac M1 executable (#836)
* Update release template for Mac M1
2022-02-21 13:32:48 +02:00
Adam Kol
5a4baa05ca rabbit test is skipped temporarily (#833) 2022-02-20 18:10:00 +02:00
Nimrod Gilboa Markevich
4ec9b9b475 Remove permissions examples for deprecated install process (#832)
* Remove examples related to the install cmd

* Remove install cmd references from docs/PERMISSIONS.md
2022-02-20 14:22:57 +02:00
Nimrod Gilboa Markevich
1e2288b9a8 Update permission examples (#824)
Reorganize permissions example.
Permissions for optional features are separated from those that are mandatory.
Revised the list of permissions. Added and removed features to make it fit what Mizu currently requires.
2022-02-20 13:16:15 +02:00
Adam Kol
74f58a88bf no minimum entries check (#826)
Co-authored-by: gadotroee <55343099+gadotroee@users.noreply.github.com>
2022-02-19 20:03:23 +02:00
M. Mert Yıldıran
69ee8752d0 Create and push the latest tag if the branch is main (stable) (#831)
* Fix the styling issue in the badges

* Create and push the `latest` tag if the branch is `main` (stable)

* Build the for `latest` tag as well
2022-02-19 18:09:18 +03:00
M. Mert Yıldıran
27fa0afb72 TRA-4331 Implement full data streaming over WebSocket (#819)
* Implement full data streaming over WebSocket

* Fix the linting error

* Make the empty being the criteria

* Use a label to break the nested loop
2022-02-17 17:01:44 +03:00
Adam Kol
c98c99e488 Cypress fix: resizing mizu when needed (#821) 2022-02-17 13:19:44 +02:00
55 changed files with 490 additions and 849 deletions

View File

@@ -58,6 +58,7 @@ jobs:
up9inc/mizu up9inc/mizu
tags: | tags: |
type=raw,${{ steps.versioning.outputs.version }} type=raw,${{ steps.versioning.outputs.version }}
type=raw,value=latest,enable=${{ steps.condval.outputs.value == 'stable' }}
flavor: | flavor: |
latest=auto latest=auto
prefix= prefix=
@@ -143,6 +144,7 @@ jobs:
${{ steps.base_image_step.outputs.image }} ${{ steps.base_image_step.outputs.image }}
tags: | tags: |
type=raw,${{ steps.versioning.outputs.version }} type=raw,${{ steps.versioning.outputs.version }}
type=raw,value=latest,enable=${{ steps.condval.outputs.value == 'stable' }}
flavor: | flavor: |
latest=auto latest=auto
prefix= prefix=
@@ -205,6 +207,7 @@ jobs:
up9inc/mizu up9inc/mizu
tags: | tags: |
type=raw,${{ steps.versioning.outputs.version }} type=raw,${{ steps.versioning.outputs.version }}
type=raw,value=latest,enable=${{ steps.condval.outputs.value == 'stable' }}
- name: Login to Docker Hub - name: Login to Docker Hub
uses: docker/login-action@v1 uses: docker/login-action@v1

View File

@@ -78,8 +78,8 @@ RUN go build -ldflags="-extldflags=-static -s -w \
-X 'github.com/up9inc/mizu/agent/pkg/version.Ver=${VER}'" -o mizuagent . -X 'github.com/up9inc/mizu/agent/pkg/version.Ver=${VER}'" -o mizuagent .
# Download Basenine executable, verify the sha1sum # Download Basenine executable, verify the sha1sum
ADD https://github.com/up9inc/basenine/releases/download/v0.4.16/basenine_linux_${GOARCH} ./basenine_linux_${GOARCH} ADD https://github.com/up9inc/basenine/releases/download/v0.4.17/basenine_linux_${GOARCH} ./basenine_linux_${GOARCH}
ADD https://github.com/up9inc/basenine/releases/download/v0.4.16/basenine_linux_${GOARCH}.sha256 ./basenine_linux_${GOARCH}.sha256 ADD https://github.com/up9inc/basenine/releases/download/v0.4.17/basenine_linux_${GOARCH}.sha256 ./basenine_linux_${GOARCH}.sha256
RUN shasum -a 256 -c basenine_linux_${GOARCH}.sha256 RUN shasum -a 256 -c basenine_linux_${GOARCH}.sha256
RUN chmod +x ./basenine_linux_${GOARCH} RUN chmod +x ./basenine_linux_${GOARCH}
RUN mv ./basenine_linux_${GOARCH} ./basenine RUN mv ./basenine_linux_${GOARCH} ./basenine

View File

@@ -8,10 +8,10 @@
<img alt="GitHub Latest Release" src="https://img.shields.io/github/v/release/up9inc/mizu?logo=GitHub&style=flat-square"> <img alt="GitHub Latest Release" src="https://img.shields.io/github/v/release/up9inc/mizu?logo=GitHub&style=flat-square">
</a> </a>
<a href="https://hub.docker.com/r/up9inc/mizu"> <a href="https://hub.docker.com/r/up9inc/mizu">
<img alt="Docker pulls" src="https://img.shields.io/docker/pulls/up9inc/mizu?color=%23099cec"> <img alt="Docker pulls" src="https://img.shields.io/docker/pulls/up9inc/mizu?color=%23099cec&logo=Docker&style=flat-square">
</a> </a>
<a href="https://hub.docker.com/r/up9inc/mizu"> <a href="https://hub.docker.com/r/up9inc/mizu">
<img alt="Image size" src="https://img.shields.io/docker/image-size/up9inc/mizu/latest"> <img alt="Image size" src="https://img.shields.io/docker/image-size/up9inc/mizu/latest?logo=Docker&style=flat-square">
</a> </a>
<a href="https://join.slack.com/t/up9/shared_invite/zt-tfjnduli-QzlR8VV4Z1w3YnPIAJfhlQ"> <a href="https://join.slack.com/t/up9/shared_invite/zt-tfjnduli-QzlR8VV4Z1w3YnPIAJfhlQ">
<img alt="Slack" src="https://img.shields.io/badge/slack-join_chat-white.svg?logo=slack&style=social"> <img alt="Slack" src="https://img.shields.io/badge/slack-join_chat-white.svg?logo=slack&style=social">

View File

@@ -15,7 +15,8 @@
"tests/IgnoredUserAgents.js", "tests/IgnoredUserAgents.js",
"tests/UiTest.js", "tests/UiTest.js",
"tests/Redis.js", "tests/Redis.js",
"tests/Rabbit.js" "tests/Rabbit.js",
"tests/serviceMapFunction.js"
], ],
"env": { "env": {
@@ -23,9 +24,11 @@
"redactHeaderContent": "User-Header[REDACTED]", "redactHeaderContent": "User-Header[REDACTED]",
"redactBodyContent": "{ \"User\": \"[REDACTED]\" }", "redactBodyContent": "{ \"User\": \"[REDACTED]\" }",
"regexMaskingBodyContent": "[REDACTED]", "regexMaskingBodyContent": "[REDACTED]",
"minimumEntries": 25,
"greenFilterColor": "rgb(210, 250, 210)", "greenFilterColor": "rgb(210, 250, 210)",
"redFilterColor": "rgb(250, 214, 220)", "redFilterColor": "rgb(250, 214, 220)",
"bodyJsonClass": ".hljs" "bodyJsonClass": ".hljs",
"mizuWidth": 1920,
"normalMizuHeight": 1080,
"hugeMizuHeight": 3500
} }
} }

View File

@@ -4,6 +4,8 @@ export const valueTabs = {
none: null none: null
} }
const maxEntriesInDom = 13;
export function isValueExistsInElement(shouldInclude, content, domPathToContainer){ export function isValueExistsInElement(shouldInclude, content, domPathToContainer){
it(`should ${shouldInclude ? '' : 'not'} include '${content}'`, function () { it(`should ${shouldInclude ? '' : 'not'} include '${content}'`, function () {
cy.get(domPathToContainer).then(htmlText => { cy.get(domPathToContainer).then(htmlText => {
@@ -15,22 +17,24 @@ export function isValueExistsInElement(shouldInclude, content, domPathToContaine
} }
export function resizeToHugeMizu() { export function resizeToHugeMizu() {
cy.viewport(1920, 3500); cy.viewport(Cypress.env('mizuWidth'), Cypress.env('hugeMizuHeight'));
} }
export function resizeToNormalMizu() { export function resizeToNormalMizu() {
cy.viewport(1920, 1080); cy.viewport(Cypress.env('mizuWidth'), Cypress.env('normalMizuHeight'));
} }
export function verifyMinimumEntries() { export function verifyMinimumEntries() {
const minimumEntries = Cypress.env('minimumEntries'); const entriesSent = Cypress.env('entriesCount');
it(`Making sure that mizu shows at least ${minimumEntries} entries`, async function () { const minimumEntries = Math.round((0.75 * entriesSent));
it(`Making sure that mizu shows at least ${minimumEntries} entries`, function () {
cy.get('#total-entries').then(number => { cy.get('#total-entries').then(number => {
const getNum = () => { const getNum = () => {
const numOfEntries = number.text(); return parseInt(number.text());
return parseInt(numOfEntries);
}; };
cy.wrap({there: getNum}).invoke('there').should('be.gte', minimumEntries);
cy.wrap({num: getNum}).invoke('num').should('be.gt', minimumEntries);
}); });
}); });
} }
@@ -61,7 +65,7 @@ export function checkThatAllEntriesShown() {
} }
export function checkFilterByMethod(funcDict) { export function checkFilterByMethod(funcDict) {
const {protocol, method, summary} = funcDict; const {protocol, method, summary, hugeMizu} = funcDict;
const summaryDict = getSummeryDict(summary); const summaryDict = getSummeryDict(summary);
const methodDict = getMethodDict(method); const methodDict = getMethodDict(method);
const protocolDict = getProtocolDict(protocol.name, protocol.text); const protocolDict = getProtocolDict(protocol.name, protocol.text);
@@ -82,20 +86,24 @@ export function checkFilterByMethod(funcDict) {
const listElmWithIdAttr = Object.values(elements); const listElmWithIdAttr = Object.values(elements);
let doneCheckOnFirst = false; let doneCheckOnFirst = false;
listElmWithIdAttr.forEach(entry => { cy.get('#entries-length').invoke('text').then(len => {
if (entry?.id && entry.id.match(RegExp(/entry-(\d{2}|\d{1})$/gm))) { resizeIfNeeded(len);
const entryNum = getEntryNumById(entry.id); listElmWithIdAttr.forEach(entry => {
if (entry?.id && entry.id.match(RegExp(/entry-(\d{2}|\d{1})$/gm))) {
const entryNum = getEntryNumById(entry.id);
leftTextCheck(entryNum, methodDict.pathLeft, methodDict.expectedText); leftTextCheck(entryNum, methodDict.pathLeft, methodDict.expectedText);
leftTextCheck(entryNum, protocolDict.pathLeft, protocolDict.expectedTextLeft); leftTextCheck(entryNum, protocolDict.pathLeft, protocolDict.expectedTextLeft);
if (summaryDict) if (summaryDict)
leftTextCheck(entryNum, summaryDict.pathLeft, summaryDict.expectedText); leftTextCheck(entryNum, summaryDict.pathLeft, summaryDict.expectedText);
if (!doneCheckOnFirst) { if (!doneCheckOnFirst) {
deepCheck(funcDict, protocolDict, methodDict, entry); deepCheck(funcDict, protocolDict, methodDict, entry);
doneCheckOnFirst = true; doneCheckOnFirst = true;
}
} }
} });
resizeIfNeeded(len);
}); });
}); });
}); });
@@ -103,6 +111,13 @@ export function checkFilterByMethod(funcDict) {
}); });
} }
function resizeIfNeeded(entriesLen) {
if (entriesLen > maxEntriesInDom){
Cypress.config().viewportHeight === Cypress.env('normalMizuHeight') ?
resizeToHugeMizu() : resizeToNormalMizu()
}
}
function deepCheck(generalDict, protocolDict, methodDict, entry) { function deepCheck(generalDict, protocolDict, methodDict, entry) {
const entryNum = getEntryNumById(entry.id); const entryNum = getEntryNumById(entry.id);
const {summary, value} = generalDict; const {summary, value} = generalDict;

View File

@@ -1,5 +1,4 @@
import {findLineAndCheck, getExpectedDetailsDict} from "../testHelpers/StatusBarHelper"; import {findLineAndCheck, getExpectedDetailsDict} from "../testHelpers/StatusBarHelper";
import {verifyMinimumEntries} from "../testHelpers/TrafficHelper";
it('check', function () { it('check', function () {
const podName = Cypress.env('name'), namespace = Cypress.env('namespace'); const podName = Cypress.env('name'), namespace = Cypress.env('namespace');
@@ -9,8 +8,6 @@ it('check', function () {
cy.visit(`http://localhost:${port}`); cy.visit(`http://localhost:${port}`);
cy.wait('@statusTap').its('response.statusCode').should('match', /^2\d{2}/); cy.wait('@statusTap').its('response.statusCode').should('match', /^2\d{2}/);
verifyMinimumEntries();
cy.get('.podsCount').trigger('mouseover'); cy.get('.podsCount').trigger('mouseover');
findLineAndCheck(getExpectedDetailsDict(podName, namespace)); findLineAndCheck(getExpectedDetailsDict(podName, namespace));
}); });

View File

@@ -2,15 +2,12 @@ import {
checkThatAllEntriesShown, checkThatAllEntriesShown,
isValueExistsInElement, isValueExistsInElement,
resizeToHugeMizu, resizeToHugeMizu,
verifyMinimumEntries
} from "../testHelpers/TrafficHelper"; } from "../testHelpers/TrafficHelper";
it('Loading Mizu', function () { it('Loading Mizu', function () {
cy.visit(Cypress.env('testUrl')); cy.visit(Cypress.env('testUrl'));
}); });
verifyMinimumEntries();
checkEntries(); checkEntries();
function checkEntries() { function checkEntries() {

View File

@@ -1,10 +1,8 @@
import {isValueExistsInElement, verifyMinimumEntries} from '../testHelpers/TrafficHelper'; import {isValueExistsInElement} from '../testHelpers/TrafficHelper';
it('Loading Mizu', function () { it('Loading Mizu', function () {
cy.visit(Cypress.env('testUrl')); cy.visit(Cypress.env('testUrl'));
}); });
verifyMinimumEntries();
isValueExistsInElement(false, Cypress.env('redactHeaderContent'), '#tbody-Headers'); isValueExistsInElement(false, Cypress.env('redactHeaderContent'), '#tbody-Headers');
isValueExistsInElement(false, Cypress.env('redactBodyContent'), Cypress.env('bodyJsonClass')); isValueExistsInElement(false, Cypress.env('redactBodyContent'), Cypress.env('bodyJsonClass'));

View File

@@ -1,6 +1,5 @@
import {checkFilterByMethod, valueTabs,} from "../testHelpers/TrafficHelper"; import {checkFilterByMethod, valueTabs,} from "../testHelpers/TrafficHelper";
it('opening mizu', function () { it('opening mizu', function () {
cy.visit(Cypress.env('testUrl')); cy.visit(Cypress.env('testUrl'));
}); });

View File

@@ -1,10 +1,8 @@
import {isValueExistsInElement, verifyMinimumEntries} from '../testHelpers/TrafficHelper'; import {isValueExistsInElement} from '../testHelpers/TrafficHelper';
it('Loading Mizu', function () { it('Loading Mizu', function () {
cy.visit(Cypress.env('testUrl')); cy.visit(Cypress.env('testUrl'));
}); });
verifyMinimumEntries();
isValueExistsInElement(true, Cypress.env('redactHeaderContent'), '#tbody-Headers'); isValueExistsInElement(true, Cypress.env('redactHeaderContent'), '#tbody-Headers');
isValueExistsInElement(true, Cypress.env('redactBodyContent'), Cypress.env('bodyJsonClass')); isValueExistsInElement(true, Cypress.env('redactBodyContent'), Cypress.env('bodyJsonClass'));

View File

@@ -1,9 +1,7 @@
import {isValueExistsInElement, verifyMinimumEntries} from "../testHelpers/TrafficHelper"; import {isValueExistsInElement} from "../testHelpers/TrafficHelper";
it('Loading Mizu', function () { it('Loading Mizu', function () {
cy.visit(Cypress.env('testUrl')); cy.visit(Cypress.env('testUrl'));
}); });
verifyMinimumEntries();
isValueExistsInElement(true, Cypress.env('regexMaskingBodyContent'), Cypress.env('bodyJsonClass')); isValueExistsInElement(true, Cypress.env('regexMaskingBodyContent'), Cypress.env('bodyJsonClass'));

View File

@@ -64,6 +64,8 @@ it('right side sanity test', function () {
}); });
}); });
serviceMapCheck();
checkIllegalFilter('invalid filter'); checkIllegalFilter('invalid filter');
checkFilter({ checkFilter({
@@ -188,7 +190,7 @@ function checkFilter(filterDetails){
const entriesForDeeperCheck = 5; const entriesForDeeperCheck = 5;
it(`checking the filter: ${name}`, function () { 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(); const totalEntries = number.text();
// checks the hover on the last entry (the only one in DOM at the beginning) // 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', 1).and('have.text', decodedText);
cy.get(`${Cypress.env('bodyJsonClass')} > >`).should('have.length', jsonItems) 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);
}

View File

@@ -155,7 +155,7 @@ func TestAmqp(t *testing.T) {
defer conn.Close() defer conn.Close()
// Temporary fix for missing amqp entries // Temporary fix for missing amqp entries
time.Sleep(5 * time.Second) time.Sleep(10 * time.Second)
for i := 0; i < defaultEntriesCount/5; i++ { for i := 0; i < defaultEntriesCount/5; i++ {
ch, err := conn.Channel() ch, err := conn.Channel()

View File

@@ -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))
}) })
} }
} }

View File

@@ -150,9 +150,10 @@ func runCypressTests(t *testing.T, cypressRunCmd string) {
t.Logf("running command: %v", cypressCmd.String()) t.Logf("running command: %v", cypressCmd.String())
out, err := cypressCmd.Output() out, err := cypressCmd.Output()
if err != nil { if err != nil {
t.Errorf("%s", out) t.Errorf("error running cypress, error: %v", err)
return return
} }
t.Logf("%s", out) t.Logf("%s", out)
} }

View File

@@ -22,7 +22,7 @@ require (
github.com/ory/kratos-client-go v0.8.2-alpha.1 github.com/ory/kratos-client-go v0.8.2-alpha.1
github.com/patrickmn/go-cache v2.1.0+incompatible github.com/patrickmn/go-cache v2.1.0+incompatible
github.com/stretchr/testify v1.7.0 github.com/stretchr/testify v1.7.0
github.com/up9inc/basenine/client/go v0.0.0-20220125035757-926e42208705 github.com/up9inc/basenine/client/go v0.0.0-20220220204122-0ef8cb24fab1
github.com/up9inc/mizu/shared v0.0.0 github.com/up9inc/mizu/shared v0.0.0
github.com/up9inc/mizu/tap v0.0.0 github.com/up9inc/mizu/tap v0.0.0
github.com/up9inc/mizu/tap/api v0.0.0 github.com/up9inc/mizu/tap/api v0.0.0

View File

@@ -853,8 +853,8 @@ github.com/ugorji/go v1.2.6/go.mod h1:anCg0y61KIhDlPZmnH+so+RQbysYVyDko0IMgJv0Nn
github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY= github.com/ugorji/go/codec v1.1.7/go.mod h1:Ax+UKWsSmolVDwsd+7N3ZtXu+yMGCf907BLYF3GoBXY=
github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ= github.com/ugorji/go/codec v1.2.6 h1:7kbGefxLoDBuYXOms4yD7223OpNMMPNPZxXk5TvFcyQ=
github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw= github.com/ugorji/go/codec v1.2.6/go.mod h1:V6TCNZ4PHqoHGFZuSG1W8nrCzzdgA2DozYxWFFpvxTw=
github.com/up9inc/basenine/client/go v0.0.0-20220125035757-926e42208705 h1:5LLhzv0cjb/F+dU0z3j8teVGjQInMYAocTyAZohKUwY= github.com/up9inc/basenine/client/go v0.0.0-20220220204122-0ef8cb24fab1 h1:0XN8s3HtwUBr9hbWRAFulFMsu1f2cabfJbwpz/sOoLA=
github.com/up9inc/basenine/client/go v0.0.0-20220125035757-926e42208705/go.mod h1:SvJGPoa/6erhUQV7kvHBwM/0x5LyO6XaG2lUaCaKiUI= github.com/up9inc/basenine/client/go v0.0.0-20220220204122-0ef8cb24fab1/go.mod h1:SvJGPoa/6erhUQV7kvHBwM/0x5LyO6XaG2lUaCaKiUI=
github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw= github.com/vektah/gqlparser v1.1.2/go.mod h1:1ycwN7Ij5njmMkPPAOaRFY4rET2Enx7IkVv3vaXspKw=
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg= github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74 h1:gga7acRE695APm9hlsSMoOoE65U4/TcqNj90mc69Rlg=
github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0= github.com/vishvananda/netns v0.0.0-20211101163701-50045581ed74/go.mod h1:DD4vA1DwXk04H54A1oHXtwZmA0grkVMdPxx/VGLCah0=

View File

@@ -56,11 +56,9 @@ const (
func main() { func main() {
logLevel := determineLogLevel() logLevel := determineLogLevel()
logger.InitLoggerStderrOnly(logLevel) logger.InitLoggerStd(logLevel)
flag.Parse() flag.Parse()
if err := config.LoadConfig(); err != nil {
logger.Log.Fatalf("Error loading config file %v", err)
}
app.LoadExtensions() app.LoadExtensions()
if !*tapperMode && !*apiServerMode && !*standaloneMode && !*harsReaderMode { if !*tapperMode && !*apiServerMode && !*standaloneMode && !*harsReaderMode {
@@ -139,7 +137,10 @@ func hostApi(socketHarOutputChannel chan<- *tapApi.OutputChannelItem) *gin.Engin
} }
func runInApiServerMode(namespace string) *gin.Engine { func runInApiServerMode(namespace string) *gin.Engine {
app.ConfigureBasenineServer(shared.BasenineHost, shared.BaseninePort) if err := config.LoadConfig(); err != nil {
logger.Log.Fatalf("Error loading config file %v", err)
}
app.ConfigureBasenineServer(shared.BasenineHost, shared.BaseninePort, config.Config.MaxDBSizeBytes, config.Config.LogLevel)
startTime = time.Now().UnixNano() / int64(time.Millisecond) startTime = time.Now().UnixNano() / int64(time.Millisecond)
api.StartResolving(namespace) api.StartResolving(namespace)
@@ -215,7 +216,7 @@ func enableExpFeatureIfNeeded() {
oas.GetOasGeneratorInstance().Start() oas.GetOasGeneratorInstance().Start()
} }
if config.Config.ServiceMap { if config.Config.ServiceMap {
servicemap.GetInstance().SetConfig(config.Config) servicemap.GetInstance().Enable()
} }
elastic.GetInstance().Configure(config.Config.Elastic) elastic.GetInstance().Configure(config.Config.Elastic)
} }

View File

@@ -140,7 +140,17 @@ func startReadingChannel(outputItems <-chan *tapApi.OutputChannelItem, extension
mizuEntry.Rules = rules mizuEntry.Rules = rules
} }
entryWSource := oas.EntryWithSource{Entry: *harEntry, Source: mizuEntry.Source.Name, Id: mizuEntry.Id} entryWSource := oas.EntryWithSource{
Entry: *harEntry,
Source: mizuEntry.Source.Name,
Destination: mizuEntry.Destination.Name,
Id: mizuEntry.Id,
}
if entryWSource.Destination == "" {
entryWSource.Destination = mizuEntry.Destination.IP + ":" + mizuEntry.Destination.Port
}
oas.GetOasGeneratorInstance().PushEntry(&entryWSource) oas.GetOasGeneratorInstance().PushEntry(&entryWSource)
} }

View File

@@ -30,6 +30,11 @@ type SocketConnection struct {
isTapper bool isTapper bool
} }
type WebSocketParams struct {
Query string `json:"query"`
EnableFullEntries bool `json:"enableFullEntries"`
}
var ( var (
websocketUpgrader = websocket.Upgrader{ websocketUpgrader = websocket.Upgrader{
ReadBufferSize: 1024, ReadBufferSize: 1024,
@@ -110,6 +115,8 @@ func websocketHandler(w http.ResponseWriter, r *http.Request, eventHandlers Even
logger.Log.Error(err) logger.Log.Error(err)
} }
var params WebSocketParams
for { for {
_, msg, err := ws.ReadMessage() _, msg, err := ws.ReadMessage()
if err != nil { if err != nil {
@@ -123,7 +130,11 @@ func websocketHandler(w http.ResponseWriter, r *http.Request, eventHandlers Even
} }
if !isTapper && !isQuerySet { if !isTapper && !isQuerySet {
query := string(msg) if err := json.Unmarshal(msg, &params); err != nil {
logger.Log.Errorf("Error: %v", socketId, err)
}
query := params.Query
err = basenine.Validate(shared.BasenineHost, shared.BaseninePort, query) err = basenine.Validate(shared.BasenineHost, shared.BaseninePort, query)
if err != nil { if err != nil {
toastBytes, _ := models.CreateWebsocketToastMessage(&models.ToastMessage{ toastBytes, _ := models.CreateWebsocketToastMessage(&models.ToastMessage{
@@ -150,10 +161,15 @@ func websocketHandler(w http.ResponseWriter, r *http.Request, eventHandlers Even
var entry *tapApi.Entry var entry *tapApi.Entry
err = json.Unmarshal(bytes, &entry) err = json.Unmarshal(bytes, &entry)
base := tapApi.Summarize(entry) var message []byte
if params.EnableFullEntries {
message, _ = models.CreateFullEntryWebSocketMessage(entry)
} else {
base := tapApi.Summarize(entry)
message, _ = models.CreateBaseEntryWebSocketMessage(base)
}
baseEntryBytes, _ := models.CreateBaseEntryWebSocketMessage(base) if err := SendToSocket(socketId, message); err != nil {
if err := SendToSocket(socketId, baseEntryBytes); err != nil {
logger.Log.Error(err) logger.Log.Error(err)
} }
} }

View File

@@ -9,7 +9,6 @@ import (
"github.com/op/go-logging" "github.com/op/go-logging"
basenine "github.com/up9inc/basenine/client/go" basenine "github.com/up9inc/basenine/client/go"
"github.com/up9inc/mizu/agent/pkg/api" "github.com/up9inc/mizu/agent/pkg/api"
"github.com/up9inc/mizu/agent/pkg/config"
"github.com/up9inc/mizu/agent/pkg/controllers" "github.com/up9inc/mizu/agent/pkg/controllers"
"github.com/up9inc/mizu/shared/logger" "github.com/up9inc/mizu/shared/logger"
tapApi "github.com/up9inc/mizu/tap/api" tapApi "github.com/up9inc/mizu/tap/api"
@@ -60,27 +59,21 @@ func LoadExtensions() {
return Extensions[i].Protocol.Priority < Extensions[j].Protocol.Priority return Extensions[i].Protocol.Priority < Extensions[j].Protocol.Priority
}) })
for _, extension := range Extensions {
logger.Log.Infof("Extension Properties: %+v", extension)
}
controllers.InitExtensionsMap(ExtensionsMap) controllers.InitExtensionsMap(ExtensionsMap)
} }
func ConfigureBasenineServer(host string, port string) { func ConfigureBasenineServer(host string, port string, dbSize int64, logLevel logging.Level) {
if !wait.New( if !wait.New(
wait.WithProto("tcp"), wait.WithProto("tcp"),
wait.WithWait(200*time.Millisecond), wait.WithWait(200*time.Millisecond),
wait.WithBreak(50*time.Millisecond), wait.WithBreak(50*time.Millisecond),
wait.WithDeadline(5*time.Second), wait.WithDeadline(5*time.Second),
wait.WithDebug(config.Config.LogLevel == logging.DEBUG), wait.WithDebug(logLevel == logging.DEBUG),
).Do([]string{fmt.Sprintf("%s:%s", host, port)}) { ).Do([]string{fmt.Sprintf("%s:%s", host, port)}) {
logger.Log.Panicf("Basenine is not available!") logger.Log.Panicf("Basenine is not available!")
} }
// Limit the database size to default 200MB if err := basenine.Limit(host, port, dbSize); err != nil {
err := basenine.Limit(host, port, config.Config.MaxDBSizeBytes)
if err != nil {
logger.Log.Panicf("Error while limiting database size: %v", err) logger.Log.Panicf("Error while limiting database size: %v", err)
} }
@@ -88,8 +81,7 @@ func ConfigureBasenineServer(host string, port string) {
for _, extension := range Extensions { for _, extension := range Extensions {
macros := extension.Dissector.Macros() macros := extension.Dissector.Macros()
for macro, expanded := range macros { for macro, expanded := range macros {
err = basenine.Macro(host, port, macro, expanded) if err := basenine.Macro(host, port, macro, expanded); err != nil {
if err != nil {
logger.Log.Panicf("Error while adding a macro: %v", err) logger.Log.Panicf("Error while adding a macro: %v", err)
} }
} }

View File

@@ -11,7 +11,6 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/up9inc/mizu/shared"
tapApi "github.com/up9inc/mizu/tap/api" tapApi "github.com/up9inc/mizu/tap/api"
) )
@@ -59,9 +58,7 @@ type ServiceMapControllerSuite struct {
func (s *ServiceMapControllerSuite) SetupTest() { func (s *ServiceMapControllerSuite) SetupTest() {
s.c = NewServiceMapController() s.c = NewServiceMapController()
s.c.service.SetConfig(&shared.MizuAgentConfig{ s.c.service.Enable()
ServiceMap: true,
})
s.c.service.NewTCPEntry(TCPEntryA, TCPEntryB, ProtocolHttp) s.c.service.NewTCPEntry(TCPEntryA, TCPEntryB, ProtocolHttp)
s.w = httptest.NewRecorder() s.w = httptest.NewRecorder()

View File

@@ -42,6 +42,11 @@ type WebSocketEntryMessage struct {
Data *tapApi.BaseEntry `json:"data,omitempty"` Data *tapApi.BaseEntry `json:"data,omitempty"`
} }
type WebSocketFullEntryMessage struct {
*shared.WebSocketMessageMetadata
Data *tapApi.Entry `json:"data,omitempty"`
}
type WebSocketTappedEntryMessage struct { type WebSocketTappedEntryMessage struct {
*shared.WebSocketMessageMetadata *shared.WebSocketMessageMetadata
Data *tapApi.OutputChannelItem Data *tapApi.OutputChannelItem
@@ -88,6 +93,16 @@ func CreateBaseEntryWebSocketMessage(base *tapApi.BaseEntry) ([]byte, error) {
return json.Marshal(message) return json.Marshal(message)
} }
func CreateFullEntryWebSocketMessage(entry *tapApi.Entry) ([]byte, error) {
message := &WebSocketFullEntryMessage{
WebSocketMessageMetadata: &shared.WebSocketMessageMetadata{
MessageType: shared.WebSocketMessageTypeFullEntry,
},
Data: entry,
}
return json.Marshal(message)
}
func CreateWebsocketTappedEntryMessage(base *tapApi.OutputChannelItem) ([]byte, error) { func CreateWebsocketTappedEntryMessage(base *tapApi.OutputChannelItem) ([]byte, error) {
message := &WebSocketTappedEntryMessage{ message := &WebSocketTappedEntryMessage{
WebSocketMessageMetadata: &shared.WebSocketMessageMetadata{ WebSocketMessageMetadata: &shared.WebSocketMessageMetadata{

View File

@@ -6,6 +6,7 @@ import (
"errors" "errors"
"io" "io"
"io/ioutil" "io/ioutil"
"net/url"
"os" "os"
"path/filepath" "path/filepath"
"sort" "sort"
@@ -139,7 +140,12 @@ func feedEntry(entry *har.Entry, source string, isSync bool, file string) {
logger.Log.Debugf("Interesting: %s", entry.Request.URL) logger.Log.Debugf("Interesting: %s", entry.Request.URL)
} }
ews := EntryWithSource{Entry: *entry, Source: source, Id: uint(0)} u, err := url.Parse(entry.Request.URL)
if err != nil {
logger.Log.Errorf("Failed to parse entry URL: %v, err: %v", entry.Request.URL, err)
}
ews := EntryWithSource{Entry: *entry, Source: source, Destination: u.Host, Id: uint(0)}
if isSync { if isSync {
GetOasGeneratorInstance().entriesChan <- ews // blocking variant, right? GetOasGeneratorInstance().entriesChan <- ews // blocking variant, right?
} else { } else {

View File

@@ -54,11 +54,11 @@ func (g *oasGenerator) runGeneretor() {
logger.Log.Errorf("Failed to parse entry URL: %v, err: %v", entry.Request.URL, err) logger.Log.Errorf("Failed to parse entry URL: %v, err: %v", entry.Request.URL, err)
} }
val, found := g.ServiceSpecs.Load(u.Host) val, found := g.ServiceSpecs.Load(entryWithSource.Destination)
var gen *SpecGen var gen *SpecGen
if !found { if !found {
gen = NewGen(u.Scheme + "://" + u.Host) gen = NewGen(u.Scheme + "://" + entryWithSource.Destination)
g.ServiceSpecs.Store(u.Host, gen) g.ServiceSpecs.Store(entryWithSource.Destination, gen)
} else { } else {
gen = val.(*SpecGen) gen = val.(*SpecGen)
} }
@@ -105,9 +105,10 @@ func newOasGenerator() *oasGenerator {
} }
type EntryWithSource struct { type EntryWithSource struct {
Source string Source string
Entry har.Entry Destination string
Id uint Entry har.Entry
Id uint
} }
type oasGenerator struct { type oasGenerator struct {

View File

@@ -41,7 +41,7 @@ func outputSpec(label string, spec *openapi.OpenAPI, t *testing.T) string {
} }
func TestEntries(t *testing.T) { func TestEntries(t *testing.T) {
logger.InitLoggerStderrOnly(logging.INFO) logger.InitLoggerStd(logging.INFO)
files, err := getFiles("./test_artifacts/") files, err := getFiles("./test_artifacts/")
if err != nil { if err != nil {
t.Log(err) t.Log(err)

View File

@@ -3,7 +3,6 @@ package servicemap
import ( import (
"sync" "sync"
"github.com/up9inc/mizu/shared"
"github.com/up9inc/mizu/shared/logger" "github.com/up9inc/mizu/shared/logger"
tapApi "github.com/up9inc/mizu/tap/api" tapApi "github.com/up9inc/mizu/tap/api"
) )
@@ -26,13 +25,13 @@ func GetInstance() ServiceMap {
} }
type serviceMap struct { type serviceMap struct {
config *shared.MizuAgentConfig enabled bool
graph *graph graph *graph
entriesProcessed int entriesProcessed int
} }
type ServiceMap interface { type ServiceMap interface {
SetConfig(config *shared.MizuAgentConfig) Enable()
IsEnabled() bool IsEnabled() bool
NewTCPEntry(source *tapApi.TCP, destination *tapApi.TCP, protocol *tapApi.Protocol) NewTCPEntry(source *tapApi.TCP, destination *tapApi.TCP, protocol *tapApi.Protocol)
GetStatus() ServiceMapStatus GetStatus() ServiceMapStatus
@@ -46,7 +45,7 @@ type ServiceMap interface {
func newServiceMap() *serviceMap { func newServiceMap() *serviceMap {
return &serviceMap{ return &serviceMap{
config: nil, enabled: false,
entriesProcessed: 0, entriesProcessed: 0,
graph: newDirectedGraph(), graph: newDirectedGraph(),
} }
@@ -156,15 +155,12 @@ func (s *serviceMap) addEdge(u, v *entryData, p *tapApi.Protocol) {
s.entriesProcessed++ s.entriesProcessed++
} }
func (s *serviceMap) SetConfig(config *shared.MizuAgentConfig) { func (s *serviceMap) Enable() {
s.config = config s.enabled = true
} }
func (s *serviceMap) IsEnabled() bool { func (s *serviceMap) IsEnabled() bool {
if s.config != nil && s.config.ServiceMap { return s.enabled
return true
}
return false
} }
func (s *serviceMap) NewTCPEntry(src *tapApi.TCP, dst *tapApi.TCP, p *tapApi.Protocol) { func (s *serviceMap) NewTCPEntry(src *tapApi.TCP, dst *tapApi.TCP, p *tapApi.Protocol) {

View File

@@ -6,7 +6,6 @@ import (
"testing" "testing"
"github.com/stretchr/testify/suite" "github.com/stretchr/testify/suite"
"github.com/up9inc/mizu/shared"
tapApi "github.com/up9inc/mizu/tap/api" tapApi "github.com/up9inc/mizu/tap/api"
) )
@@ -96,9 +95,7 @@ func (s *ServiceMapDisabledSuite) SetupTest() {
func (s *ServiceMapEnabledSuite) SetupTest() { func (s *ServiceMapEnabledSuite) SetupTest() {
s.instance = GetInstance() s.instance = GetInstance()
s.instance.SetConfig(&shared.MizuAgentConfig{ s.instance.Enable()
ServiceMap: true,
})
} }
func (s *ServiceMapDisabledSuite) TestServiceMapInstance() { func (s *ServiceMapDisabledSuite) TestServiceMapInstance() {

View File

@@ -10,7 +10,7 @@ curl -Lo mizu https://github.com/up9inc/mizu/releases/download/_VER_/mizu_darwin
**Mac** (AArch64/Apple M1 silicon) **Mac** (AArch64/Apple M1 silicon)
``` ```
curl -Lo mizu https://github.com/up9inc/mizu/releases/download/_VER_/mizu_darwin_arm64 && chmod 755 mizu rm -f mizu && curl -Lo mizu https://github.com/up9inc/mizu/releases/download/_VER_/mizu_darwin_arm64 && chmod 755 mizu
``` ```
**Linux** (x86-64) **Linux** (x86-64)

View File

@@ -1,8 +1,11 @@
package cmd package cmd
import ( import (
"github.com/creasty/defaults"
"github.com/spf13/cobra" "github.com/spf13/cobra"
"github.com/up9inc/mizu/cli/config/configStructs"
"github.com/up9inc/mizu/cli/telemetry" "github.com/up9inc/mizu/cli/telemetry"
"github.com/up9inc/mizu/shared/logger"
) )
var checkCmd = &cobra.Command{ var checkCmd = &cobra.Command{
@@ -17,4 +20,11 @@ var checkCmd = &cobra.Command{
func init() { func init() {
rootCmd.AddCommand(checkCmd) 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")
} }

View File

@@ -2,7 +2,11 @@ package cmd
import ( import (
"context" "context"
"embed"
"fmt" "fmt"
rbac "k8s.io/api/rbac/v1"
"k8s.io/apimachinery/pkg/runtime"
"k8s.io/client-go/kubernetes/scheme"
"regexp" "regexp"
"github.com/up9inc/mizu/cli/apiserver" "github.com/up9inc/mizu/cli/apiserver"
@@ -13,8 +17,13 @@ import (
"github.com/up9inc/mizu/shared/semver" "github.com/up9inc/mizu/shared/semver"
) )
var (
//go:embed permissionFiles
embedFS embed.FS
)
func runMizuCheck() { func runMizuCheck() {
logger.Log.Infof("Mizu install checks\n===================") logger.Log.Infof("Mizu checks\n===================")
ctx, cancel := context.WithCancel(context.Background()) ctx, cancel := context.WithCancel(context.Background())
defer cancel() // cancel will be called when this function exits defer cancel() // cancel will be called when this function exits
@@ -25,17 +34,18 @@ func runMizuCheck() {
checkPassed = checkKubernetesVersion(kubernetesVersion) checkPassed = checkKubernetesVersion(kubernetesVersion)
} }
var isInstallCommand bool if config.Config.Check.PreTap {
if checkPassed { if checkPassed {
checkPassed, isInstallCommand = checkMizuMode(ctx, kubernetesProvider) checkPassed = checkK8sTapPermissions(ctx, kubernetesProvider)
} }
} else {
if checkPassed {
checkPassed = checkK8sResources(ctx, kubernetesProvider)
}
if checkPassed { if checkPassed {
checkPassed = checkK8sResources(ctx, kubernetesProvider, isInstallCommand) checkPassed = checkServerConnection(kubernetesProvider)
} }
if checkPassed {
checkPassed = checkServerConnection(kubernetesProvider)
} }
if checkPassed { if checkPassed {
@@ -65,27 +75,6 @@ func checkKubernetesApi() (*kubernetes.Provider, *semver.SemVersion, bool) {
return kubernetesProvider, kubernetesVersion, true 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 { func checkKubernetesVersion(kubernetesVersion *semver.SemVersion) bool {
logger.Log.Infof("\nkubernetes-version\n--------------------") logger.Log.Infof("\nkubernetes-version\n--------------------")
@@ -169,7 +158,7 @@ func checkPortForward(serverUrl string, kubernetesProvider *kubernetes.Provider)
return nil 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--------------------") logger.Log.Infof("\nk8s-components\n--------------------")
exist, err := kubernetesProvider.DoesNamespaceExist(ctx, config.Config.MizuResourcesNamespace) exist, err := kubernetesProvider.DoesNamespaceExist(ctx, config.Config.MizuResourcesNamespace)
@@ -198,32 +187,12 @@ func checkK8sResources(ctx context.Context, kubernetesProvider *kubernetes.Provi
exist, err = kubernetesProvider.DoesServiceExist(ctx, config.Config.MizuResourcesNamespace, kubernetes.ApiServerPodName) exist, err = kubernetesProvider.DoesServiceExist(ctx, config.Config.MizuResourcesNamespace, kubernetes.ApiServerPodName)
allResourcesExist = checkResourceExist(kubernetes.ApiServerPodName, "service", exist, err) && allResourcesExist allResourcesExist = checkResourceExist(kubernetes.ApiServerPodName, "service", exist, err) && allResourcesExist
if isInstallCommand { allResourcesExist = checkPodResourcesExist(ctx, kubernetesProvider) && allResourcesExist
allResourcesExist = checkInstallResourcesExist(ctx, kubernetesProvider) && allResourcesExist
} else {
allResourcesExist = checkTapResourcesExist(ctx, kubernetesProvider) && allResourcesExist
}
return allResourcesExist return allResourcesExist
} }
func checkInstallResourcesExist(ctx context.Context, kubernetesProvider *kubernetes.Provider) bool { func checkPodResourcesExist(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) exist, err := kubernetesProvider.DoesPodExist(ctx, config.Config.MizuResourcesNamespace, kubernetes.ApiServerPodName)
tapResourcesExist := checkResourceExist(kubernetes.ApiServerPodName, "pod", exist, err) tapResourcesExist := checkResourceExist(kubernetes.ApiServerPodName, "pod", exist, err)
@@ -273,9 +242,81 @@ func checkResourceExist(resourceName string, resourceType string, exist bool, er
} else if !exist { } else if !exist {
logger.Log.Errorf("%v '%v' %v doesn't exist", fmt.Sprintf(uiUtils.Red, "✗"), resourceName, resourceType) logger.Log.Errorf("%v '%v' %v doesn't exist", fmt.Sprintf(uiUtils.Red, "✗"), resourceName, resourceType)
return false 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 return true
} }

View File

@@ -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("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("To install stable build of Mizu on your cluster using helm, run the following command:")
logger.Log.Infof(" helm install mizu https://static.up9.com/mizu/helm --namespace=mizu --create-namespace\n\n") logger.Log.Infof(" helm install mizu mizu --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("To install development build of Mizu on your cluster using helm, run the following command:")
logger.Log.Infof(" helm install mizu https://static.up9.com/mizu/helm-develop --namespace=mizu --create-namespace") logger.Log.Infof(" helm install mizu mizu --repo https://static.up9.com/mizu/helm-develop --namespace=mizu --create-namespace\n")
return nil return nil
}, },

View File

@@ -0,0 +1,25 @@
# This example shows permissions that enrich the logs with additional info
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: mizu-runner-debug-clusterrole
rules:
- apiGroups: ["events.k8s.io"]
resources: ["events"]
verbs: ["watch"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: mizu-runner-debug-clusterrolebindings
subjects:
- kind: User
name: user1
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: mizu-runner-debug-clusterrole
apiGroup: rbac.authorization.k8s.io

View File

@@ -0,0 +1,37 @@
# This example shows permissions that are required for Mizu to resolve IPs to service names
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: mizu-resolver-clusterrole
rules:
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs: ["get", "create"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles"]
verbs: ["get", "list", "create", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterrolebindings"]
verbs: ["get", "list", "create", "delete"]
- apiGroups: ["", "apps", "extensions"]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["", "apps", "extensions"]
resources: ["services"]
verbs: ["get", "list", "watch"]
- apiGroups: ["", "apps", "extensions"]
resources: ["endpoints"]
verbs: ["get", "list", "watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: mizu-resolver-clusterrolebindings
subjects:
- kind: User
name: user1
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: mizu-resolver-clusterrole
apiGroup: rbac.authorization.k8s.io

View File

@@ -1,5 +1,4 @@
# This example shows the roles required for a user to be able to use Mizu in all namespaces with IP resolution disabled. # This example shows the permissions that are required in order to run the `mizu tap` command
# (Traffic will be recorded, but Mizu will not translate IP addresses to names)
kind: ClusterRole kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1 apiVersion: rbac.authorization.k8s.io/v1
metadata: metadata:
@@ -7,25 +6,22 @@ metadata:
rules: rules:
- apiGroups: [""] - apiGroups: [""]
resources: ["pods"] resources: ["pods"]
verbs: ["list", "watch", "create", "delete"] verbs: ["list", "watch", "create"]
- apiGroups: [""] - apiGroups: [""]
resources: ["services"] resources: ["services"]
verbs: ["create", "delete"] verbs: ["get", "create"]
- apiGroups: ["apps"] - apiGroups: ["apps"]
resources: ["daemonsets"] resources: ["daemonsets"]
verbs: ["create", "patch", "delete"] verbs: ["create", "patch"]
- apiGroups: [""] - apiGroups: [""]
resources: ["namespaces"] resources: ["namespaces"]
verbs: ["get", "list", "watch", "create", "delete"] verbs: ["list", "watch", "create", "delete"]
- apiGroups: [""] - apiGroups: [""]
resources: ["services/proxy"] resources: ["services/proxy"]
verbs: ["get"] verbs: ["get", "create"]
- apiGroups: [""] - apiGroups: [""]
resources: ["configmaps"] resources: ["configmaps"]
verbs: ["get", "create", "delete"] verbs: ["create"]
- apiGroups: ["events.k8s.io"]
resources: ["events"]
verbs: ["list", "watch"]
--- ---
kind: ClusterRoleBinding kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1 apiVersion: rbac.authorization.k8s.io/v1

View File

@@ -0,0 +1,27 @@
# This example shows permissions that enrich the logs with additional info in namespace-restricted mode
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: mizu-runner-debug-role
namespace: user1
rules:
- apiGroups: ["events.k8s.io"]
resources: ["events"]
verbs: ["watch"]
- apiGroups: [""]
resources: ["pods"]
verbs: ["get"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: mizu-runner-debug-rolebindings
namespace: user1
subjects:
- kind: User
name: user1
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: mizu-runner-debug-role
apiGroup: rbac.authorization.k8s.io

View File

@@ -0,0 +1,39 @@
# This example shows permissions that are required for Mizu to resolve IPs to service names in namespace-restricted mode
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: mizu-resolver-role
namespace: user1
rules:
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs: ["get", "list", "create", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles"]
verbs: ["get", "list", "create", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["rolebindings"]
verbs: ["get", "list", "create", "delete"]
- apiGroups: ["", "apps", "extensions"]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["", "apps", "extensions"]
resources: ["services"]
verbs: ["get", "list", "watch"]
- apiGroups: ["", "apps", "extensions"]
resources: ["endpoints"]
verbs: ["get", "list", "watch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: mizu-resolver-rolebindings
namespace: user1
subjects:
- kind: User
name: user1
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: mizu-resolver-role
apiGroup: rbac.authorization.k8s.io

View File

@@ -1,4 +1,4 @@
# This example shows the roles required for a user to be able to use Mizu in a single namespace with IP resolution disabled. # This example shows the permissions that are required in order to run the `mizu tap` command in namespace-restricted mode
kind: Role kind: Role
apiVersion: rbac.authorization.k8s.io/v1 apiVersion: rbac.authorization.k8s.io/v1
metadata: metadata:
@@ -7,22 +7,19 @@ metadata:
rules: rules:
- apiGroups: [""] - apiGroups: [""]
resources: ["pods"] resources: ["pods"]
verbs: ["get", "list", "watch", "create", "delete"] verbs: ["list", "watch", "create"]
- apiGroups: [""] - apiGroups: [""]
resources: ["services"] resources: ["services"]
verbs: ["get", "create", "delete"] verbs: ["get", "create", "delete"]
- apiGroups: ["apps"] - apiGroups: ["apps"]
resources: ["daemonsets"] resources: ["daemonsets"]
verbs: ["get", "create", "patch", "delete"] verbs: ["create", "patch", "delete"]
- apiGroups: [""] - apiGroups: [""]
resources: ["services/proxy"] resources: ["services/proxy"]
verbs: ["get"] verbs: ["get", "create", "delete"]
- apiGroups: [""] - apiGroups: [""]
resources: ["configmaps"] resources: ["configmaps"]
verbs: ["get", "create", "delete"] verbs: ["create", "delete"]
- apiGroups: ["events.k8s.io"]
resources: ["events"]
verbs: ["list", "watch"]
--- ---
kind: RoleBinding kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1 apiVersion: rbac.authorization.k8s.io/v1

View File

@@ -22,6 +22,7 @@ const (
type ConfigStruct struct { type ConfigStruct struct {
Tap configStructs.TapConfig `yaml:"tap"` Tap configStructs.TapConfig `yaml:"tap"`
Check configStructs.CheckConfig `yaml:"check"`
Version configStructs.VersionConfig `yaml:"version"` Version configStructs.VersionConfig `yaml:"version"`
View configStructs.ViewConfig `yaml:"view"` View configStructs.ViewConfig `yaml:"view"`
Logs configStructs.LogsConfig `yaml:"logs"` Logs configStructs.LogsConfig `yaml:"logs"`

View File

@@ -0,0 +1,9 @@
package configStructs
const (
PreTapCheckName = "pre-tap"
)
type CheckConfig struct {
PreTap bool `yaml:"pre-tap"`
}

View File

@@ -80,327 +80,9 @@ Notes:
## List of permissions ## List of permissions
We broke down this list into few categories: The permissions that are required to run Mizu depend on the configuration.
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.
- Required - what is needed for `mizu` to run properly on your k8s cluster The different requirements are listed in [the permission templates dir](../cli/cmd/permissionFiles)
- Optional - permissions needed for proper name resolving for service & pod IPs
- addition required for policy validation
### Required permissions
Mizu needs following permissions on your Kubernetes cluster to run properly
```yaml
- apiGroups:
- ""
resources:
- pods
verbs:
- list
- watch
- create
- delete
- apiGroups:
- ""
resources:
- services
verbs:
- create
- delete
- apiGroups:
- apps
resources:
- daemonsets
verbs:
- create
- patch
- delete
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
- create
- delete
- apiGroups:
- ""
resources:
- services/proxy
verbs:
- get
```
#### Permissions required running with install command or (optional) for service / pod name resolving
Mandatory permissions for running with install command.
Optional for service/pod name resolving in non install standalone
```yaml
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
- create
- delete
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- create
- delete
- apiGroups:
- apps
resources:
- daemonsets
verbs:
- create
- patch
- delete
- apiGroups:
- ""
resources:
- namespaces
verbs:
- get
- list
- watch
- create
- delete
- apiGroups:
- ""
resources:
- services/proxy
verbs:
- get
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- get
- create
- delete
- apiGroups:
- rbac.authorization.k8s.io
resources:
- clusterroles
verbs:
- get
- create
- delete
- apiGroups:
- rbac.authorization.k8s.io
resources:
- clusterrolebindings
verbs:
- get
- create
- delete
- apiGroups:
- rbac.authorization.k8s.io
resources:
- roles
verbs:
- get
- create
- delete
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
verbs:
- get
- create
- delete
- apiGroups:
- apps
- extensions
resources:
- pods
verbs:
- get
- list
- watch
- apiGroups:
- apps
- extensions
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- ""
- apps
- extensions
resources:
- endpoints
verbs:
- get
- list
- watch
```
#### Permissions for Policy rules validation feature (opt)
Optionally, in order to use the policy rules validation feature, Mizu requires the following additional permissions:
```yaml
- apiGroups:
- ""
resources:
- configmaps
verbs:
- get
- create
- delete
```
- - -
#### Namespace-Restricted mode
Alternatively, in order to restrict Mizu to one namespace only (by setting `agent.namespace` in the config file), Mizu needs the following permissions in that namespace:
```yaml
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
- create
- delete
- apiGroups:
- ""
resources:
- services
verbs:
- get
- create
- delete
- apiGroups:
- apps
resources:
- daemonsets
verbs:
- get
- create
- patch
- delete
- apiGroups:
- ""
resources:
- services/proxy
verbs:
- get
```
##### Name resolving in Namespace-Restricted mode (opt)
To restrict Mizu to one namespace while also resolving IPs, Mizu needs the following permissions in that namespace:
```yaml
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- list
- watch
- create
- delete
- apiGroups:
- ""
resources:
- services
verbs:
- get
- list
- watch
- create
- delete
- apiGroups:
- apps
resources:
- daemonsets
verbs:
- get
- create
- patch
- delete
- apiGroups:
- ""
resources:
- services/proxy
verbs:
- get
- apiGroups:
- ""
resources:
- serviceaccounts
verbs:
- get
- create
- delete
- apiGroups:
- rbac.authorization.k8s.io
resources:
- roles
verbs:
- get
- create
- delete
- apiGroups:
- rbac.authorization.k8s.io
resources:
- rolebindings
verbs:
- get
- create
- delete
- apiGroups:
- apps
- extensions
resources:
- pods
verbs:
- get
- list
- watch
- apiGroups:
- apps
- extensions
resources:
- services
verbs:
- get
- list
- watch
- apiGroups:
- ""
- apps
- extensions
resources:
- endpoints
verbs:
- get
- list
- watch
```

View File

@@ -1,67 +0,0 @@
# This example shows the roles required for a user to be able to use Mizu in all namespaces.
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: mizu-runner-clusterrole
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch", "delete"]
- apiGroups: [ "apps" ]
resources: [ "deployments" ]
verbs: [ "get", "create", "delete" ]
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: ["apps"]
resources: ["daemonsets"]
verbs: ["get", "create", "patch", "delete", "list"]
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["services/proxy"]
verbs: ["get"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "create", "delete"]
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs: ["get", "create", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles"]
verbs: ["get", "create", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterrolebindings"]
verbs: ["get", "create", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles"]
verbs: ["get", "create", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["rolebindings"]
verbs: ["get", "create", "delete"]
- apiGroups: ["apps", "extensions"]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps", "extensions"]
resources: ["services"]
verbs: ["get", "list", "watch"]
- apiGroups: ["", "apps", "extensions"]
resources: ["endpoints"]
verbs: ["get", "list", "watch"]
- apiGroups: ["events.k8s.io"]
resources: ["events"]
verbs: ["list", "watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: mizu-runner-clusterrolebindings
subjects:
- kind: User
name: user1
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: mizu-runner-clusterrole
apiGroup: rbac.authorization.k8s.io

View File

@@ -1,64 +0,0 @@
# This example shows the roles required for a user to be able to use Mizu in all namespaces.
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: mizu-runner-clusterrole
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: ["apps"]
resources: ["daemonsets"]
verbs: ["create", "patch", "delete"]
- apiGroups: [""]
resources: ["namespaces"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["services/proxy"]
verbs: ["get"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "create", "delete"]
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs: ["get", "create", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterroles"]
verbs: ["get", "create", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["clusterrolebindings"]
verbs: ["get", "create", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles"]
verbs: ["get", "create", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["rolebindings"]
verbs: ["get", "create", "delete"]
- apiGroups: ["apps", "extensions"]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps", "extensions"]
resources: ["services"]
verbs: ["get", "list", "watch"]
- apiGroups: ["", "apps", "extensions"]
resources: ["endpoints"]
verbs: ["get", "list", "watch"]
- apiGroups: ["events.k8s.io"]
resources: ["events"]
verbs: ["list", "watch"]
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: mizu-runner-clusterrolebindings
subjects:
- kind: User
name: user1
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: ClusterRole
name: mizu-runner-clusterrole
apiGroup: rbac.authorization.k8s.io

View File

@@ -1,60 +0,0 @@
# This example shows the roles required for a user to be able to use Mizu in a single namespace.
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: mizu-runner-role
namespace: user1
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch", "delete"]
- apiGroups: [ "apps" ]
resources: [ "deployments" ]
verbs: [ "get", "create", "delete" ]
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: ["apps"]
resources: ["daemonsets"]
verbs: ["get", "create", "patch", "delete", "list"]
- apiGroups: [""]
resources: ["services/proxy"]
verbs: ["get"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "create", "delete"]
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs: ["get", "create", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles"]
verbs: ["get", "create", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["rolebindings"]
verbs: ["get", "create", "delete"]
- apiGroups: ["apps", "extensions", ""]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps", "extensions"]
resources: ["services"]
verbs: ["get", "list", "watch"]
- apiGroups: ["", "apps", "extensions"]
resources: ["endpoints"]
verbs: ["get", "list", "watch"]
- apiGroups: ["events.k8s.io"]
resources: ["events"]
verbs: ["list", "watch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: mizu-runner-rolebindings
namespace: user1
subjects:
- kind: User
name: user1
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: mizu-runner-role
apiGroup: rbac.authorization.k8s.io

View File

@@ -1,57 +0,0 @@
# This example shows the roles required for a user to be able to use Mizu in a single namespace.
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: mizu-runner-role
namespace: user1
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: ["apps"]
resources: ["daemonsets"]
verbs: ["get", "create", "patch", "delete"]
- apiGroups: [""]
resources: ["services/proxy"]
verbs: ["get"]
- apiGroups: [""]
resources: ["configmaps"]
verbs: ["get", "create", "delete"]
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs: ["get", "create", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles"]
verbs: ["get", "create", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["rolebindings"]
verbs: ["get", "create", "delete"]
- apiGroups: ["apps", "extensions"]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps", "extensions"]
resources: ["services"]
verbs: ["get", "list", "watch"]
- apiGroups: ["", "apps", "extensions"]
resources: ["endpoints"]
verbs: ["get", "list", "watch"]
- apiGroups: ["events.k8s.io"]
resources: ["events"]
verbs: ["list", "watch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: mizu-runner-rolebindings
namespace: user1
subjects:
- kind: User
name: user1
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: mizu-runner-role
apiGroup: rbac.authorization.k8s.io

View File

@@ -1,57 +0,0 @@
# This example shows the roles required for a user to be able to use Mizu in a single namespace.
kind: Role
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: mizu-runner-role
namespace: user1
rules:
- apiGroups: [""]
resources: ["pods"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: [""]
resources: ["services"]
verbs: ["get", "list", "watch", "create", "delete"]
- apiGroups: ["apps"]
resources: ["daemonsets"]
verbs: ["get", "create", "patch", "delete"]
- apiGroups: [""]
resources: ["services/proxy"]
verbs: ["get"]
- apiGroups: [ "" ]
resources: [ "configmaps" ]
verbs: [ "get", "create", "delete" ]
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs: ["get", "create", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["roles"]
verbs: ["get", "create", "delete"]
- apiGroups: ["rbac.authorization.k8s.io"]
resources: ["rolebindings"]
verbs: ["get", "create", "delete"]
- apiGroups: ["apps", "extensions"]
resources: ["pods"]
verbs: ["get", "list", "watch"]
- apiGroups: ["apps", "extensions"]
resources: ["services"]
verbs: ["get", "list", "watch"]
- apiGroups: ["", "apps", "extensions"]
resources: ["endpoints"]
verbs: ["get", "list", "watch"]
- apiGroups: ["events.k8s.io"]
resources: ["events"]
verbs: ["list", "watch"]
---
kind: RoleBinding
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: mizu-runner-rolebindings
namespace: user1
subjects:
- kind: User
name: user1
apiGroup: rbac.authorization.k8s.io
roleRef:
kind: Role
name: mizu-runner-role
apiGroup: rbac.authorization.k8s.io

View File

@@ -17,6 +17,7 @@ import (
"github.com/up9inc/mizu/shared/semver" "github.com/up9inc/mizu/shared/semver"
"github.com/up9inc/mizu/tap/api" "github.com/up9inc/mizu/tap/api"
v1 "k8s.io/api/apps/v1" v1 "k8s.io/api/apps/v1"
auth "k8s.io/api/authorization/v1"
core "k8s.io/api/core/v1" core "k8s.io/api/core/v1"
rbac "k8s.io/api/rbac/v1" rbac "k8s.io/api/rbac/v1"
k8serrors "k8s.io/apimachinery/pkg/api/errors" 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{}) 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) { func (provider *Provider) DoesNamespaceExist(ctx context.Context, name string) (bool, error) {
namespaceResource, err := provider.clientSet.CoreV1().Namespaces().Get(ctx, name, metav1.GetOptions{}) namespaceResource, err := provider.clientSet.CoreV1().Namespaces().Get(ctx, name, metav1.GetOptions{})
return provider.doesResourceExist(namespaceResource, err) return provider.doesResourceExist(namespaceResource, err)
@@ -829,7 +850,7 @@ func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespac
if tls { if tls {
mizuCmd = append(mizuCmd, "--tls") mizuCmd = append(mizuCmd, "--tls")
} }
if serviceMesh || tls { if serviceMesh || tls {
mizuCmd = append(mizuCmd, "--procfs", procfsMountPath) mizuCmd = append(mizuCmd, "--procfs", procfsMountPath)
} }
@@ -939,24 +960,6 @@ func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespac
sysfsVolumeMount := applyconfcore.VolumeMount().WithName(sysfsVolumeName).WithMountPath(sysfsMountPath).WithReadOnly(true) sysfsVolumeMount := applyconfcore.VolumeMount().WithName(sysfsVolumeName).WithMountPath(sysfsMountPath).WithReadOnly(true)
agentContainer.WithVolumeMounts(sysfsVolumeMount) 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 := applyconfcore.PodSpec()
podSpec.WithHostNetwork(true) podSpec.WithHostNetwork(true)
podSpec.WithDNSPolicy(core.DNSClusterFirstWithHostNet) podSpec.WithDNSPolicy(core.DNSClusterFirstWithHostNet)
@@ -967,7 +970,7 @@ func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespac
podSpec.WithContainers(agentContainer) podSpec.WithContainers(agentContainer)
podSpec.WithAffinity(affinity) podSpec.WithAffinity(affinity)
podSpec.WithTolerations(noExecuteToleration, noScheduleToleration) podSpec.WithTolerations(noExecuteToleration, noScheduleToleration)
podSpec.WithVolumes(&configMapVolume, procfsVolume, sysfsVolume) podSpec.WithVolumes(procfsVolume, sysfsVolume)
podTemplate := applyconfcore.PodTemplateSpec() podTemplate := applyconfcore.PodTemplateSpec()
podTemplate.WithLabels(map[string]string{ podTemplate.WithLabels(map[string]string{
@@ -981,7 +984,7 @@ func (provider *Provider) ApplyMizuTapperDaemonSet(ctx context.Context, namespac
labelSelector.WithMatchLabels(map[string]string{"app": tapperPodName}) labelSelector.WithMatchLabels(map[string]string{"app": tapperPodName})
applyOptions := metav1.ApplyOptions{ applyOptions := metav1.ApplyOptions{
Force: true, Force: true,
FieldManager: fieldManagerName, FieldManager: fieldManagerName,
} }

View File

@@ -29,10 +29,21 @@ func InitLogger(logPath string) {
logging.SetBackend(backend1Leveled, backend2Formatter) logging.SetBackend(backend1Leveled, backend2Formatter)
} }
func InitLoggerStderrOnly(level logging.Level) { func InitLoggerStd(level logging.Level) {
backend := logging.NewLogBackend(os.Stderr, "", 0) var backends []logging.Backend
backendFormatter := logging.NewBackendFormatter(backend, format)
logging.SetBackend(backendFormatter) stderrBackend := logging.NewLogBackend(os.Stderr, "", 0)
logging.SetLevel(level, "") stderrFormater := logging.NewBackendFormatter(stderrBackend, format)
stderrLeveled := logging.AddModuleLevel(stderrFormater)
stderrLeveled.SetLevel(logging.ERROR, "")
backends = append(backends, stderrLeveled)
if level >= logging.WARNING {
stdoutBackend := logging.NewLogBackend(os.Stdout, "", 0)
stdoutFormater := logging.NewBackendFormatter(stdoutBackend, format)
stdoutLeveled := logging.AddModuleLevel(stdoutFormater)
stdoutLeveled.SetLevel(level, "")
backends = append(backends, stdoutLeveled)
}
logging.SetBackend(backends...)
} }

View File

@@ -15,6 +15,7 @@ type WebSocketMessageType string
const ( const (
WebSocketMessageTypeEntry WebSocketMessageType = "entry" WebSocketMessageTypeEntry WebSocketMessageType = "entry"
WebSocketMessageTypeFullEntry WebSocketMessageType = "fullEntry"
WebSocketMessageTypeTappedEntry WebSocketMessageType = "tappedEntry" WebSocketMessageTypeTappedEntry WebSocketMessageType = "tappedEntry"
WebSocketMessageTypeUpdateStatus WebSocketMessageType = "status" WebSocketMessageTypeUpdateStatus WebSocketMessageType = "status"
WebSocketMessageTypeAnalyzeStatus WebSocketMessageType = "analyzeStatus" WebSocketMessageTypeAnalyzeStatus WebSocketMessageType = "analyzeStatus"

View File

@@ -27,10 +27,6 @@ var protocol api.Protocol = api.Protocol{
Priority: 1, Priority: 1,
} }
func init() {
log.Println("Initializing AMQP extension...")
}
type dissecting string type dissecting string
func (d dissecting) Register(extension *api.Extension) { func (d dissecting) Register(extension *api.Extension) {

View File

@@ -76,10 +76,6 @@ const (
TypeHttpResponse TypeHttpResponse
) )
func init() {
log.Println("Initializing HTTP extension...")
}
type dissecting string type dissecting string
func (d dissecting) Register(extension *api.Extension) { func (d dissecting) Register(extension *api.Extension) {

View File

@@ -25,10 +25,6 @@ var _protocol api.Protocol = api.Protocol{
Priority: 2, Priority: 2,
} }
func init() {
log.Println("Initializing Kafka extension...")
}
type dissecting string type dissecting string
func (d dissecting) Register(extension *api.Extension) { func (d dissecting) Register(extension *api.Extension) {

View File

@@ -24,10 +24,6 @@ var protocol api.Protocol = api.Protocol{
Priority: 3, Priority: 3,
} }
func init() {
log.Println("Initializing Redis extension...")
}
type dissecting string type dissecting string
func (d dissecting) Register(extension *api.Extension) { func (d dissecting) Register(extension *api.Extension) {

View File

@@ -8,6 +8,7 @@ import {toast} from "react-toastify";
import {useRecoilValue} from "recoil"; import {useRecoilValue} from "recoil";
import focusedEntryIdAtom from "../recoil/focusedEntryId"; import focusedEntryIdAtom from "../recoil/focusedEntryId";
import Api from "../helpers/api"; import Api from "../helpers/api";
import queryAtom from "../recoil/query";
const useStyles = makeStyles(() => ({ const useStyles = makeStyles(() => ({
entryTitle: { entryTitle: {
@@ -82,6 +83,7 @@ const api = Api.getInstance();
export const EntryDetailed = () => { export const EntryDetailed = () => {
const focusedEntryId = useRecoilValue(focusedEntryIdAtom); const focusedEntryId = useRecoilValue(focusedEntryIdAtom);
const query = useRecoilValue(queryAtom);
const [entryData, setEntryData] = useState(null); const [entryData, setEntryData] = useState(null);
useEffect(() => { useEffect(() => {
@@ -89,7 +91,7 @@ export const EntryDetailed = () => {
setEntryData(null); setEntryData(null);
(async () => { (async () => {
try { try {
const entryData = await api.getEntry(focusedEntryId); const entryData = await api.getEntry(focusedEntryId, query);
setEntryData(entryData); setEntryData(entryData);
} catch (error) { } catch (error) {
if (error.response?.data?.type) { if (error.response?.data?.type) {

View File

@@ -121,7 +121,7 @@ export const TrafficPage: React.FC<TrafficPageProps> = ({setAnalyzeStatus}) => {
ws.current = new WebSocket(MizuWebsocketURL); ws.current = new WebSocket(MizuWebsocketURL);
ws.current.onopen = () => { ws.current.onopen = () => {
setWsConnection(WsConnectionStatus.Connected); setWsConnection(WsConnectionStatus.Connected);
ws.current.send(query); ws.current.send(JSON.stringify({"query": query, "enableFullEntries": false}));
} }
ws.current.onclose = () => { ws.current.onclose = () => {
setWsConnection(WsConnectionStatus.Closed); setWsConnection(WsConnectionStatus.Closed);