Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore: fix broken links and bring changes from #1393 #1448

Merged
merged 5 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
210 changes: 209 additions & 1 deletion docs/sources/next/examples/oauth-authentication.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,207 @@ export function authenticateUsingAzure(tenantId, clientId, clientSecret, scope,

{{< /code >}}

### Azure B2C

The following example shows how you can authenticate with Azure B2C using the [Client Credentials Flow](https://docs.microsoft.com/en-us/azure/active-directory-b2c/active-directory-b2c-reference-oauth-code#client-credentials-flow).

This example is based on a JMeter example found at the [azure-ad-b2c/load-tests](https://github.com/azure-ad-b2c/load-tests) repository.

To use this script, you need to:

1. [Set up your own Azure B2C tenant](https://learn.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-tenant)
- Copy the tenant name, it will be used in your test script.
1. [Register a web application](https://learn.microsoft.com/en-us/azure/active-directory-b2c/tutorial-register-applications?tabs=app-reg-ga)
- Register a single page application with the redirect URL of: https://jwt.ms. That's needed for the flow to receive a token.
- After the creation, you can get the Application (client) ID, and the Directory (tenant) ID. Copy both of them, they'll be used in your test script.
1. [Create a user flow so that you can sign up and create a user](https://docs.microsoft.com/en-us/azure/active-directory-b2c/tutorial-create-user-flows)
- Create a new user, and copy the username and password. They'll be used in the test script.

You can find the settings in the B2C settings in the Azure portal if you need to refer to them later on. Make sure to fill out all the variables for the `B2CGraphSettings` object, as well as replace `USERNAME` and `PASSWORD` in `export default function`.

{{< code >}}

```javascript
import http from 'k6/http';
import crypto from 'k6/crypto';
import { randomString } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js';

const B2CGraphSettings = {
B2C: {
client_id: '', // Application ID in Azure
user_flow_name: '',
tenant_id: '', // Directory ID in Azure
tenant_name: '',
scope: 'openid',
redirect_url: 'https://jwt.ms',
},
};

/**
* Authenticate using OAuth against Azure B2C
* @function
* @param {string} username - Username of the user to authenticate
* @param {string} password
* @return {string} id_token
*/
export function GetB2cIdToken(username, password) {
const state = GetState();
SelfAsserted(state, username, password);
const code = CombinedSigninAndSignup(state);
return GetToken(code, state.codeVerifier);
}

/**
* @typedef {object} b2cStateProperties
* @property {string} csrfToken
* @property {string} stateProperty
* @property {string} codeVerifier
*
*/

/**
* Get the id token from Azure B2C
* @function
* @param {string} code
* @returns {string} id_token
*/
const GetToken = (code, codeVerifier) => {
const url =
`https://${B2CGraphSettings.B2C.tenant_name}.b2clogin.com/${B2CGraphSettings.B2C.tenant_id}` +
`/oauth2/v2.0/token` +
`?p=${B2CGraphSettings.B2C.user_flow_name}` +
`&client_id=${B2CGraphSettings.B2C.client_id}` +
`&grant_type=authorization_code` +
`&scope=${B2CGraphSettings.B2C.scope}` +
`&code=${code}` +
`&redirect_uri=${B2CGraphSettings.B2C.redirect_url}` +
`&code_verifier=${codeVerifier}`;

const response = http.post(url, '', {
tags: {
b2c_login: 'GetToken',
},
});

return JSON.parse(response.body).id_token;
};

/**
* Signs in the user using the CombinedSigninAndSignup policy
* extraqct B2C code from response
* @function
* @param {b2cStateProperties} state
* @returns {string} code
*/
const CombinedSigninAndSignup = (state) => {
const url =
`https://${B2CGraphSettings.B2C.tenant_name}.b2clogin.com/${B2CGraphSettings.B2C.tenant_name}.onmicrosoft.com` +
`/${B2CGraphSettings.B2C.user_flow_name}/api/CombinedSigninAndSignup/confirmed` +
`?csrf_token=${state.csrfToken}` +
`&rememberMe=false` +
`&tx=StateProperties=${state.stateProperty}` +
`&p=${B2CGraphSettings.B2C.user_flow_name}`;

const response = http.get(url, '', {
tags: {
b2c_login: 'CombinedSigninAndSignup',
},
});
const codeRegex = '.*code=([^"]*)';
return response.url.match(codeRegex)[1];
};

/**
* Signs in the user using the SelfAsserted policy
* @function
* @param {b2cStateProperties} state
* @param {string} username
* @param {string} password
*/
const SelfAsserted = (state, username, password) => {
const url =
`https://${B2CGraphSettings.B2C.tenant_name}.b2clogin.com/${B2CGraphSettings.B2C.tenant_id}` +
`/${B2CGraphSettings.B2C.user_flow_name}/SelfAsserted` +
`?tx=StateProperties=${state.stateProperty}` +
`&p=${B2CGraphSettings.B2C.user_flow_name}` +
`&request_type=RESPONSE` +
`&email=${username}` +
`&password=${password}`;

const params = {
headers: {
'X-CSRF-TOKEN': `${state.csrfToken}`,
},
tags: {
b2c_login: 'SelfAsserted',
},
};
http.post(url, '', params);
};

/**
* Calls the B2C login page to get the state property
* @function
* @returns {b2cStateProperties} b2cState
*/
const GetState = () => {
const nonce = randomString(50);
const challenge = crypto.sha256(nonce.toString(), 'base64rawurl');

const url =
`https://${B2CGraphSettings.B2C.tenant_name}.b2clogin.com` +
`/${B2CGraphSettings.B2C.tenant_id}/oauth2/v2.0/authorize?` +
`p=${B2CGraphSettings.B2C.user_flow_name}` +
`&client_id=${B2CGraphSettings.B2C.client_id}` +
`&nonce=${nonce}` +
`&redirect_uri=${B2CGraphSettings.B2C.redirect_url}` +
`&scope=${B2CGraphSettings.B2C.scope}` +
`&response_type=code` +
`&prompt=login` +
`&code_challenge_method=S256` +
`&code_challenge=${challenge}` +
`&response_mode=fragment`;

const response = http.get(url, '', {
tags: {
b2c_login: 'GetCookyAndState',
},
});

const vuJar = http.cookieJar();
const responseCookies = vuJar.cookiesForURL(response.url);

const b2cState = {};
b2cState.codeVerifier = nonce;
b2cState.csrfToken = responseCookies['x-ms-cpim-csrf'][0];
b2cState.stateProperty = response.body.match('.*StateProperties=([^"]*)')[1];
return b2cState;
};

/**
* Helper function to get the authorization header for a user
* @param {user} user
* @returns {object} httpsOptions
*/
export const GetAuthorizationHeaderForUser = (user) => {
const token = GetB2cIdToken(user.username, user.password);

return {
headers: {
'Content-Type': 'application/json',
'Authorization': 'Bearer ' + token,
},
};
};

export default function () {
const token = GetB2cIdToken('USERNAME', 'PASSWORD');
console.log(token);
}
```

{{< /code >}}

### Okta

{{< code >}}
Expand All @@ -79,7 +280,14 @@ import encoding from 'k6/encoding';
* @param {string} scope - Space-separated list of scopes
* @param {string|object} resource - Either a resource ID (as string) or an object containing username and password
*/
export function authenticateUsingOkta(oktaDomain, authServerId, clientId, clientSecret, scope, resource) {
export function authenticateUsingOkta(
oktaDomain,
authServerId,
clientId,
clientSecret,
scope,
resource
) {
if (authServerId === 'undefined' || authServerId == '') {
authServerId = 'default';
}
Expand Down
2 changes: 0 additions & 2 deletions docs/sources/next/get-started/resources.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,6 @@ If you need a place to learn k6 and test your scripts, you can use these playgro

- [pizza.grafana.fun](https://pizza.grafana.fun/). A simple demo webapp. [grafana/quickpizza](https://github.com/grafana/quickpizza)
- [k6-http.grafana.fun](https://k6-http.grafana.fun). A simple HTTP Request & Response Service. [grafana/httpbin](https://github.com/grafana/httpbin)
- [k6-php.grafana.fun](https://k6-php.grafana.fun). A simple PHP website. [grafana/test.k6.io](https://github.com/grafana/test.k6.io)
- [test-api.k6.io](https://test-api.k6.io). A demo HTTP REST API with some WebSocket support. [grafana/test-api.k6.io](https://github.com/grafana/test-api.k6.io)
- [grpcbin.test.k6.io](https://grpcbin.test.k6.io/). A simple gRPC Request & Response Service. [grafana/k6-grpcbin](https://github.com/grafana/k6-grpcbin)

Note that these are shared testing environments - please avoid high-load tests. Alternatively, you can deploy and host them on your infrastructure and run the examples in the repository.
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
---
title: 'Faults'
excerpt: 'xk6-disruptor: Fault Description'
weight: 01
weight: 100
---

# Faults

A fault is as an abnormal condition that affects a system component and which may lead to a failure.

| Fault type | Description |
| ------------------------------------------------------------------------------------ | ------------------------------------------- |
| [gRPC Fault](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/grpc) | Fault affecting gRPC requests from a target |
| [HTTP Fault](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/http) | Fault affecting HTTP requests from a target |
| Fault type | Description |
| --------------------------------------------------------------------------------------------------------------------- | ------------------------------------------- |
| [gRPC Fault](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/grpc) | Fault affecting gRPC requests from a target |
| [HTTP Fault](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/http) | Fault affecting HTTP requests from a target |
| [Pod Termination Fault](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/pod-termination) | Fault terminating a number of target Pods |
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
---
title: 'Pod Termination'
description: 'xk6-disruptor: Pod Termination Fault attributes'
weight: 03
---

# Pod Termination

A Pod Termination Fault allows terminating either a fixed number or a percentage of the pods that matching a selector or back a service.

A Pod Termination fault is defined by the following attributes:

| Attribute | Type | Description |
| --------- | --------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| count | integer or percentage | the number of pods to be terminated. It can be specified as a integer number or as a percentage, for example `30%`, that defines the fraction of target pods to be terminated |

{{% admonition type="note" %}}

If the count is a percentage and there are no enough elements in the target pod list, the number is rounded up.
For example '25%' of a list of 2 target pods will terminate one pod.
If the list of target pods is not empty, at least one pod is always terminated.

{{% /admonition %}}

## Example

This example defines a PorTermination fault that will terminate `30%` of target pods

```javascript
const fault = {
count: '30%',
};
```
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
title: 'Get started'
excerpt: 'xk6-disruptor is an extension that adds fault injection capabilities to k6. Start here to learn the basics and how to use the disruptor'
weight: 01
weight: 01
---

# Get started
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: 'PodDisruptor'
excerpt: 'xk6-disruptor: PodDisruptor class'
weight: 02
weight: 200
---

# PodDisruptor
Expand All @@ -12,11 +12,12 @@ To construct a `PodDisruptor`, use the [PodDisruptor() constructor](https://graf

## Methods

| Method | Description |
| --------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------- |
| [PodDisruptor.injectGrpcFaults()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/poddisruptor/injectgrpcfaults) | Inject [gRPC faults](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/grpc) in the target Pods |
| [PodDisruptor.injectHTTPFaults()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/poddisruptor/injecthttpfaults) | Inject [HTTP faults](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/http) in the target Pods |
| PodDisruptor.targets() | Returns the list of target Pods of the PodDisruptor |
| Method | Description |
| -------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| [PodDisruptor.injectGrpcFaults()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/poddisruptor/injectgrpcfaults) | Inject [gRPC faults](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/grpc) in the target Pods |
| [PodDisruptor.injectHTTPFaults()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/poddisruptor/injecthttpfaults) | Inject [HTTP faults](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/http) in the target Pods |
| PodDisruptor.targets() | Returns the list of target Pods of the PodDisruptor |
| [PodDisruptor.terminatePods()](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/poddisruptor/terminate-pods) | executes a [Pod Termination fault](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/pod-termination) in the target Pods |

## Example

Expand Down Expand Up @@ -59,4 +60,4 @@ $ kubectl run nginx --image=nginx

You can also use the [xk6-kubernetes](https://github.com/grafana/xk6-kubernetes) extension for creating these resources from your test script.

{{% /admonition %}}
{{% /admonition %}}
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: 'Constructor'
excerpt: 'xk6-disruptor: PodDisruptor constructor'
weight: 01
weight: 100
---

# Constructor
Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
---
title: 'injectGrpcFaults()'
excerpt: 'xk6-disruptor: PodDisruptor.injectGrpcFaults method'
weight: 02
weight: 200
---

# injectGrpcFaults()

injectGrpcFaults injects gRPC faults in the requests served by a target Pod.

| Parameter | Type | Description |
| ------------------ | ------ | ---------------------------------------------------------------------------------------------------------------------- |
| Parameter | Type | Description |
| ------------------ | ------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| fault | object | description of the [gRPC faults](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/grpc) to be injected |
| duration | string | duration of the disruption |
| options (optional) | object | [options](#options) that control the injection of the fault |
| duration | string | duration of the disruption |
| options (optional) | object | [options](#options) that control the injection of the fault |

## options

Expand Down
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
---
title: 'injectHTTPFaults()'
excerpt: 'xk6-disruptor: PodDisruptor.injectHTTPFaults method'
weight: 03
weight: 300
---

# injectHTTPFaults()

injectHTTPFaults injects HTTP faults in the requests served by a target Pod.

| Parameter | Type | Description |
| ------------------ | ------ | ---------------------------------------------------------------------------------------------------------------------- |
| Parameter | Type | Description |
| ------------------ | ------ | ---------------------------------------------------------------------------------------------------------------------------------- |
| fault | object | description of the [http faults](https://grafana.com/docs/k6/<K6_VERSION>/javascript-api/xk6-disruptor/faults/http) to be injected |
| duration | string | duration of the disruption |
| options (optional) | object | [options](#options) that control the injection of the fault |
| duration | string | duration of the disruption |
| options (optional) | object | [options](#options) that control the injection of the fault |

## options

Expand All @@ -30,7 +30,7 @@ WARN\[0035\] Request Failed error="read tcp 172.18.0.1:43564->172.18.255.200:80:

This is normal and means that one request was "in transit" at the time the faults were injected, causing the request to fail from a network connection reset.

{{% /admonition %}}
{{% /admonition %}}

## Example

Expand Down
Loading
Loading