diff --git a/.env.development b/.env.development index 9b8e2098704b..f3bf5740a2a3 100644 --- a/.env.development +++ b/.env.development @@ -1 +1,2 @@ -GATSBY_GRAPHQL_IDE=playground +GATSBY_GRAPHQL_IDE=playground +GATSBY_DEV_AMENDED=false \ No newline at end of file diff --git a/.env.production b/.env.production new file mode 100644 index 000000000000..7a54a8a6e775 --- /dev/null +++ b/.env.production @@ -0,0 +1 @@ +GATSBY_DEV_AMENDED=false \ No newline at end of file diff --git a/.eslintrc.js b/.eslintrc.js index 573d5350fd4f..c6725eb1f412 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -94,5 +94,28 @@ module.exports = { "space-infix-ops": [ "error" ] - } + }, + "overrides": [ + { + "files": ["*.mdx", "*.md"], + "extends": ["plugin:mdx/recommended"], + "settings": { + "mdx/code-blocks": true, + "mdx/language-mapper": {}, + }, + "rules": { + //these eslint rule exceptions allow for checklint to run and lint mdx files are compatible with MDXv2, and not error out due to react/eslint rules + "semi": 0, + "indent": 0, + "no-trailing-spaces": 0, + "object-curly-spacing": 0, + "space-infix-ops": 0, + "no-irregular-whitespace": 0, + "no-unused-expressions": 0, + "linebreak-style": 0, + "react/jsx-no-undef": 0, + "no-unused-vars": 0, + } + } + ], }; diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index b16dfbc932ee..87be7d4c85db 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,29 +1,36 @@ ---- -name: 🐛 Bug Report -about: Report an issue to help us improve -title: '' -labels: 'kind/bug' -assignees: '' ---- -### Description - - -### Expected Behavior - - -### Screenshots - - -### Environment: -- Host OS: -- Browser: - ---- -

Contributor Resources and Handbook

- -The layer5.io website uses Gatsby, React, and GitHub Pages. Site content is found under the [`master` branch](https://github.com/layer5io/layer5/tree/master). -- 📚 See [contributing instructions](https://github.com/layer5io/layer5/blob/master/CONTRIBUTING.md). -- 🎨 Wireframes and [designs for Layer5 site](https://www.figma.com/file/5ZwEkSJwUPitURD59YHMEN/Layer5-Designs) in Figma [(open invite)](https://www.figma.com/team_invite/redeem/qJy1c95qirjgWQODApilR9) -- 🙋🏾🙋🏼 Questions: [Discussion Forum](https://discuss.layer5.io) and [Community Slack](https://slack.layer5.io). - -Join the Layer5 Community by submitting your [community member form](https://layer5.io/newcomer). +--- +name: 🐛 Bug Report +about: Report an issue to help us improve +title: "" +labels: "kind/bug" +assignees: "" +--- + +### Description + + + +### Expected Behavior + + + +### Screenshots + + + +### Environment: + +- Host OS: +- Browser: + +--- + +

Contributor Resources and Handbook

+ +The layer5.io website uses Gatsby, React, and GitHub Pages. Site content is found under the [`master` branch](https://github.com/layer5io/layer5/tree/master). + +- 📚 See [contributing instructions](https://github.com/layer5io/layer5/blob/master/CONTRIBUTING.md). +- 🎨 Wireframes and [designs for Layer5 site](https://www.figma.com/file/5ZwEkSJwUPitURD59YHMEN/Layer5-Designs) in Figma [(open invite)](https://www.figma.com/team_invite/redeem/qJy1c95qirjgWQODApilR9) +- 🙋🏾🙋🏼 Questions: [Discussion Forum](https://discuss.layer5.io) and [Community Slack](https://slack.layer5.io). + +Join the Layer5 Community by submitting your [community member form](https://layer5.io/newcomer). diff --git a/.github/ISSUE_TEMPLATE/chore_task.md b/.github/ISSUE_TEMPLATE/chore_task.md index aca67feb99b4..b12594d45209 100644 --- a/.github/ISSUE_TEMPLATE/chore_task.md +++ b/.github/ISSUE_TEMPLATE/chore_task.md @@ -1,22 +1,22 @@ ---- -name: 🧹Chore or task -about: Identify a necessary task to be addressed. -title: '' -labels: 'kind/chore' -assignees: '' ---- -### Current Behavior - - -### Desired Situation - - ---- -

Contributor Resources and Handbook

- -The layer5.io website uses Gatsby, React, and GitHub Pages. Site content is found under the [`master` branch](https://github.com/layer5io/layer5/tree/master). -- 📚 See [contributing instructions](https://github.com/layer5io/layer5/blob/master/CONTRIBUTING.md). -- 🎨 Wireframes and [designs for Layer5 site](https://www.figma.com/file/5ZwEkSJwUPitURD59YHMEN/Layer5-Designs) in Figma [(open invite)](https://www.figma.com/team_invite/redeem/qJy1c95qirjgWQODApilR9) -- 🙋🏾🙋🏼 Questions: [Discussion Forum](https://discuss.layer5.io) and [Community Slack](https://slack.layer5.io). - -Join the Layer5 Community by submitting your [community member form](https://layer5.io/newcomer). +--- +name: 🧹Chore or task +about: Identify a necessary task to be addressed. +title: '' +labels: 'kind/chore' +assignees: '' +--- +### Current Behavior + + +### Desired Situation + + +--- +

Contributor Resources and Handbook

+ +The layer5.io website uses Gatsby, React, and GitHub Pages. Site content is found under the [`master` branch](https://github.com/layer5io/layer5/tree/master). +- 📚 See [contributing instructions](https://github.com/layer5io/layer5/blob/master/CONTRIBUTING.md). +- 🎨 Wireframes and [designs for Layer5 site](https://www.figma.com/file/5ZwEkSJwUPitURD59YHMEN/Layer5-Designs) in Figma [(open invite)](https://www.figma.com/team_invite/redeem/qJy1c95qirjgWQODApilR9) +- 🙋🏾🙋🏼 Questions: [Discussion Forum](https://discuss.layer5.io) and [Community Slack](https://slack.layer5.io). + +Join the Layer5 Community by submitting your [community member form](https://layer5.io/newcomer). diff --git a/.github/ISSUE_TEMPLATE/sistent_feature.md b/.github/ISSUE_TEMPLATE/sistent_feature.md index 52444c480226..f90306130535 100644 --- a/.github/ISSUE_TEMPLATE/sistent_feature.md +++ b/.github/ISSUE_TEMPLATE/sistent_feature.md @@ -1,29 +1,29 @@ ---- -name: 🚀 Enhancement in Sistent Project -about: Propose a new feature, suggest a component, or report an issue for Sistent. -title: '[Sistent]' -labels: 'project/sistent, kind/enhancement' -assignees: '' ---- -### Current Behavior - - -### Desired Behavior - - -### Screenshots / Mockups - - -### Implementation - - ---- -

Contributor Resources and Handbook

- -The layer5.io website uses Gatsby, React, and GitHub Pages. Site content is found under the [`master` branch](https://github.com/layer5io/layer5/tree/master). -- 🎨 See [Sistent Repository](https://github.com/layer5io/sistent). -- 📚 See [contributing instructions](https://github.com/layer5io/layer5/blob/master/CONTRIBUTING.md). -- 🎨 Wireframes and [designs for Layer5 site](https://www.figma.com/file/5ZwEkSJwUPitURD59YHMEN/Layer5-Designs) in Figma [(open invite)](https://www.figma.com/team_invite/redeem/qJy1c95qirjgWQODApilR9) -- 🙋🏾🙋🏼 Questions: [Discussion Forum](https://discuss.layer5.io) and [Community Slack](https://slack.layer5.io). - -Join the Layer5 Community by submitting your [community member form](https://layer5.io/newcomer). +--- +name: 🚀 Enhancement in Sistent Project +about: Propose a new feature, suggest a component, or report an issue for Sistent. +title: '[Sistent]' +labels: 'project/sistent, kind/enhancement' +assignees: '' +--- +### Current Behavior + + +### Desired Behavior + + +### Screenshots / Mockups + + +### Implementation + + +--- +

Contributor Resources and Handbook

+ +The layer5.io website uses Gatsby, React, and GitHub Pages. Site content is found under the [`master` branch](https://github.com/layer5io/layer5/tree/master). +- 🎨 See [Sistent Repository](https://github.com/layer5io/sistent). +- 📚 See [contributing instructions](https://github.com/layer5io/layer5/blob/master/CONTRIBUTING.md). +- 🎨 Wireframes and [designs for Layer5 site](https://www.figma.com/file/5ZwEkSJwUPitURD59YHMEN/Layer5-Designs) in Figma [(open invite)](https://www.figma.com/team_invite/redeem/qJy1c95qirjgWQODApilR9) +- 🙋🏾🙋🏼 Questions: [Discussion Forum](https://discuss.layer5.io) and [Community Slack](https://slack.layer5.io). + +Join the Layer5 Community by submitting your [community member form](https://layer5.io/newcomer). diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ffce62888d59..49946dc705c3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,695 +1,695 @@ -# Contributing at Layer5 - -We are beyond excited to see that you want to contribute! We would love to accept your contributions. Layer5 is built by the community and warmly welcomes collaboration. There are many ways in which one could contribute to Layer5 and every contribution is equally appreciated here. Navigate through the following to understand more about contributing here. - -- [Before You Get Started](#before-you-get-started) -- [Contributing to Layer5 Projects](#contributing-to-layer5-projects) -- [Contributing to Layer5's Blogs](#contributing-to-layer5s-blogs) -- [Contributing to Layer5's Sistent](#contributing-to-layer5s-sistent) -- [How to Contribute](#how-to-contribute) - - [Prerequisites](#prerequisites) - - [Set up your Local Development Environment](#set-up-your-local-development-environment) - - [Signing-off on Commits](#signing-off-on-commits) - -⚠️ Cloning this repository ⚠️ - -Cloning the repo with all its history results in a ~6 GB download. To contribute to this site, you don't need its entire history. Use the `--depth=1` flag to significantly reduce the footprint this repo creates in your environment. - -```bash -git clone --depth=1 https://github.com/layer5io/layer5.git -``` - -# Before You Get Started - -## Code of Conduct - -Layer5 follows the [Cloud Native Computing Foundation (CNCF) Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). - -Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting community@layer5.io. -Violation of the code of conduct is taken seriously, kindly report any violations of the Code of Conduct by filling in the Incident report. -The comfort and safety of Layer5 community members are our priority. Please do well to adhere to the Code of Conduct to participate in the Layer5 community. - -## For Newcomers - -To help you get started on contributing to Layer5 projects, refer to the [Layer5 Newcomers Guide](https://layer5.io/community/newcomers), which aims to make contributions easier for new folks like you! See the resources and tutorials to help you get started. Along with this we have an extensive handbook on how this community works , how folks inside the community wear different hats to run it and few of its guidelines, have a look inside the [Community Handbook](https://layer5.io/community/handbook). - -## Issues & Pull Requests - -### Creating an Issue - -Before **creating** an Issue i.e for `features`/`bugs`/`improvements` please follow these steps: - - -1. Search existing Issues before creating a new Issue (look to see if the Issue has already been created). -1. If it doesn't exist create a new Issue giving as much context as possible (please take note and select the correct Issue type, for example `bug`, `documentation` or `feature`. -1. If you wish to work on the Issue once it has been triaged, please include this in your Issue description. - -### Working on an Issue - -Before working on an existing Issue please follow these steps: - -1. Comment asking for the Issue to be assigned to you. -1. To best position yourself for Issues assignment, we recommend that you: - 1. Confirm that you have read the CONTRIBUTING.md. - 1. Have a functional development environment (have built and are able to run the project). - 1. Convey your intended approach to solving the issue. - 1. Put each of these items in writing in one or more comments. -1. After the Issue is assigned to you, you can start working on it. -1. In general, **only** start working on this Issue (and open a Pull Request) when it has been assigned to you. Doing so will prevent confusion, duplicate work (some of which may go unaccepted given its duplicity), incidental stepping on toes, and the headache involved for maintainers and contributors alike as Issue assignments collide and heads bump together. -1. Reference the Issue in your Pull Request (for example `This PR fixes #123`). so that the corresponding Issue is automatically closed upon merge of your Pull Request. - -> Notes: -> -> - Check the `Assignees` box at the top of the page to see if the Issue has been assigned to someone else before requesting this be assigned to you. If the issue has a current Assignee, but appears to be inactive, politely inquire with the current Assignee as to whether they are still working on a solution and/or if you might collaborate with them. -> - Only request to be assigned an Issue if you know how to work on it. -> - If an Issue is unclear, ask questions to get more clarity before asking to have the Issue assigned to you; avoid asking "what do I do next? how do I fix this?" (see the item above this line) -> - An Issue can be assigned to multiple people, if you all agree to collaborate on the Issue (the Pull Request can contain commits from different collaborators) -> - Any Issues that has no activity after 2 weeks will be unassigned and re-assigned to someone else. - -## Reviewing Pull Requests - -We welcome everyone to review Pull Requests. It is a great way to learn, network, and support each other. - -### DOs - -- Use inline comments to explain your suggestions -- Use inline suggestions to propose changes -- Exercise patience and empathy while offering critiques of the works of others. - -### DON'Ts - -- Do not repeat feedback, this creates more noise than value (check the existing conversation), use GitHub reactions if you agree/disagree with a comment -- Do not blindly approve Pull Requests to improve your GitHub contributors graph - - -## Style Guide - -The Layer5 website is hosted in this repository and is built using Gatsbyjs. Before opening a Pull Request, please review the [design doc](https://docs.google.com/document/d/1rvUZy2_S1a2_14BAQIg6b9cMhUuu04kYzkOPDPaPptI/edit#) to learn more about the structure of the website. Once a Pull Request has been submitted, a preview deployment will be built and made available to you and other contributors on your PR to review. - -## Discussion Forum - -Join the [discussion forum](https://discuss.layer5.io/c/landscape/7) (the Landscape topic is appropriate for all layer5.io questions) to discuss suggested new features, possible bugs, enhancement in user experience, and any other aspects of the site. The discussion forum is our preferred method of communication, you can, however, also inquire in the [#websites](https://layer5io.slack.com/archives/C015QJKUMPU) channel in the Layer5 Slack workspace. - -# Contributing to Layer5 Projects - -Please follow these steps and note these guidelines to begin contributing: - -1. First step is to set up the local development environment. -1. Bug fixes are always welcome. Start by reviewing the [list of bugs](https://github.com/layer5io/layer5/labels/kind%2Fbug). -1. A good way to easily start contributing is to pick and work on a [good first issue](https://github.com/layer5io/layer5/labels/good%20first%20issue). We try to make these Issues as clear as possible and provide basic info on how the code should be changed, and if something is unclear feel free to ask for more information on the Issue. -1. We regularly discuss new Issues to work on in our [discussion forum](https://discuss.layer5.io/c/landscape/7) and the [#websites](https://layer5io.slack.com/archives/C015QJKUMPU) channel. Feel free to join and discuss any Issue or any idea that you may have. - -# Contributing to Layer5's Blogs Section - -If you'd like to contribute a post to layer5.io/blog, please open an Issue and suggest a topic. If you don't have a topic, then hop into the [#blog-kitchen](https://layer5io.slack.com/archives/C0210TZRF88) channel, and we'll help you find one. - -## Things to keep in mind - -1. We use inbuilt components called Call to Action(CTAs), prominently in our MarkDown(.mdx) files. Check out our [guide to CTAs](https://github.com/layer5io/layer5/blob/master/src/components/Call-To-Actions/README.md). - -## Adding a Blog Post - -1. In order to contribute a blog post, fork this repository, clone it, create a new branch and navigate to the `src/collections/blog` directory. -2. Create a copy of the [blog template](https://github.com/layer5io/layer5/tree/master/src/collections/blog/blog-template). -3. Follow the instructions included in the blog template and name the new file after the title of the blog article. -4. Entries will be listed in chronological order automatically. - -## Adding a Resource - -1. In order to contribute a resource, fork this repository, clone it, create a new branch and navigate to the `src/collections/resources` directory. -2. Create a copy of the [resource template](https://github.com/layer5io/layer5/tree/master/src/collections/resources/resources-template). -3. Follow the instructions included in the resource template and name the new file after the title of the resource. -4. Please note that different types of resources like `article`,`tutorial`, `webinars` are organized into separate folders inside the `/resource` collection. Add your entries in the respective folders. -5. To qualify any post as a resource, the field `resource: true` must be added. This applies for `/news`, `/blog`, `/events` as well. -6. Each resource can be associated with 4 additional fields: `type`, `mesh`, `technology` and `product`. The current list of values can be found from these [options](https://github.com/layer5io/layer5/blob/master/src/sections/Resources/Resources-grid/options.js). - -## Adding News - -1. In order to add/update news items, fork this repository, clone it, create a new branch, and navigate to the `src/collections/news` directory. -2. Create a copy of the [news template](https://github.com/layer5io/layer5/tree/master/src/collections/news/news-template/0000-00-00-news-title). -3. Follow the instructions included in the news template and name the new file after the title of the news article. -4. Entries will be listed in chronological order automatically. - -# Contributing to Layer5's Sistent - -If you'd like to contribute to Sistent, start by selecting the project/sistent label in the [#GitHub issue tracker](https://github.com/layer5io/layer5/labels/project%2Fsistent). - -### General Contribution Guidelines - -1. Select the [project/sistent](https://github.com/layer5io/layer5/labels/project%2Fsistent) label in the GitHub issue tracker. -1. Navigate to the relevant directory, such as: - ``` - src/sections/Projects/Sistent - ``` - > Note: For other parts of the project, the file path may vary. Ensure you're working in the correct file associated with the area you're contributing to. -1. Add or update content. The system dynamically generates pages and routes to maintain consistency. - -### Adding Sistent Component - -We've streamlined the process by introducing a dynamic page creation workflow, simplifying the addition of new pages and ensuring a consistent structure for all contributions. - -1. Navigate to the relevant directory, such as: - ``` - src/sections/Projects/Sistent - ``` -1. To add a new page, simply update this `content.js` file with the necessary details. All content is managed in a centralized file: - ``` - src/sections/Projects/Sistent/components/content.js - ``` -1. The system will dynamically generate pages based on this content and handle routing automatically. - -### Example -Refer to the [**Button component**](https://layer5.io/projects/sistent/components/button) in the Sistent Library for an example of how to structure the content. - -# Common Types of Site Contributions - -The following list of instructions pertains to commonplace site updates by contributors. - -## Things to keep in mind - -1. Prioritize using only the theme colors and hexcodes that are already being used in [themeStyles.js](https://github.com/layer5io/layer5/blob/master/src/theme/app/themeStyles.js) instead of introducing new color codes to the file. -2. Avoid adding `rel="noreferrer"` attribute to internal links on the site. Use gatsby [`` component](https://www.gatsbyjs.com/docs/linking-between-pages/) for internal links on the site. - -## Adding dark mode for components - -The site currently has dark and light mode, the colors used in these two modes can be found in the dark and light theme objects in [themeStyles.js](https://github.com/layer5io/layer5/blob/master/src/theme/app/themeStyles.js). - -These theme objects use a property whose value automatically changes based on the active theme without using a conditional. - -An example of a conditional: - -``` -theme === "dark" ? "white" : "black" -``` - -The preference is to **not use conditionals** for elements because they will flicker when reloading a page in dark mode. - -As currently constructed, the dark and light theme objects share similar property names that have different values. - -The property name will tell you how the value (color or hexcode) will change from dark mode to light mode. The first part is for dark mode, then "To", and the next part is for light mode. - -example #1: `whiteToBlack` - -"white" is the first part for dark mode -"To" -"Black" is the second part for light mode - -In dark mode the value of `whiteToBlack` will be `white` -In light mode the value of `whiteToBlack` will be `black` - -example #2: `grey141414ToGreyF5F5F5` - -In dark mode this value will be `#141414` (a dark shade of grey) -In light mode this value will be `#F5F5F5` (a light shade of grey). - -The hexcode in the property name is the indication of the color shade being used in the active theme. Always check the hexcode to confirm it is the desired shade/color. - -In a styled component, you can use the property name in the following way: - -#### Examples - -example #1: -`color: ${props => props.theme.whiteToBlack};` - -example #2: -`color: ${props => props.theme.greyDEE3DEToGreen3C494F}` - -### Adding a new color pair transition property - -It is recommended to use pre-existing styles, colors, hexcodes from the theme. Avoid adding your own CSS variables and incorporating new colors. - -If you must add a new property that changes with the theme: - -1. Add a new property with the same name to the dark and light theme objects in [themeStyles.js](https://github.com/layer5io/layer5/blob/master/src/theme/app/themeStyles.js) and the corresponding values you want them to have in each mode. - -#### Example: - -``` -const lighttheme = { - blue0000FFToRedFF0000: "#FF0000", -``` - -``` -const darktheme = { - blue0000FFToRedFF0000: "#0000FF", - -``` - -2. Use that property name in your styled component - -``` -color: ${props => props.theme.blue0000FFToRedFF0000}; -``` - -### Adding the transition property to the element in the styled component - -Transition property is not inherited. It must be added for each element that is changing colors and be consistent with the transition timing and style of the background color in [`GlobalStyle`](https://github.com/layer5io/layer5/blob/master/src/sections/app.style.js) to ensure uniform color change. - -Currently this property:value is - -``` -transition: 0.8s cubic-bezier(0.2, 0.8, 0.2, 1); -``` - -## Preferable SVG and Images - -- SVG or image does not need to change colors depending on the theme - -OR - -- SVG or image uses transparent sections that change with the background color to work with either theme. - -[Example of SVG file with transparent sections](https://github.com/layer5io/layer5/blob/master/src/assets/images/kanvas/icon-only/kanvas-icon-color.svg) - -[Example of image file with transparent sections](https://github.com/layer5io/layer5/blob/master/src/assets/images/app/projects/meshery-logo-light.webp) - -You can see these two examples in action [here](https://layer5.io/projects) by toggling the theme (located on the right side of the navigation bar). - -The above are the preferred kinds of SVG and images. If your SVG or image fits one of the descriptions above, then you do not need to read further. - -### Changing SVG according to theme - -SVG image formats are the preferred format because of the ability to control colors used to fill path or stroke with styled-components and have them change dependent on the theme without using a conditional. - -#### Importing SVG as a React Component - -To use the SVG as an `svg` element and not a source for an `img` element, we will import the SVG as a ReactComponent. You can see an example of importing the SVG as a ReactComponent in the code [here](https://github.com/layer5io/layer5/blob/master/src/sections/General/Navigation/index.js) - -``` -import { ReactComponent as Logo } from "../../../assets/images/app/layer5-colorMode.svg"; -``` - -Then we include the component where you want to display it - -``` - - - -``` - -#### Adding the color change property to the SVG - -To change a fill for a SVG depending on the theme, you will need to create a class in the SVG to fill inner paths or rect or polygon with default colors, then assign that SVG class in a styled-component to a property value as done in components. - -#### Example: Layer5 Logo - -To see the code for this SVG click [here](https://github.com/layer5io/layer5/blob/master/src/assets/images/app/layer5-colorMode.svg?short_path=e76da80). (note: if link is not working , click [here](https://github.com/layer5io/layer5/blob/master/src/assets/images/app/layer5-colorMode.svg) and then click the "<>" button to display the source blob.) - -In the SVG code, we see classes declared here: - -``` - - - -``` - -We use `colorMode[#]` in the class name to designate classes that we want to change depending on the theme. - -Then in the related styled component, we use a specific class generated by styled-components to add the theme property. - -In our example with the logo in the navigation, this is the relevant [styled component](https://github.com/layer5io/layer5/blob/master/src/sections/General/Navigation/navigation.style.js). - -Here, if we want to update the CSS of the SVG then we target the appropriate parent class. For this example, looking at the where the SVG React component (``) was placed, we see `className="logo"` as the relevant parent class. - -``` - - - -``` - -In the styled component, we find ".logo", add the `svg` element, and within that add the class that is generated by the styled-component plugin, in our example it is `.layer5-colorMode_svg__colorMode1`. - -> Note: the styled-component generated class name is based off the file name and the colorMode class name, using the following structure: -> -> svg file name (`layer5-colorMode`) - -- a separator (`_svg___`) -- the class name being targeted inside the SVG (`colorMode1`) - > this results in the class `.layer5-colorMode_svg__colorMode1` - -``` - .logo { - margin-top: 8px; - - svg { - width: 155px; - .layer5-colorMode_svg__colorMode1 { - fill: ${props => props.theme.whiteToGreen3C494F}; - transition: fill 0.8s cubic-bezier(0.2, 0.8, 0.2, 1); - } - } - } -``` - -> Notes: -> -> - You can add presentation css attributes to `svg` similar to how you would add to an `img`. -> - You can find the generated class name when you inspect the element in the browser console and look at the styles section of the svg code. -> - Even though we have a default fill property in the SVG itself (just in case), the fill property in the styled component will override it. -> - Whenever we are changing colors in a SVG, be sure to add the transition timing and style that is used for the background color in [GlobalStyle](https://github.com/layer5io/layer5/blob/master/src/sections/app.style.js) to have everything smoothly transition. Currently this property: value is -> -> ``` -> transition: 0.8s cubic-bezier(0.2, 0.8, 0.2, 1); -> ``` - -## Changing images depending on the theme. - -If possible we wish to avoid using images dependent on the theme because we are required to use a conditional (which will cause a flicker of the image when the page is reloaded). If necessary, please use the following instructions. - -1. To change images or SVG as the image source, according to the theme, you have to import the hook `useStyledDarkMode` from the following [folder](https://github.com/layer5io/layer5/blob/master/src/theme/app/useStyledDarkMode.js), and then use the `isDark` value from `useStyledDarkMode` hook for the conditional. - -For example, you can view the code for [this file](https://github.com/layer5io/layer5/blob/master/src/sections/Kanvas/Kanvas-collaborate/kanvas-collaborate-banner.js). - -Here are the relevant parts of the code: - -``` -import { useStyledDarkMode } from "../../../theme/app/useStyledDarkMode"; - -const { isDark } = useStyledDarkMode(); - - -``` - -## Changing images in gatsby-image-plugin according to the theme. - -Procedure of changing the image for the gatsby-image is the same as we change for images, however, it is recommended to fetch two images, one for a dark theme and one for a light theme change it according to the `isDark` value as done with images. - -Example (For Thumbnail): -Fetching images through Graphql. Add this in graphql query in frontmatter - - darkthumbnail { - childImageSharp { - gatsbyImageData(layout: FULL_WIDTH) - } - extension - publicURL - } - -Change image according to isDark value: - -``` -{frontmatter.title} -``` - -> Note: -> -> - A condition `frontmatter.darkthumbnail.publicURL !== frontmatter.thumbnail.publicURL` is added so that the image only changes if there is a difference between the thumbnail publicURLs. - -## Adding Images and Icons - -1. It is recommended to use `@react-icons/all-files` instead of `react-icons` for importing icons. The Issue with react-icons is that even though we are importing a single icon from the package/folder it still imports the complete icon folder which is creating unwanted junks of JS in the build. -2. It is recommended to use Gatsby's `` instead of `` tag to display static images on the site **except for SVG images**. This performs automatic image optimization, thereby improving site performance. -3. Avoid creating duplicate copies of the same image under different folders. All images must be imported from `/assets/images` folder. - -## Site Performance Considerations - -1. Analyze page load metrics of mobile version in lighthouse report (see status of GitHub workflow on your open PR). -2. While creating a new page make sure to use Gatsby Head API for SEO. -3. Prefer using `loading="eager"` for Hero images to improve LCP(Largest Contentful Paint) and FCP(First Contentful Paint). -4. Optimise page by deferring loading of third party scripts. You can use [off-main-thread](https://www.gatsbyjs.com/docs/reference/built-in-components/gatsby-script/#off-main-thread-strategy-experimental) in Script API. -5. Prefer Code Splitting using [loadable](https://github.com/gregberge/loadable-components) to lazy load heavy components which are not in the viewport. - -Note:- You can also refer to [Improving Site Performance](https://www.gatsbyjs.com/docs/how-to/performance/improving-site-performance/), [web.dev](https://web.dev/vitals/). - -## Updating/Creating a Community Member Profile - -Layer5 community members are an integral part of what makes Layer5 and its projects successful. Prominently highlighting our members and their works is something that we think is important. To initiate adding a new or updating an existing community member profile, be sure to use the community member [issue template](https://github.com/layer5io/layer5/issues/new?assignees=&labels=area%2Fcommunity%2C+help+wanted%2C+framework%2Fgatsby%2C+language%2Fmarkdown%2C+good+first+issue&template=community_member_profile.md&title=%5BCommunity%5D+Member+Profile%3A). When creating or updating a community member profile, use the [profile template](https://github.com/layer5io/layer5/tree/master/src/collections/members/_member-profile-template). You can easily understand how the template is used by reviewing other profiles. - -### Badges for Community Members - -Badges are a great way of highlighting the area of contribution by any given community member. A variety of badges exist so that community members and their efforts may be affiliated with a particular project or with a community initiative. An example of how a badge is assigned using markdown can be found [here](https://github.com/layer5io/layer5/blob/master/src/collections/members/lee-calcote/index.mdx), and it will appear [this way](https://layer5.io/community/members/lee-calcote) on a member profile. - -#### Possible Badges: - -- Community -- Docker Extension -- Docs -- Meshery Catalog -- Kanvas -- Landscape -- ImageHub -- Meshery -- Meshery Operator -- SMP -- Nighthawk -- Patterns -- UI/UX Design -- Writer Program - -## Updating the Service Mesh Landscape - -Another common site update includes the updation of the Service Mesh Landscape. The service mesh landscape is powered by Gatsby.js. To update the landscape, fork this repository, clone it, create a branch and navigate to the **src/collections/landscape** folder. - -Make sure to open a [new issue](https://github.com/layer5io/layer5/issues/new?assignees=&labels=area%2Flandscape&template=landscape.md&title=%5BLandscape%5D) first. Following is a list of files that you may edit and make the necessary updates (if appropriate): - -- [non-functional.js](https://github.com/layer5io/layer5/blob/master/src/collections/landscape/non-functional.js) - overview of various service meshes -- [meshes.js](https://github.com/layer5io/layer5/blob/master/src/collections/landscape/meshes.js) - list of individual service mesh details -- [proxies.js](https://github.com/layer5io/layer5/blob/master/src/collections/landscape/proxies.js) - list of individual modern proxies -- [gateway.js](https://github.com/layer5io/layer5/blob/master/src/collections/landscape/gateways.js) - list of API gateways -- [load-balancer.js](https://github.com/layer5io/layer5/blob/master/src/collections/landscape/load-balancer.js) - list of load balancers - -Entries should be listed in alphabetical order. Data provided to the `smi.js` is dynamic and based upon results from conformance tests run using Meshery. - -To update the Service Mesh Timeline, add the new service mesh in the [non-functional.js](https://github.com/layer5io/layer5/blob/master/src/collections/landscape/non-functional.js) file. Add an `announce-date` key for the service mesh, then add a `timeline-order` key having a value 1+`maximum value of timeline-order` till now, to list the service mesh in the timeline correctly. - -# How to Contribute - -## Prerequisites - -Make sure you have the following prerequisites installed on your operating system before you start contributing: - -- [Nodejs and npm](https://nodejs.org/en/) - - To verify run: - - ``` - node -v - ``` - - ``` - npm -v - ``` - -- [Gatsby.js](https://www.gatsbyjs.com/) - - To verify run: - - ``` - gatsby --version - ``` - -**Note:** If you're on a _Windows environment_ then it is highly recommended that you install [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/install) both for performance and ease of use. Refer to the [documentation](https://docs.microsoft.com/en-us/windows/dev-environment/javascript/gatsby-on-wsl) for the installation of _Gatsby.js on WSL_. - -## Set up your Local Development Environment - -Follow the following instructions to start contributing. - -**1.** Fork [this](https://github.com/layer5io/layer5) repository. - -**2.** Clone your forked copy of the project. - -``` -git clone --depth=1 https://github.com//layer5.git -``` - -**3.** Navigate to the project directory. - -``` -cd layer5 -``` - -**4.** Add a reference(remote) to the original repository. - -``` -git remote add upstream https://github.com/layer5io/layer5.git -``` - -**5.** Check the remotes for this repository. - -``` -git remote -v -``` - -**6.** Always take a pull from the upstream repository to your master branch to keep it at par with the main project (updated repository). - -``` -git pull upstream master -``` - -**7.** Create a new branch. - -``` -git checkout -b -``` - -**8.** Install the dependencies for running the site. - -``` -make setup -``` - -**9.** Make the desired changes. - -**10.** Run the site locally to preview changes. - -``` -make site -``` - -This will run a local webserver with "live reload" conveniently enabled. ( **NOTE**: while using the make command on Windows, there sometimes arises an error in identifying the command even after it is installed (unrecognized command), this is because the PATH for the binary might not be set correctly ). - -**11.** Track your changes. - -``` -git add . -``` - -**12.** Commit your changes. To contribute to this project, you must agree to the [Developer Certificate of Origin (DCO)](#signing-off-on-commits) for each commit you make. - -``` -git commit --signoff -m "" -``` - -or you could go with the shorter format for the same, as shown below. - -``` -git commit -s -m "" -``` - -**13.** While you are working on your branch, other developers may update the `master` branch with their branch. This action means your branch is now out of date with the `master` branch and missing content. So to fetch the new changes, follow along: - -``` -git checkout master -git fetch origin master -git merge upstream/master -git push origin -``` - -Now you need to merge the `master` branch into your branch. This can be done in the following way: - -``` -git checkout -git merge master -``` - -**14.** Push the committed changes in your feature branch to your remote repo. - -``` -git push -u origin -``` - -**15.** Once you’ve committed and pushed all of your changes to GitHub, go to the page for your fork on GitHub, select your development branch, and click the pull request button. Please ensure that you compare your feature branch to the desired branch of the repo you are supposed to make a PR to. If you need to make any adjustments to your pull request, just push the updates to GitHub. Your pull request will automatically track the changes in your development branch and update it. - -### Lint Rules - -Layer5 uses ESLint to maintain code quality and consistency in our UI code. Use this command to trigger a lint check: - -```sh -make lint -``` - -> Note: -> - Eslint in Gatsby requires generating config files from CLI. Run `gatsby build` or `gatsby develop` if you face this error during linting. - - -## Signing-off on Commits - -To contribute to this project, you must agree to the **Developer Certificate of -Origin (DCO)** for each commit you make. The DCO is a simple statement that you, -as a contributor, have the legal right to make the contribution. - -See the [DCO](https://developercertificate.org) file for the full text of what you must agree to -and how it works [here](https://github.com/probot/dco#how-it-works). -To signify that you agree to the DCO for contributions, you simply add a line to each of your -git commit messages: - -``` -Signed-off-by: Jane Smith -``` - -**Note:** you don't have to manually include this line on your commits, git does that for you as shown below: - -``` -$ git commit -s -m “my commit message w/signoff” -``` - -In most cases, git automatically adds the signoff to your commit with the use of -`-s` or `--signoff` flag to `git commit`. You must use your real name and a reachable email -address (sorry, no pseudonyms or anonymous contributions). - -To ensure all your commits are signed, you may choose to add this alias to your global `.gitconfig`: - -_~/.gitconfig_ - -``` -[alias] - amend = commit -s --amend - cm = commit -s -m - commit = commit -s -``` - -Or you may configure your IDE, for example, Visual Studio Code to automatically sign-off commits for you: - - - -## FYI regarding the dev environment - -### Dev and Browser Warnings You May Encounter - -Note: - -- These are **non-blocking warnings** you can expect to see in your terminal or browser while working in local development environment. -- They do not impact the performance of the code and are unrelated to your contributions. -- These will not show in `build` or `production` mode. -- These are being documented to minimize confusion for the user while doing development. - ---- - -> warn ./node_modules/react-accessible-accordion/dist/es/index.js -> Attempted import error: 'useId' is not exported from 'react' (imported as 'useId'). - -and - -> client.js:196 export 'useId' (imported as 'useId') was not found in 'react' (possible exports: Children, Component, Fragment, Profiler, PureComponent, StrictMode, Suspense, \_\_SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, cloneElement, createContext, createElement, createFactory, createRef, forwardRef, isValidElement, lazy, memo, useCallback, useContext, useDebugValue, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState, version) - -Where/When: - -- In terminal: after `npm start` -- In browser: loading https://layer5.io - -Reason: [https://github.com/springload/react-accessible-accordion/issues/351](https://github.com/springload/react-accessible-accordion/issues/351) - -> V5 is a release we cut explicitly for React 18 support (Hence the major upgrade, this was a breaking change, the webpack fix would not work as we are using React 18 new APIs), we are sticking with V4 for React 17 and under compatibility, using V4 has no functional difference outside of React version compatibility. - -Layer5 currently using: -"react-accessible-accordion": "^5.0.0" -react": "^17.0.2" - -To clear the warning: -Upgrade the `react`package to ^18. However upgrading may introduce too many breaking changes and complexity. - ---- - -> Warning: Each child in a list should have a unique "key" prop. -> Check the top-level render call using . See https://reactjs.org/link/warning-keys for more information. -> at title - -Where/When: - -- In terminal: after `npm start` and loading page - -Reason: In this version of Gatsby (4.20), the file: -`node_modules/gatsby/cache-dir/head/head-export-handler-for-ssr.js` is missing code to assign `key` prop to each head tag included in the `SEO` component. - -To clear the warning: -This could be resolved by adding code to the package, but requires too much complexity to include for each user. This warning is cleared in later versions of Gatsby. +# Contributing at Layer5 + +We are beyond excited to see that you want to contribute! We would love to accept your contributions. Layer5 is built by the community and warmly welcomes collaboration. There are many ways in which one could contribute to Layer5 and every contribution is equally appreciated here. Navigate through the following to understand more about contributing here. + +- [Before You Get Started](#before-you-get-started) +- [Contributing to Layer5 Projects](#contributing-to-layer5-projects) +- [Contributing to Layer5's Blogs](#contributing-to-layer5s-blogs) +- [Contributing to Layer5's Sistent](#contributing-to-layer5s-sistent) +- [How to Contribute](#how-to-contribute) + - [Prerequisites](#prerequisites) + - [Set up your Local Development Environment](#set-up-your-local-development-environment) + - [Signing-off on Commits](#signing-off-on-commits) + +⚠️ Cloning this repository ⚠️ + +Cloning the repo with all its history results in a ~6 GB download. To contribute to this site, you don't need its entire history. Use the `--depth=1` flag to significantly reduce the footprint this repo creates in your environment. + +```bash +git clone --depth=1 https://github.com/layer5io/layer5.git +``` + +# Before You Get Started + +## Code of Conduct + +Layer5 follows the [Cloud Native Computing Foundation (CNCF) Code of Conduct](https://github.com/cncf/foundation/blob/master/code-of-conduct.md). + +Instances of abusive, harassing, or otherwise unacceptable behavior may be reported by contacting community@layer5.io. +Violation of the code of conduct is taken seriously, kindly report any violations of the Code of Conduct by filling in the Incident report. +The comfort and safety of Layer5 community members are our priority. Please do well to adhere to the Code of Conduct to participate in the Layer5 community. + +## For Newcomers + +To help you get started on contributing to Layer5 projects, refer to the [Layer5 Newcomers Guide](https://layer5.io/community/newcomers), which aims to make contributions easier for new folks like you! See the resources and tutorials to help you get started. Along with this we have an extensive handbook on how this community works , how folks inside the community wear different hats to run it and few of its guidelines, have a look inside the [Community Handbook](https://layer5.io/community/handbook). + +## Issues & Pull Requests + +### Creating an Issue + +Before **creating** an Issue i.e for `features`/`bugs`/`improvements` please follow these steps: + + +1. Search existing Issues before creating a new Issue (look to see if the Issue has already been created). +1. If it doesn't exist create a new Issue giving as much context as possible (please take note and select the correct Issue type, for example `bug`, `documentation` or `feature`. +1. If you wish to work on the Issue once it has been triaged, please include this in your Issue description. + +### Working on an Issue + +Before working on an existing Issue please follow these steps: + +1. Comment asking for the Issue to be assigned to you. +1. To best position yourself for Issues assignment, we recommend that you: + 1. Confirm that you have read the CONTRIBUTING.md. + 1. Have a functional development environment (have built and are able to run the project). + 1. Convey your intended approach to solving the issue. + 1. Put each of these items in writing in one or more comments. +1. After the Issue is assigned to you, you can start working on it. +1. In general, **only** start working on this Issue (and open a Pull Request) when it has been assigned to you. Doing so will prevent confusion, duplicate work (some of which may go unaccepted given its duplicity), incidental stepping on toes, and the headache involved for maintainers and contributors alike as Issue assignments collide and heads bump together. +1. Reference the Issue in your Pull Request (for example `This PR fixes #123`). so that the corresponding Issue is automatically closed upon merge of your Pull Request. + +> Notes: +> +> - Check the `Assignees` box at the top of the page to see if the Issue has been assigned to someone else before requesting this be assigned to you. If the issue has a current Assignee, but appears to be inactive, politely inquire with the current Assignee as to whether they are still working on a solution and/or if you might collaborate with them. +> - Only request to be assigned an Issue if you know how to work on it. +> - If an Issue is unclear, ask questions to get more clarity before asking to have the Issue assigned to you; avoid asking "what do I do next? how do I fix this?" (see the item above this line) +> - An Issue can be assigned to multiple people, if you all agree to collaborate on the Issue (the Pull Request can contain commits from different collaborators) +> - Any Issues that has no activity after 2 weeks will be unassigned and re-assigned to someone else. + +## Reviewing Pull Requests + +We welcome everyone to review Pull Requests. It is a great way to learn, network, and support each other. + +### DOs + +- Use inline comments to explain your suggestions +- Use inline suggestions to propose changes +- Exercise patience and empathy while offering critiques of the works of others. + +### DON'Ts + +- Do not repeat feedback, this creates more noise than value (check the existing conversation), use GitHub reactions if you agree/disagree with a comment +- Do not blindly approve Pull Requests to improve your GitHub contributors graph + + +## Style Guide + +The Layer5 website is hosted in this repository and is built using Gatsbyjs. Before opening a Pull Request, please review the [design doc](https://docs.google.com/document/d/1rvUZy2_S1a2_14BAQIg6b9cMhUuu04kYzkOPDPaPptI/edit#) to learn more about the structure of the website. Once a Pull Request has been submitted, a preview deployment will be built and made available to you and other contributors on your PR to review. + +## Discussion Forum + +Join the [discussion forum](https://discuss.layer5.io/c/landscape/7) (the Landscape topic is appropriate for all layer5.io questions) to discuss suggested new features, possible bugs, enhancement in user experience, and any other aspects of the site. The discussion forum is our preferred method of communication, you can, however, also inquire in the [#websites](https://layer5io.slack.com/archives/C015QJKUMPU) channel in the Layer5 Slack workspace. + +# Contributing to Layer5 Projects + +Please follow these steps and note these guidelines to begin contributing: + +1. First step is to set up the local development environment. +1. Bug fixes are always welcome. Start by reviewing the [list of bugs](https://github.com/layer5io/layer5/labels/kind%2Fbug). +1. A good way to easily start contributing is to pick and work on a [good first issue](https://github.com/layer5io/layer5/labels/good%20first%20issue). We try to make these Issues as clear as possible and provide basic info on how the code should be changed, and if something is unclear feel free to ask for more information on the Issue. +1. We regularly discuss new Issues to work on in our [discussion forum](https://discuss.layer5.io/c/landscape/7) and the [#websites](https://layer5io.slack.com/archives/C015QJKUMPU) channel. Feel free to join and discuss any Issue or any idea that you may have. + +# Contributing to Layer5's Blogs Section + +If you'd like to contribute a post to layer5.io/blog, please open an Issue and suggest a topic. If you don't have a topic, then hop into the [#blog-kitchen](https://layer5io.slack.com/archives/C0210TZRF88) channel, and we'll help you find one. + +## Things to keep in mind + +1. We use inbuilt components called Call to Action(CTAs), prominently in our MarkDown(.mdx) files. Check out our [guide to CTAs](https://github.com/layer5io/layer5/blob/master/src/components/Call-To-Actions/README.md). + +## Adding a Blog Post + +1. In order to contribute a blog post, fork this repository, clone it, create a new branch and navigate to the `src/collections/blog` directory. +2. Create a copy of the [blog template](https://github.com/layer5io/layer5/tree/master/src/collections/blog/blog-template). +3. Follow the instructions included in the blog template and name the new file after the title of the blog article. +4. Entries will be listed in chronological order automatically. + +## Adding a Resource + +1. In order to contribute a resource, fork this repository, clone it, create a new branch and navigate to the `src/collections/resources` directory. +2. Create a copy of the [resource template](https://github.com/layer5io/layer5/tree/master/src/collections/resources/resources-template). +3. Follow the instructions included in the resource template and name the new file after the title of the resource. +4. Please note that different types of resources like `article`,`tutorial`, `webinars` are organized into separate folders inside the `/resource` collection. Add your entries in the respective folders. +5. To qualify any post as a resource, the field `resource: true` must be added. This applies for `/news`, `/blog`, `/events` as well. +6. Each resource can be associated with 4 additional fields: `type`, `mesh`, `technology` and `product`. The current list of values can be found from these [options](https://github.com/layer5io/layer5/blob/master/src/sections/Resources/Resources-grid/options.js). + +## Adding News + +1. In order to add/update news items, fork this repository, clone it, create a new branch, and navigate to the `src/collections/news` directory. +2. Create a copy of the [news template](https://github.com/layer5io/layer5/tree/master/src/collections/news/news-template/0000-00-00-news-title). +3. Follow the instructions included in the news template and name the new file after the title of the news article. +4. Entries will be listed in chronological order automatically. + +# Contributing to Layer5's Sistent + +If you'd like to contribute to Sistent, start by selecting the project/sistent label in the [#GitHub issue tracker](https://github.com/layer5io/layer5/labels/project%2Fsistent). + +### General Contribution Guidelines + +1. Select the [project/sistent](https://github.com/layer5io/layer5/labels/project%2Fsistent) label in the GitHub issue tracker. +1. Navigate to the relevant directory, such as: + ``` + src/sections/Projects/Sistent + ``` + > Note: For other parts of the project, the file path may vary. Ensure you're working in the correct file associated with the area you're contributing to. +1. Add or update content. The system dynamically generates pages and routes to maintain consistency. + +### Adding Sistent Component + +We've streamlined the process by introducing a dynamic page creation workflow, simplifying the addition of new pages and ensuring a consistent structure for all contributions. + +1. Navigate to the relevant directory, such as: + ``` + src/sections/Projects/Sistent + ``` +1. To add a new page, simply update this `content.js` file with the necessary details. All content is managed in a centralized file: + ``` + src/sections/Projects/Sistent/components/content.js + ``` +1. The system will dynamically generate pages based on this content and handle routing automatically. + +### Example +Refer to the [**Button component**](https://layer5.io/projects/sistent/components/button) in the Sistent Library for an example of how to structure the content. + +# Common Types of Site Contributions + +The following list of instructions pertains to commonplace site updates by contributors. + +## Things to keep in mind + +1. Prioritize using only the theme colors and hexcodes that are already being used in [themeStyles.js](https://github.com/layer5io/layer5/blob/master/src/theme/app/themeStyles.js) instead of introducing new color codes to the file. +2. Avoid adding `rel="noreferrer"` attribute to internal links on the site. Use gatsby [`` component](https://www.gatsbyjs.com/docs/linking-between-pages/) for internal links on the site. + +## Adding dark mode for components + +The site currently has dark and light mode, the colors used in these two modes can be found in the dark and light theme objects in [themeStyles.js](https://github.com/layer5io/layer5/blob/master/src/theme/app/themeStyles.js). + +These theme objects use a property whose value automatically changes based on the active theme without using a conditional. + +An example of a conditional: + +``` +theme === "dark" ? "white" : "black" +``` + +The preference is to **not use conditionals** for elements because they will flicker when reloading a page in dark mode. + +As currently constructed, the dark and light theme objects share similar property names that have different values. + +The property name will tell you how the value (color or hexcode) will change from dark mode to light mode. The first part is for dark mode, then "To", and the next part is for light mode. + +example #1: `whiteToBlack` + +"white" is the first part for dark mode +"To" +"Black" is the second part for light mode + +In dark mode the value of `whiteToBlack` will be `white` +In light mode the value of `whiteToBlack` will be `black` + +example #2: `grey141414ToGreyF5F5F5` + +In dark mode this value will be `#141414` (a dark shade of grey) +In light mode this value will be `#F5F5F5` (a light shade of grey). + +The hexcode in the property name is the indication of the color shade being used in the active theme. Always check the hexcode to confirm it is the desired shade/color. + +In a styled component, you can use the property name in the following way: + +#### Examples + +example #1: +`color: ${props => props.theme.whiteToBlack};` + +example #2: +`color: ${props => props.theme.greyDEE3DEToGreen3C494F}` + +### Adding a new color pair transition property + +It is recommended to use pre-existing styles, colors, hexcodes from the theme. Avoid adding your own CSS variables and incorporating new colors. + +If you must add a new property that changes with the theme: + +1. Add a new property with the same name to the dark and light theme objects in [themeStyles.js](https://github.com/layer5io/layer5/blob/master/src/theme/app/themeStyles.js) and the corresponding values you want them to have in each mode. + +#### Example: + +``` +const lighttheme = { + blue0000FFToRedFF0000: "#FF0000", +``` + +``` +const darktheme = { + blue0000FFToRedFF0000: "#0000FF", + +``` + +2. Use that property name in your styled component + +``` +color: ${props => props.theme.blue0000FFToRedFF0000}; +``` + +### Adding the transition property to the element in the styled component + +Transition property is not inherited. It must be added for each element that is changing colors and be consistent with the transition timing and style of the background color in [`GlobalStyle`](https://github.com/layer5io/layer5/blob/master/src/sections/app.style.js) to ensure uniform color change. + +Currently this property:value is + +``` +transition: 0.8s cubic-bezier(0.2, 0.8, 0.2, 1); +``` + +## Preferable SVG and Images + +- SVG or image does not need to change colors depending on the theme + +OR + +- SVG or image uses transparent sections that change with the background color to work with either theme. + +[Example of SVG file with transparent sections](https://github.com/layer5io/layer5/blob/master/src/assets/images/kanvas/icon-only/kanvas-icon-color.svg) + +[Example of image file with transparent sections](https://github.com/layer5io/layer5/blob/master/src/assets/images/app/projects/meshery-logo-light.webp) + +You can see these two examples in action [here](https://layer5.io/projects) by toggling the theme (located on the right side of the navigation bar). + +The above are the preferred kinds of SVG and images. If your SVG or image fits one of the descriptions above, then you do not need to read further. + +### Changing SVG according to theme + +SVG image formats are the preferred format because of the ability to control colors used to fill path or stroke with styled-components and have them change dependent on the theme without using a conditional. + +#### Importing SVG as a React Component + +To use the SVG as an `svg` element and not a source for an `img` element, we will import the SVG as a ReactComponent. You can see an example of importing the SVG as a ReactComponent in the code [here](https://github.com/layer5io/layer5/blob/master/src/sections/General/Navigation/index.js) + +``` +import { ReactComponent as Logo } from "../../../assets/images/app/layer5-colorMode.svg"; +``` + +Then we include the component where you want to display it + +``` + + + +``` + +#### Adding the color change property to the SVG + +To change a fill for a SVG depending on the theme, you will need to create a class in the SVG to fill inner paths or rect or polygon with default colors, then assign that SVG class in a styled-component to a property value as done in components. + +#### Example: Layer5 Logo + +To see the code for this SVG click [here](https://github.com/layer5io/layer5/blob/master/src/assets/images/app/layer5-colorMode.svg?short_path=e76da80). (note: if link is not working , click [here](https://github.com/layer5io/layer5/blob/master/src/assets/images/app/layer5-colorMode.svg) and then click the "<>" button to display the source blob.) + +In the SVG code, we see classes declared here: + +``` + + + +``` + +We use `colorMode[#]` in the class name to designate classes that we want to change depending on the theme. + +Then in the related styled component, we use a specific class generated by styled-components to add the theme property. + +In our example with the logo in the navigation, this is the relevant [styled component](https://github.com/layer5io/layer5/blob/master/src/sections/General/Navigation/navigation.style.js). + +Here, if we want to update the CSS of the SVG then we target the appropriate parent class. For this example, looking at the where the SVG React component (``) was placed, we see `className="logo"` as the relevant parent class. + +``` + + + +``` + +In the styled component, we find ".logo", add the `svg` element, and within that add the class that is generated by the styled-component plugin, in our example it is `.layer5-colorMode_svg__colorMode1`. + +> Note: the styled-component generated class name is based off the file name and the colorMode class name, using the following structure: +> +> svg file name (`layer5-colorMode`) + +- a separator (`_svg___`) +- the class name being targeted inside the SVG (`colorMode1`) + > this results in the class `.layer5-colorMode_svg__colorMode1` + +``` + .logo { + margin-top: 8px; + + svg { + width: 155px; + .layer5-colorMode_svg__colorMode1 { + fill: ${props => props.theme.whiteToGreen3C494F}; + transition: fill 0.8s cubic-bezier(0.2, 0.8, 0.2, 1); + } + } + } +``` + +> Notes: +> +> - You can add presentation css attributes to `svg` similar to how you would add to an `img`. +> - You can find the generated class name when you inspect the element in the browser console and look at the styles section of the svg code. +> - Even though we have a default fill property in the SVG itself (just in case), the fill property in the styled component will override it. +> - Whenever we are changing colors in a SVG, be sure to add the transition timing and style that is used for the background color in [GlobalStyle](https://github.com/layer5io/layer5/blob/master/src/sections/app.style.js) to have everything smoothly transition. Currently this property: value is +> +> ``` +> transition: 0.8s cubic-bezier(0.2, 0.8, 0.2, 1); +> ``` + +## Changing images depending on the theme. + +If possible we wish to avoid using images dependent on the theme because we are required to use a conditional (which will cause a flicker of the image when the page is reloaded). If necessary, please use the following instructions. + +1. To change images or SVG as the image source, according to the theme, you have to import the hook `useStyledDarkMode` from the following [folder](https://github.com/layer5io/layer5/blob/master/src/theme/app/useStyledDarkMode.js), and then use the `isDark` value from `useStyledDarkMode` hook for the conditional. + +For example, you can view the code for [this file](https://github.com/layer5io/layer5/blob/master/src/sections/Kanvas/Kanvas-collaborate/kanvas-collaborate-banner.js). + +Here are the relevant parts of the code: + +``` +import { useStyledDarkMode } from "../../../theme/app/useStyledDarkMode"; + +const { isDark } = useStyledDarkMode(); + + +``` + +## Changing images in gatsby-image-plugin according to the theme. + +Procedure of changing the image for the gatsby-image is the same as we change for images, however, it is recommended to fetch two images, one for a dark theme and one for a light theme change it according to the `isDark` value as done with images. + +Example (For Thumbnail): +Fetching images through Graphql. Add this in graphql query in frontmatter + + darkthumbnail { + childImageSharp { + gatsbyImageData(layout: FULL_WIDTH) + } + extension + publicURL + } + +Change image according to isDark value: + +``` +{frontmatter.title} +``` + +> Note: +> +> - A condition `frontmatter.darkthumbnail.publicURL !== frontmatter.thumbnail.publicURL` is added so that the image only changes if there is a difference between the thumbnail publicURLs. + +## Adding Images and Icons + +1. It is recommended to use `@react-icons/all-files` instead of `react-icons` for importing icons. The Issue with react-icons is that even though we are importing a single icon from the package/folder it still imports the complete icon folder which is creating unwanted junks of JS in the build. +2. It is recommended to use Gatsby's `` instead of `` tag to display static images on the site **except for SVG images**. This performs automatic image optimization, thereby improving site performance. +3. Avoid creating duplicate copies of the same image under different folders. All images must be imported from `/assets/images` folder. + +## Site Performance Considerations + +1. Analyze page load metrics of mobile version in lighthouse report (see status of GitHub workflow on your open PR). +2. While creating a new page make sure to use Gatsby Head API for SEO. +3. Prefer using `loading="eager"` for Hero images to improve LCP(Largest Contentful Paint) and FCP(First Contentful Paint). +4. Optimise page by deferring loading of third party scripts. You can use [off-main-thread](https://www.gatsbyjs.com/docs/reference/built-in-components/gatsby-script/#off-main-thread-strategy-experimental) in Script API. +5. Prefer Code Splitting using [loadable](https://github.com/gregberge/loadable-components) to lazy load heavy components which are not in the viewport. + +Note:- You can also refer to [Improving Site Performance](https://www.gatsbyjs.com/docs/how-to/performance/improving-site-performance/), [web.dev](https://web.dev/vitals/). + +## Updating/Creating a Community Member Profile + +Layer5 community members are an integral part of what makes Layer5 and its projects successful. Prominently highlighting our members and their works is something that we think is important. To initiate adding a new or updating an existing community member profile, be sure to use the community member [issue template](https://github.com/layer5io/layer5/issues/new?assignees=&labels=area%2Fcommunity%2C+help+wanted%2C+framework%2Fgatsby%2C+language%2Fmarkdown%2C+good+first+issue&template=community_member_profile.md&title=%5BCommunity%5D+Member+Profile%3A). When creating or updating a community member profile, use the [profile template](https://github.com/layer5io/layer5/tree/master/src/collections/members/_member-profile-template). You can easily understand how the template is used by reviewing other profiles. + +### Badges for Community Members + +Badges are a great way of highlighting the area of contribution by any given community member. A variety of badges exist so that community members and their efforts may be affiliated with a particular project or with a community initiative. An example of how a badge is assigned using markdown can be found [here](https://github.com/layer5io/layer5/blob/master/src/collections/members/lee-calcote/index.mdx), and it will appear [this way](https://layer5.io/community/members/lee-calcote) on a member profile. + +#### Possible Badges: + +- Community +- Docker Extension +- Docs +- Meshery Catalog +- Kanvas +- Landscape +- ImageHub +- Meshery +- Meshery Operator +- SMP +- Nighthawk +- Patterns +- UI/UX Design +- Writer Program + +## Updating the Service Mesh Landscape + +Another common site update includes the updation of the Service Mesh Landscape. The service mesh landscape is powered by Gatsby.js. To update the landscape, fork this repository, clone it, create a branch and navigate to the **src/collections/landscape** folder. + +Make sure to open a [new issue](https://github.com/layer5io/layer5/issues/new?assignees=&labels=area%2Flandscape&template=landscape.md&title=%5BLandscape%5D) first. Following is a list of files that you may edit and make the necessary updates (if appropriate): + +- [non-functional.js](https://github.com/layer5io/layer5/blob/master/src/collections/landscape/non-functional.js) - overview of various service meshes +- [meshes.js](https://github.com/layer5io/layer5/blob/master/src/collections/landscape/meshes.js) - list of individual service mesh details +- [proxies.js](https://github.com/layer5io/layer5/blob/master/src/collections/landscape/proxies.js) - list of individual modern proxies +- [gateway.js](https://github.com/layer5io/layer5/blob/master/src/collections/landscape/gateways.js) - list of API gateways +- [load-balancer.js](https://github.com/layer5io/layer5/blob/master/src/collections/landscape/load-balancer.js) - list of load balancers + +Entries should be listed in alphabetical order. Data provided to the `smi.js` is dynamic and based upon results from conformance tests run using Meshery. + +To update the Service Mesh Timeline, add the new service mesh in the [non-functional.js](https://github.com/layer5io/layer5/blob/master/src/collections/landscape/non-functional.js) file. Add an `announce-date` key for the service mesh, then add a `timeline-order` key having a value 1+`maximum value of timeline-order` till now, to list the service mesh in the timeline correctly. + +# How to Contribute + +## Prerequisites + +Make sure you have the following prerequisites installed on your operating system before you start contributing: + +- [Nodejs and npm](https://nodejs.org/en/) + + To verify run: + + ``` + node -v + ``` + + ``` + npm -v + ``` + +- [Gatsby.js](https://www.gatsbyjs.com/) + + To verify run: + + ``` + gatsby --version + ``` + +**Note:** If you're on a _Windows environment_ then it is highly recommended that you install [Windows Subsystem for Linux (WSL)](https://docs.microsoft.com/en-us/windows/wsl/install) both for performance and ease of use. Refer to the [documentation](https://docs.microsoft.com/en-us/windows/dev-environment/javascript/gatsby-on-wsl) for the installation of _Gatsby.js on WSL_. + +## Set up your Local Development Environment + +Follow the following instructions to start contributing. + +**1.** Fork [this](https://github.com/layer5io/layer5) repository. + +**2.** Clone your forked copy of the project. + +``` +git clone --depth=1 https://github.com//layer5.git +``` + +**3.** Navigate to the project directory. + +``` +cd layer5 +``` + +**4.** Add a reference(remote) to the original repository. + +``` +git remote add upstream https://github.com/layer5io/layer5.git +``` + +**5.** Check the remotes for this repository. + +``` +git remote -v +``` + +**6.** Always take a pull from the upstream repository to your master branch to keep it at par with the main project (updated repository). + +``` +git pull upstream master +``` + +**7.** Create a new branch. + +``` +git checkout -b +``` + +**8.** Install the dependencies for running the site. + +``` +make setup +``` + +**9.** Make the desired changes. + +**10.** Run the site locally to preview changes. + +``` +make site +``` + +This will run a local webserver with "live reload" conveniently enabled. ( **NOTE**: while using the make command on Windows, there sometimes arises an error in identifying the command even after it is installed (unrecognized command), this is because the PATH for the binary might not be set correctly ). + +**11.** Track your changes. + +``` +git add . +``` + +**12.** Commit your changes. To contribute to this project, you must agree to the [Developer Certificate of Origin (DCO)](#signing-off-on-commits) for each commit you make. + +``` +git commit --signoff -m "" +``` + +or you could go with the shorter format for the same, as shown below. + +``` +git commit -s -m "" +``` + +**13.** While you are working on your branch, other developers may update the `master` branch with their branch. This action means your branch is now out of date with the `master` branch and missing content. So to fetch the new changes, follow along: + +``` +git checkout master +git fetch origin master +git merge upstream/master +git push origin +``` + +Now you need to merge the `master` branch into your branch. This can be done in the following way: + +``` +git checkout +git merge master +``` + +**14.** Push the committed changes in your feature branch to your remote repo. + +``` +git push -u origin +``` + +**15.** Once you’ve committed and pushed all of your changes to GitHub, go to the page for your fork on GitHub, select your development branch, and click the pull request button. Please ensure that you compare your feature branch to the desired branch of the repo you are supposed to make a PR to. If you need to make any adjustments to your pull request, just push the updates to GitHub. Your pull request will automatically track the changes in your development branch and update it. + +### Lint Rules + +Layer5 uses ESLint to maintain code quality and consistency in our UI code. Use this command to trigger a lint check: + +```sh +make lint +``` + +> Note: +> - Eslint in Gatsby requires generating config files from CLI. Run `gatsby build` or `gatsby develop` if you face this error during linting. + + +## Signing-off on Commits + +To contribute to this project, you must agree to the **Developer Certificate of +Origin (DCO)** for each commit you make. The DCO is a simple statement that you, +as a contributor, have the legal right to make the contribution. + +See the [DCO](https://developercertificate.org) file for the full text of what you must agree to +and how it works [here](https://github.com/probot/dco#how-it-works). +To signify that you agree to the DCO for contributions, you simply add a line to each of your +git commit messages: + +``` +Signed-off-by: Jane Smith +``` + +**Note:** you don't have to manually include this line on your commits, git does that for you as shown below: + +``` +$ git commit -s -m “my commit message w/signoff” +``` + +In most cases, git automatically adds the signoff to your commit with the use of +`-s` or `--signoff` flag to `git commit`. You must use your real name and a reachable email +address (sorry, no pseudonyms or anonymous contributions). + +To ensure all your commits are signed, you may choose to add this alias to your global `.gitconfig`: + +_~/.gitconfig_ + +``` +[alias] + amend = commit -s --amend + cm = commit -s -m + commit = commit -s +``` + +Or you may configure your IDE, for example, Visual Studio Code to automatically sign-off commits for you: + + + +## FYI regarding the dev environment + +### Dev and Browser Warnings You May Encounter + +Note: + +- These are **non-blocking warnings** you can expect to see in your terminal or browser while working in local development environment. +- They do not impact the performance of the code and are unrelated to your contributions. +- These will not show in `build` or `production` mode. +- These are being documented to minimize confusion for the user while doing development. + +--- + +> warn ./node_modules/react-accessible-accordion/dist/es/index.js +> Attempted import error: 'useId' is not exported from 'react' (imported as 'useId'). + +and + +> client.js:196 export 'useId' (imported as 'useId') was not found in 'react' (possible exports: Children, Component, Fragment, Profiler, PureComponent, StrictMode, Suspense, \_\_SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED, cloneElement, createContext, createElement, createFactory, createRef, forwardRef, isValidElement, lazy, memo, useCallback, useContext, useDebugValue, useEffect, useImperativeHandle, useLayoutEffect, useMemo, useReducer, useRef, useState, version) + +Where/When: + +- In terminal: after `npm start` +- In browser: loading https://layer5.io + +Reason: [https://github.com/springload/react-accessible-accordion/issues/351](https://github.com/springload/react-accessible-accordion/issues/351) + +> V5 is a release we cut explicitly for React 18 support (Hence the major upgrade, this was a breaking change, the webpack fix would not work as we are using React 18 new APIs), we are sticking with V4 for React 17 and under compatibility, using V4 has no functional difference outside of React version compatibility. + +Layer5 currently using: +"react-accessible-accordion": "^5.0.0" +react": "^17.0.2" + +To clear the warning: +Upgrade the `react`package to ^18. However upgrading may introduce too many breaking changes and complexity. + +--- + +> Warning: Each child in a list should have a unique "key" prop. +> Check the top-level render call using . See https://reactjs.org/link/warning-keys for more information. +> at title + +Where/When: + +- In terminal: after `npm start` and loading page + +Reason: In this version of Gatsby (4.20), the file: +`node_modules/gatsby/cache-dir/head/head-export-handler-for-ssr.js` is missing code to assign `key` prop to each head tag included in the `SEO` component. + +To clear the warning: +This could be resolved by adding code to the package, but requires too much complexity to include for each user. This warning is cleared in later versions of Gatsby. diff --git a/content-learn/mastering-kubernetes-for-engineers/index.mdx b/content-learn/mastering-kubernetes-for-engineers/index.mdx index 8d4d3cc692fa..6ef8a21dfad6 100644 --- a/content-learn/mastering-kubernetes-for-engineers/index.mdx +++ b/content-learn/mastering-kubernetes-for-engineers/index.mdx @@ -1,14 +1,14 @@ ---- -title: 'Mastering Kubernetes for Engineers' -description: 'Learn how to configure your Kubernetes clusters and manage the lifecycle of your workloads' -order: 4 -themeColor: '#3C494F' -cardImage: '../../src/assets/images/meshery/icon-only/meshery-logo-light.webp' -courses: 0 -disabled: yes ---- - - \ No newline at end of file +--- +title: 'Mastering Kubernetes for Engineers' +description: 'Learn how to configure your Kubernetes clusters and manage the lifecycle of your workloads' +order: 4 +themeColor: '#3C494F' +cardImage: '../../src/assets/images/meshery/icon-only/meshery-logo-light.webp' +courses: 0 +disabled: yes +--- + +{/* + This file is only used to render the courses list within a learning path. + Check the Learn-Layer5 folder under src/sections/, src/templates for more understanding of how the data is used +*/} \ No newline at end of file diff --git a/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/index.mdx b/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/index.mdx index 6b6c163414a9..6824ba130603 100644 --- a/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/index.mdx +++ b/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/index.mdx @@ -1,35 +1,29 @@ ---- -docType: "Course" -title: "Course" -description: "A course which teaches advanced concepts of service meshes and how to use them in an application effectively." -courseTitle: "Advance Concepts of Service Meshes - Hands On" -themeColor: "#466BB0" -order: 2 -videos: 3 -lectures: 8 -cardImage: "../../../src/assets/images/service-mesh-icons/istio-white.svg" -meshesYouLearn: - [ - { - imagepath: "../../../src/assets/images/service-mesh-icons/istio.svg", - name: "Istio", - }, - { - imagepath: "../../../src/assets/images/service-mesh-icons/linkerd.webp", - name: "Linkerd", - } - ] -toc: - [ - 'getting-started', - 'deploy-an-application', - 'expose-services', - 'observability', - 'traffic-management', - 'service-security-capabilities', - 'webassembly-and-intelligent-data-planes', - 'conclusion', - ] ---- - -Chapters available +--- +docType: "Course" +title: "Course" +description: "A course which teaches advanced concepts of service meshes and how to use them in an application effectively." +courseTitle: "Advance Concepts of Service Meshes - Hands On" +themeColor: "#466BB0" +order: 2 +videos: 3 +lectures: 8 +cardImage: "../../../src/assets/images/service-mesh-icons/istio-white.svg" +meshesYouLearn: + - imagepath: "../../../src/assets/images/service-mesh-icons/istio.svg" + name: "Istio" + - imagepath: "../../../src/assets/images/service-mesh-icons/linkerd.webp" + name: "Linkerd" +toc: + [ + 'getting-started', + 'deploy-an-application', + 'expose-services', + 'observability', + 'traffic-management', + 'service-security-capabilities', + 'webassembly-and-intelligent-data-planes', + 'conclusion', + ] +--- + +Chapters available diff --git a/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/conclusion.mdx b/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/conclusion.mdx index 30a396acc55f..6dc00f5195df 100644 --- a/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/conclusion.mdx +++ b/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/conclusion.mdx @@ -1,27 +1,27 @@ ---- -docType: "Chapter" -chapterTitle: "Conclusion" -description: "As a self-service engineering platform, Meshery enables collaborative design and operation of cloud native infrastructure." -videos: 4 -lectures: 12 -order: 8 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; - - - -
- -

Congratulations!

- -
- You have successfully completed the course on{" "} - "Advanced concepts of service meshes - Hands on" using{" "} - - Istio - - . -
- -
+--- +docType: "Chapter" +chapterTitle: "Conclusion" +description: "As a self-service engineering platform, Meshery enables collaborative design and operation of cloud native infrastructure." +videos: 4 +lectures: 12 +order: 8 +--- + + + + + +
+ +

Congratulations!

+ +
+ You have successfully completed the course on{" "} + "Advanced concepts of service meshes - Hands on" using{" "} + + Istio + + . +
+ +
diff --git a/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/deploy-an-application.mdx b/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/deploy-an-application.mdx index 94bcc81fd124..ace14314bd7b 100644 --- a/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/deploy-an-application.mdx +++ b/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/deploy-an-application.mdx @@ -1,219 +1,219 @@ ---- -docType: "Chapter" -chapterTitle: "Deploy a sample application" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 2 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; -import BookInfoOffMesh from "../../../../src/assets/images/learn-layer5/istio/bookinfo-off-mesh.webp"; -import BookInfoOnMesh from "../../../../src/assets/images/learn-layer5/istio/bookinfo-on-mesh.webp"; - - - -To play with Istio and demonstrate some of it's capabilities, you will deploy the example BookInfo application, which is included the Istio package. - -

What is the Bookinfo Application

-
-This application is a polyglot composition of microservices are written in -different languages and sample BookInfo application displays information about a -book, similar to a single catalog entry of an online book store. Displayed on -the page is a description of the book, book details (ISBN, number of pages, and -so on), and a few book reviews. - -The end-to-end architecture of the application is shown in the figure. - -
-
- - - -_Figure: BookInfo deployed off the mesh_ - -
-It’s worth noting that these services have no dependencies on Istio, but make an -interesting service mesh example, particularly because of the multitude of services, -languages and versions for the reviews service. - -As shown in the figure below, proxies are sidecarred to each of the application containers. - -
- - - - -_Figure: BookInfo deployed on the mesh_ - -
-Sidecars proxy can be either manually or automatically injected into the pods. Automatic -sidecar injection requires that your Kubernetes api-server supports `admissionregistration.k8s.io/v1` -or `admissionregistration.k8s.io/v1beta1` or `admissionregistration.k8s.io/v1beta2` -APIs. Verify whether your Kubernetes deployment supports these APIs by executing: - -```sh -kubectl api-versions | grep admissionregistration -``` - -If your environment **does NOT** supports either of these two APIs, then you may use [manual sidecar injection](#manual-sidecar-inj) to deploy the sample app. - -As part of Istio deployment in [Previous chapter](./getting-started), you have deployed the sidecar injector. - -
-

- Deploying Sample App with Automatic sidecar injection -

- -
-Istio, deployed as part of this workshop, will also deploy the sidecar injector. -Let us now verify sidecar injector deployment. - -```sh -kubectl -n istio-system get configmaps istio-sidecar-injector -``` - -Output: - -```sh -NAME DATA AGE -istio-sidecar-injector 2 9h -``` - -NamespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the [selector](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors). - -```sh -kubectl get namespace -L istio-injection -``` - -Output: - -```sh -NAME STATUS AGE ISTIO-INJECTION -default Active 1h enabled -istio-system Active 1h disabled -kube-public Active 1h -kube-system Active 1h -``` - -Using Meshery, navigate to the Istio management page. - -1. Enter `default` in the `Namespace` field. -1. Click the (+) icon on the `Sample Application` card and select `BookInfo Application` from the list. - -This will do 3 things: - -1. Label `default` namespace for sidecar injection. -1. Deploys all the BookInfo services in the `default` namespace. -1. Deploys the virtual service and gateway needed to expose the BookInfo's productpage application in the `default` namespace. - -

- Verify Bookinfo deployment{" "} -

- -1. Verify that the deployments are all in a state of AVAILABLE before continuing. - -```sh -watch kubectl get deployment -``` - -2. Choose a service, for instance `productpage`, and view it's container configuration: - -```sh -kubectl get po - -kubectl describe pod productpage-v1-..... -``` - -3. Examine details of the services: - -```sh -kubectl describe svc productpage -``` - -Next, you will expose the BookInfo application to be accessed external from the cluster. - -
-

Alternative: Manual installation

-Follow this if the above steps did not work for you -
-
- -

Label namespace for injection

- -Label the default namespace with istio-injection=enabled - -```sh -kubectl label namespace default istio-injection=enabled -``` - -```sh -kubectl get namespace -L istio-injection -``` - -Output: - -```sh -NAME STATUS AGE ISTIO-INJECTION -default Active 1h enabled -istio-system Active 1h disabled -kube-public Active 1h -kube-system Active 1h -``` - -

Deploy BookInfo

-
- -Applying this yaml file included in the Istio package you collected in [Getting Started](./getting-started) will deploy the BookInfo app in you cluster. - -```sh -kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -``` - -

- Deploy Gateway and Virtual Service for BookInfo app -

- -```sh -kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml -``` - -
-
- -

- - Manual Sidecar Injection -

- -

Use this only when Automatic Sidecar injection doesn't work

- -To do a manual sidecar injection we will be using `istioctl` command: - -```sh -curl https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/platform/kube/bookinfo.yaml | istioctl kube-inject -f - > newBookInfo.yaml -``` - -Observing the new yaml file reveals that additional container Istio Proxy has been added to the Pods with necessary configurations: - -``` - image: docker.io/istio/proxyv2:1.3.0 - imagePullPolicy: IfNotPresent - name: istio-proxy -``` - -We need to now deploy the new yaml using `kubectl` - -```sh -kubectl apply -f newBookInfo.yaml -``` - -To do both in a single command: - -```sh -kubectl apply -f <(curl https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/platform/kube/bookinfo.yaml | istioctl kube-inject -f -) -``` - -Now continue to [Verify Bookinfo deployment](#verify). - - +--- +docType: "Chapter" +chapterTitle: "Deploy a sample application" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 2 +--- + + +import BookInfoOffMesh from "../../../../src/assets/images/learn-layer5/istio/bookinfo-off-mesh.webp"; +import BookInfoOnMesh from "../../../../src/assets/images/learn-layer5/istio/bookinfo-on-mesh.webp"; + + + +To play with Istio and demonstrate some of it's capabilities, you will deploy the example BookInfo application, which is included the Istio package. + +

What is the Bookinfo Application

+
+This application is a polyglot composition of microservices are written in +different languages and sample BookInfo application displays information about a +book, similar to a single catalog entry of an online book store. Displayed on +the page is a description of the book, book details (ISBN, number of pages, and +so on), and a few book reviews. + +The end-to-end architecture of the application is shown in the figure. + +
+
+ + + +_Figure: BookInfo deployed off the mesh_ + +
+It’s worth noting that these services have no dependencies on Istio, but make an +interesting service mesh example, particularly because of the multitude of services, +languages and versions for the reviews service. + +As shown in the figure below, proxies are sidecarred to each of the application containers. + +
+ + + + +_Figure: BookInfo deployed on the mesh_ + +
+Sidecars proxy can be either manually or automatically injected into the pods. Automatic +sidecar injection requires that your Kubernetes api-server supports `admissionregistration.k8s.io/v1` +or `admissionregistration.k8s.io/v1beta1` or `admissionregistration.k8s.io/v1beta2` +APIs. Verify whether your Kubernetes deployment supports these APIs by executing: + +```sh +kubectl api-versions | grep admissionregistration +``` + +If your environment **does NOT** supports either of these two APIs, then you may use [manual sidecar injection](#manual-sidecar-inj) to deploy the sample app. + +As part of Istio deployment in [Previous chapter](./getting-started), you have deployed the sidecar injector. + +
+

+ Deploying Sample App with Automatic sidecar injection +

+ +
+Istio, deployed as part of this workshop, will also deploy the sidecar injector. +Let us now verify sidecar injector deployment. + +```sh +kubectl -n istio-system get configmaps istio-sidecar-injector +``` + +Output: + +```sh +NAME DATA AGE +istio-sidecar-injector 2 9h +``` + +NamespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the [selector](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors). + +```sh +kubectl get namespace -L istio-injection +``` + +Output: + +```sh +NAME STATUS AGE ISTIO-INJECTION +default Active 1h enabled +istio-system Active 1h disabled +kube-public Active 1h +kube-system Active 1h +``` + +Using Meshery, navigate to the Istio management page. + +1. Enter `default` in the `Namespace` field. +1. Click the (+) icon on the `Sample Application` card and select `BookInfo Application` from the list. + +This will do 3 things: + +1. Label `default` namespace for sidecar injection. +1. Deploys all the BookInfo services in the `default` namespace. +1. Deploys the virtual service and gateway needed to expose the BookInfo's productpage application in the `default` namespace. + +

+ Verify Bookinfo deployment{" "} +

+ +1. Verify that the deployments are all in a state of AVAILABLE before continuing. + +```sh +watch kubectl get deployment +``` + +2. Choose a service, for instance `productpage`, and view it's container configuration: + +```sh +kubectl get po + +kubectl describe pod productpage-v1-..... +``` + +3. Examine details of the services: + +```sh +kubectl describe svc productpage +``` + +Next, you will expose the BookInfo application to be accessed external from the cluster. + +
+

Alternative: Manual installation

+Follow this if the above steps did not work for you +
+
+ +

Label namespace for injection

+ +Label the default namespace with istio-injection=enabled + +```sh +kubectl label namespace default istio-injection=enabled +``` + +```sh +kubectl get namespace -L istio-injection +``` + +Output: + +```sh +NAME STATUS AGE ISTIO-INJECTION +default Active 1h enabled +istio-system Active 1h disabled +kube-public Active 1h +kube-system Active 1h +``` + +

Deploy BookInfo

+
+ +Applying this yaml file included in the Istio package you collected in [Getting Started](./getting-started) will deploy the BookInfo app in you cluster. + +```sh +kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml +``` + +

+ Deploy Gateway and Virtual Service for BookInfo app +

+ +```sh +kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml +``` + +
+
+ +

+ + Manual Sidecar Injection +

+ +

Use this only when Automatic Sidecar injection doesn't work

+ +To do a manual sidecar injection we will be using `istioctl` command: + +```sh +curl https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/platform/kube/bookinfo.yaml | istioctl kube-inject -f - > newBookInfo.yaml +``` + +Observing the new yaml file reveals that additional container Istio Proxy has been added to the Pods with necessary configurations: + +``` + image: docker.io/istio/proxyv2:1.3.0 + imagePullPolicy: IfNotPresent + name: istio-proxy +``` + +We need to now deploy the new yaml using `kubectl` + +```sh +kubectl apply -f newBookInfo.yaml +``` + +To do both in a single command: + +```sh +kubectl apply -f <(curl https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/platform/kube/bookinfo.yaml | istioctl kube-inject -f -) +``` + +Now continue to [Verify Bookinfo deployment](#verify). + + diff --git a/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/expose-services.mdx b/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/expose-services.mdx index a19a0e925e59..b1a4a316dc70 100644 --- a/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/expose-services.mdx +++ b/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/expose-services.mdx @@ -1,253 +1,253 @@ ---- -docType: "Chapter" -chapterTitle: "Exposing services through Istio Ingress Gateway" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 3 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; - - -The components deployed on the service mesh by default are not exposed outside the cluster. An Ingress Gateway is deployed as a Kubernetes service of type LoadBalancer (or NodePort). To make Bookinfo accessible external to the cluster, you have to create an `Istio Gateway` for the Bookinfo application and also define an `Istio VirtualService` with the routes we need. - -
-
- -

Inspecting the Istio Ingress Gateway

- -
-The ingress gateway gets exposed as a normal Kubernetes service of type LoadBalancer -(or NodePort): - -```sh -kubectl get svc istio-ingressgateway -n istio-system -o yaml -``` - -Because the Istio Ingress Gateway is an Envoy Proxy you can inspect it using the admin routes. First find the name of the istio-ingressgateway: - -```sh -kubectl get pods -n istio-system -``` - -Copy and paste your ingress gateway's pod name. Execute: - -```sh -kubectl -n istio-system exec -it bash -``` - -You can view the statistics, listeners, routes, clusters and server info for the Envoy proxy by forwarding the local port: - -```sh -curl localhost:15000/help -curl localhost:15000/stats -curl localhost:15000/listeners -curl localhost:15000/clusters -curl localhost:15000/server_info -``` - -See the [admin docs](https://www.envoyproxy.io/docs/envoy/latest/operations/admin) for more details. - -Also it can be helpful to look at the log files of the Istio ingress controller to see what request is being routed. - -Before we check the logs, let us get out of the container back on the host: - -```sh -exit -``` - -Now let us find the ingress pod and output the log: - -```sh -kubectl logs istio-ingressgateway-... -n istio-system -``` - -

View Istio Ingress Gateway for Bookinfo

-
- -

View the Gateway and VirtualServices

- -Check the created `Istio Gateway` and `Istio VirtualService` to see the changes deployed: - -```sh -kubectl get gateway -kubectl get gateway -o yaml - -kubectl get virtualservices -kubectl get virtualservices -o yaml -``` - -

- Find the external port of the Istio Ingress Gateway by running: -

- -```sh -kubectl get service istio-ingressgateway -n istio-system -o wide -``` - -To just get the first port of istio-ingressgateway service, we can run this: - -```sh -kubectl get service istio-ingressgateway -n istio-system --template='{{(index .spec.ports 1).nodePort}}' -``` - -

Create a DNS entry:

- -Modify your local `/etc/hosts` file to add an entry for your sample application. - -`127.0.0.1. bookinfo.meshery.io` - -The HTTP port is usually 31380. - -Or run these commands to retrieve the full URL: - -```sh -echo "http://$(kubectl get nodes --selector=kubernetes.io/role!=master -o jsonpath={.items[0].status.addresses[?\(@.type==\"InternalIP\"\)].address}):$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[1].nodePort}')/productpage" -``` - -Docker Desktop users please use `http://localhost/productpage` to access product page in your browser. - -

Apply default destination rules

- -Before we start playing with Istio's traffic management capabilities we need to define the available versions of the deployed services. They are called subsets, in destination rules. - -Using Meshery, navigate to the Custom yaml page, and apply the below to create the subsets for BookInfo: - -```sh -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: - name: productpage -spec: - host: productpage - subsets: - - name: v1 - labels: - version: v1 ---- -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: - name: reviews -spec: - host: reviews - subsets: - - name: v1 - labels: - version: v1 - - name: v2 - labels: - version: v2 - - name: v3 - labels: - version: v3 ---- -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: - name: ratings -spec: - host: ratings - subsets: - - name: v1 - labels: - version: v1 - - name: v2 - labels: - version: v2 - - name: v2-mysql - labels: - version: v2-mysql - - name: v2-mysql-vm - labels: - version: v2-mysql-vm ---- -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: - name: details -spec: - host: details - subsets: - - name: v1 - labels: - version: v1 - - name: v2 - labels: - version: v2 -``` - -This creates destination rules for each of the BookInfo services and defines version subsets - -In a few seconds we should be able to verify the destination rules created by using the command below: - -```sh -kubectl get destinationrules - - -kubectl get destinationrules -o yaml -``` - -

Browse to BookInfo

- -Browse to the website of the Bookinfo. To view the product page, you will have to append -`/productpage` to the url. - -

Reload Page

- -Now, reload the page multiple times and notice how it round robins between v1, v2 and v3 of the reviews service. - -

- Inspect the Istio proxy of the productpage pod -

- -To better understand the istio proxy, let's inspect the details. Let us `exec` into the productpage pod to find the proxy details. To do so we need to first find the full pod name and then `exec` into the istio-proxy container: - -```sh -kubectl get pods -kubectl exec -it productpage-v1-... -c istio-proxy sh -``` - -Once in the container look at some of the envoy proxy details by inspecting it's config file: - -```sh -ps aux -ls -l /etc/istio/proxy -cat /etc/istio/proxy/envoy-rev0.json -``` - -For more details on envoy proxy please check out their [admin docs](https://www.envoyproxy.io/docs/envoy/v1.5.0/operations/admin). - -As a last step, lets exit the container: - -```sh -exit -``` - -
-

Alternative: Manual installation

-Follow this if the above steps did not work for you - -
-
- -

Default destination rules

- -Run the following command to create default destination rules for the Bookinfo services: - -```sh -kubectl apply -f samples/bookinfo/networking/destination-rule-all-mtls.yaml -``` - -

- Configure the Bookinfo route with the Istio Ingress gateway -

- -We can create a virtualservice & gateway for bookinfo app in the ingress gateway by running the following: - -```sh -kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml -``` - -
+--- +docType: "Chapter" +chapterTitle: "Exposing services through Istio Ingress Gateway" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 3 +--- + + + + +The components deployed on the service mesh by default are not exposed outside the cluster. An Ingress Gateway is deployed as a Kubernetes service of type LoadBalancer (or NodePort). To make Bookinfo accessible external to the cluster, you have to create an `Istio Gateway` for the Bookinfo application and also define an `Istio VirtualService` with the routes we need. + +
+
+ +

Inspecting the Istio Ingress Gateway

+ +
+The ingress gateway gets exposed as a normal Kubernetes service of type LoadBalancer +(or NodePort): + +```sh +kubectl get svc istio-ingressgateway -n istio-system -o yaml +``` + +Because the Istio Ingress Gateway is an Envoy Proxy you can inspect it using the admin routes. First find the name of the istio-ingressgateway: + +```sh +kubectl get pods -n istio-system +``` + +Copy and paste your ingress gateway's pod name. Execute: + +```sh +kubectl -n istio-system exec -it bash +``` + +You can view the statistics, listeners, routes, clusters and server info for the Envoy proxy by forwarding the local port: + +```sh +curl localhost:15000/help +curl localhost:15000/stats +curl localhost:15000/listeners +curl localhost:15000/clusters +curl localhost:15000/server_info +``` + +See the [admin docs](https://www.envoyproxy.io/docs/envoy/latest/operations/admin) for more details. + +Also it can be helpful to look at the log files of the Istio ingress controller to see what request is being routed. + +Before we check the logs, let us get out of the container back on the host: + +```sh +exit +``` + +Now let us find the ingress pod and output the log: + +```sh +kubectl logs istio-ingressgateway-... -n istio-system +``` + +

View Istio Ingress Gateway for Bookinfo

+
+ +

View the Gateway and VirtualServices

+ +Check the created `Istio Gateway` and `Istio VirtualService` to see the changes deployed: + +```sh +kubectl get gateway +kubectl get gateway -o yaml + +kubectl get virtualservices +kubectl get virtualservices -o yaml +``` + +

+ Find the external port of the Istio Ingress Gateway by running: +

+ +```sh +kubectl get service istio-ingressgateway -n istio-system -o wide +``` + +To just get the first port of istio-ingressgateway service, we can run this: + +```sh +kubectl get service istio-ingressgateway -n istio-system --template='{{(index .spec.ports 1).nodePort}}' +``` + +

Create a DNS entry:

+ +Modify your local `/etc/hosts` file to add an entry for your sample application. + +`127.0.0.1. bookinfo.meshery.io` + +The HTTP port is usually 31380. + +Or run these commands to retrieve the full URL: + +```sh +echo "http://$(kubectl get nodes --selector=kubernetes.io/role!=master -o jsonpath={.items[0].status.addresses[?\(@.type==\"InternalIP\"\)].address}):$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[1].nodePort}')/productpage" +``` + +Docker Desktop users please use `http://localhost/productpage` to access product page in your browser. + +

Apply default destination rules

+ +Before we start playing with Istio's traffic management capabilities we need to define the available versions of the deployed services. They are called subsets, in destination rules. + +Using Meshery, navigate to the Custom yaml page, and apply the below to create the subsets for BookInfo: + +```sh +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: productpage +spec: + host: productpage + subsets: + - name: v1 + labels: + version: v1 +--- +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: reviews +spec: + host: reviews + subsets: + - name: v1 + labels: + version: v1 + - name: v2 + labels: + version: v2 + - name: v3 + labels: + version: v3 +--- +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: ratings +spec: + host: ratings + subsets: + - name: v1 + labels: + version: v1 + - name: v2 + labels: + version: v2 + - name: v2-mysql + labels: + version: v2-mysql + - name: v2-mysql-vm + labels: + version: v2-mysql-vm +--- +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: details +spec: + host: details + subsets: + - name: v1 + labels: + version: v1 + - name: v2 + labels: + version: v2 +``` + +This creates destination rules for each of the BookInfo services and defines version subsets + +In a few seconds we should be able to verify the destination rules created by using the command below: + +```sh +kubectl get destinationrules + + +kubectl get destinationrules -o yaml +``` + +

Browse to BookInfo

+ +Browse to the website of the Bookinfo. To view the product page, you will have to append +`/productpage` to the url. + +

Reload Page

+ +Now, reload the page multiple times and notice how it round robins between v1, v2 and v3 of the reviews service. + +

+ Inspect the Istio proxy of the productpage pod +

+ +To better understand the istio proxy, let's inspect the details. Let us `exec` into the productpage pod to find the proxy details. To do so we need to first find the full pod name and then `exec` into the istio-proxy container: + +```sh +kubectl get pods +kubectl exec -it productpage-v1-... -c istio-proxy sh +``` + +Once in the container look at some of the envoy proxy details by inspecting it's config file: + +```sh +ps aux +ls -l /etc/istio/proxy +cat /etc/istio/proxy/envoy-rev0.json +``` + +For more details on envoy proxy please check out their [admin docs](https://www.envoyproxy.io/docs/envoy/v1.5.0/operations/admin). + +As a last step, lets exit the container: + +```sh +exit +``` + +
+

Alternative: Manual installation

+Follow this if the above steps did not work for you + +
+
+ +

Default destination rules

+ +Run the following command to create default destination rules for the Bookinfo services: + +```sh +kubectl apply -f samples/bookinfo/networking/destination-rule-all-mtls.yaml +``` + +

+ Configure the Bookinfo route with the Istio Ingress gateway +

+ +We can create a virtualservice & gateway for bookinfo app in the ingress gateway by running the following: + +```sh +kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml +``` + +
diff --git a/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/getting-started.mdx b/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/getting-started.mdx index 316433b787d8..f7c9c748a841 100644 --- a/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/getting-started.mdx +++ b/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/getting-started.mdx @@ -1,132 +1,132 @@ ---- -docType: "Chapter" -chapterTitle: "Getting Started" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 1 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; -import InstallIstio from "../../../../src/assets/images/learn-layer5/istio/install-istio.webp"; -import IstioAdapter from "../../../../src/assets/images/learn-layer5/istio/istio-adapter.webp"; - - - -

Setup Istio

- -Now that we have a Kubernetes cluster and Meshery, we are ready to download and deploy Istio resources. - -

Steps

- -1. [Install Istio](#1) -1. [Verify install](#2) - -Optional (manual install of Istio): - -1. [Download Istio resources](#1.1) -1. [Setup `istioctl`](#1.2) -1. [Install istio](#1.3) - -

- Install Istio -

- -Using Meshery, select `Istio` from the `Management` menu. - - - - - -In the Istio management page: - -1. Type `istio-system` into the namespace field. -1. Click the (+) icon on the `Install` card and select `Latest Istio` to install the latest version of Istio. - - - - - -

Alternative:Manual installation

-Perform the below steps if the above steps doesn't work for you. - -
-
- -

- Download Istio -

- -You will download and deploy the latest Istio resources on your Kubernetes cluster. - -**_Note to Docker Desktop users:_** Please ensure your Docker VM has at least 4GiB of Memory, which is required for all services to run. - -On your local machine, execute: - -```sh -curl -L https://git.io/getLatestIstio | ISTIO_VERSION=1.7.3 sh - -``` - -

- Setting up istioctl -

- -On a \*nix system, you can setup `istioctl` by doing the following: - -```sh -brew install istioctl -``` - -Alternatively, change into the Istio package directory and add the `istioctl` client to your PATH environment variable. - -```sh -cd istio-* -export PATH=$PWD/bin:$PATH -``` - -Verify `istioctl` is available: - -```sh -istioctl version -``` - -Check if the cluster is ready for installation: - -```sh -istioctl verify-install -``` - -

- Install Istio -

- -To install Istio with a `demo` profile, execute the below command. - -```sh -istioctl install --set profile=demo -``` - -Alternatively, with Envoy logging enabled: - -```sh -istioctl install --set profile=demo --set meshConfig.accessLogFile=/dev/stdout -``` - -

- Verify install -

- -In the Istio management page: - -1. Click the (+) icon on the `Validate Service Mesh Configuration` card. -1. Select `Verify Installation` to verify the installation of Istio. - -

Alternatively:

- -Istio is deployed in a separate Kubernetes namespace `istio-system`. To check if Istio is deployed, and also, to see all the pieces that are deployed, execute the following: - -```sh -kubectl get all -n istio-system -``` - - +--- +docType: "Chapter" +chapterTitle: "Getting Started" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 1 +--- + + +import InstallIstio from "../../../../src/assets/images/learn-layer5/istio/install-istio.webp"; +import IstioAdapter from "../../../../src/assets/images/learn-layer5/istio/istio-adapter.webp"; + + + +

Setup Istio

+ +Now that we have a Kubernetes cluster and Meshery, we are ready to download and deploy Istio resources. + +

Steps

+ +1. [Install Istio](#1) +1. [Verify install](#2) + +Optional (manual install of Istio): + +1. [Download Istio resources](#1.1) +1. [Setup `istioctl`](#1.2) +1. [Install istio](#1.3) + +

+ Install Istio +

+ +Using Meshery, select `Istio` from the `Management` menu. + + + + + +In the Istio management page: + +1. Type `istio-system` into the namespace field. +1. Click the (+) icon on the `Install` card and select `Latest Istio` to install the latest version of Istio. + + + + + +

Alternative:Manual installation

+Perform the below steps if the above steps doesn't work for you. + +
+
+ +

+ Download Istio +

+ +You will download and deploy the latest Istio resources on your Kubernetes cluster. + +**_Note to Docker Desktop users:_** Please ensure your Docker VM has at least 4GiB of Memory, which is required for all services to run. + +On your local machine, execute: + +```sh +curl -L https://git.io/getLatestIstio | ISTIO_VERSION=1.7.3 sh - +``` + +

+ Setting up istioctl +

+ +On a \*nix system, you can setup `istioctl` by doing the following: + +```sh +brew install istioctl +``` + +Alternatively, change into the Istio package directory and add the `istioctl` client to your PATH environment variable. + +```sh +cd istio-* +export PATH=$PWD/bin:$PATH +``` + +Verify `istioctl` is available: + +```sh +istioctl version +``` + +Check if the cluster is ready for installation: + +```sh +istioctl verify-install +``` + +

+ Install Istio +

+ +To install Istio with a `demo` profile, execute the below command. + +```sh +istioctl install --set profile=demo +``` + +Alternatively, with Envoy logging enabled: + +```sh +istioctl install --set profile=demo --set meshConfig.accessLogFile=/dev/stdout +``` + +

+ Verify install +

+ +In the Istio management page: + +1. Click the (+) icon on the `Validate Service Mesh Configuration` card. +1. Select `Verify Installation` to verify the installation of Istio. + +

Alternatively:

+ +Istio is deployed in a separate Kubernetes namespace `istio-system`. To check if Istio is deployed, and also, to see all the pieces that are deployed, execute the following: + +```sh +kubectl get all -n istio-system +``` + +
diff --git a/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/observability.mdx b/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/observability.mdx index 8127fdbdb7ad..5d5c4f32588c 100644 --- a/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/observability.mdx +++ b/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/observability.mdx @@ -1,246 +1,246 @@ ---- -docType: "Chapter" -chapterTitle: "Observability" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 4 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; -import ImageAppIcon from "../../../../src/assets/images/learn-layer5/istio/istio-addons.webp"; -import GraffanaDash from "../../../../src/assets/images/learn-layer5/istio/Grafana_Istio_Dashboard.webp"; -import Prometheus from "../../../../src/assets/images/learn-layer5/istio/Prometheus.webp"; -import Jaeger from "../../../../src/assets/images/learn-layer5/istio/jaeger copy.webp"; - - - -

Install Telemetry Add-ons

- -Using Meshery, install Istio telemetry add-ons. In the Istio management page: - -1. Click the (+) icon on the `Apply Service Mesh Configuration` card. -1. Select each of the following add-ons: - 1. [Prometheus](https://prometheus.io/) - 1. [Grafana](https://grafana.com/) - 1. [Jaeger](https://www.jaegertracing.io/) - - - - - -You will use Prometheus and Grafana for collecting and viewing metrics and [Jaeger](https://www.jaegertracing.io/) collecting and viewing distributed traces. Expose each add-on external to the cluster. Each the service network typs are set to "LoadBalancer". - -

Service Mesh Performance and Telemetry

- -Many of the labs require load to be placed on the sample apps. Let's generate HTTP traffic against the BookInfo application, so we can see interesting telemetry. - -Verify access through the Ingress Gateway: - -```sh -kubectl get service istio-ingressgateway -n istio-system -``` - -Once we have the port, we can append the IP of one of the nodes to get the host. - -The URL to run a load test against will be `http://:/productpage` - -**Please note:** If you are using Docker Desktop, please use the IP address of your host. You can leave the port blank. For example: `http://1.2.3.4/productpage` - -Use the computed URL above in Meshery, in the browser, to run a load test and see the results. - -

- Connect Grafana (optionally, Prometheus) to Meshery. -

- -On the Settings page: - -1. Navigate to the `Metrics` tab. -1. Enter Grafana's URL:port number and submit. - -

- Use Meshery to generate load and analyze performance. -

- -On the Performance page: - -1. give this load test a memorable name -1. enter the URL to the BookInfo productpage -1. select `Istio` in the `Service Mesh` dropdown -1. enter a valid number for `Concurrent requests` -1. enter a valid number for `Queries per second` -1. enter a valid `Duration` (a number followed by `s` for seconds (OR) `m` for minutes (OR) `h` for hour) -1. use the host IP address in the request Tab and in the advanced options, type in the header as `Host:` - -Click on `Run Test`. A performance test will run and statistical analysis performed. Examine the results of the test and behavior of the service mesh. - -Next, you will begin controlling requests to BookInfo using traffic management features. - -
-

Alternative: Manual installation

-Follow these steps if the above steps did not work -
-
- -

Install Add-ons:

-
- -**Prometheus** - -```sh -kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/addons/prometheus.yaml - -``` - -**Grafana** - -```sh -kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/addons/grafana.yaml - -``` - -**Jaeger** - -```sh -kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/addons/jaeger.yaml - -``` -
-

Exposing services

- -Istio add-on services are deployed by default as `ClusterIP` type services. We can expose the services outside the cluster by either changing the Kubernetes service type to `NodePort` or `LoadBalancer` or by port-forwarding or by configuring Kubernetes Ingress. - -**Option 1: Expose services with NodePort** -To expose them using NodePort service type, we can edit the services and change the service type from `ClusterIP` to `NodePort` - -**Option 2: Expose services with port-forwarding** -Port-forwarding runs in the foreground. We have appended `&` to the end of the above 2 commands to run them in the background. If you donot want this behavior, please remove the `&` from the end. - -

Prometheus

- -You will need to expose the Prometheus service on a port either of the two following methods: - -**Option 1: Expose services with NodePort** - -```sh -kubectl -n istio-system edit svc prometheus -``` - -To find the assigned ports for Prometheus: - -```sh -kubectl -n istio-system get svc prometheus -``` - -**Option 2: Expose Prometheus service with port-forwarding:** -\*\* -Expose Prometheus service with port-forwarding: - -```sh -kubectl -n istio-system port-forward \ - $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') \ - 9090:9090 & -``` - -Browse to `http://:` and in the `Expression` input box enter: `istio_request_bytes_count`. Click the Execute button. - -
- - -
-
-

Grafana

- -You will need to expose the Grafana service on a port either of the two following methods: - -```sh -kubectl -n istio-system edit svc grafana -``` - -Once this is done the services will be assigned dedicated ports on the hosts. - -To find the assigned ports for Grafana: - -```sh -kubectl -n istio-system get svc grafana -``` - -**Expose Grafana service with port-forwarding:** - -```sh -kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana \ - -o jsonpath='{.items[0].metadata.name}') 3000:3000 & -``` - - - -
-
-

Distributed Tracing

- -The sample Bookinfo application is configured to collect trace spans using Zipkin or Jaeger. Although Istio proxies are able to automatically send spans, it needs help from the application to tie together the entire trace. To do this applications need to propagate the appropriate HTTP headers so that when the proxies send span information to Zipkin or Jaeger, the spans can be correlated correctly into a single trace. - -To do this the application collects and propagates the following headers from the incoming request to any outgoing requests: - -- `x-request-id` -- `x-b3-traceid` -- `x-b3-spanid` -- `x-b3-parentspanid` -- `x-b3-sampled` -- `x-b3-flags` -- `x-ot-span-context` - -
- - - - - -
-
- -

Exposing services

- -Istio add-on services are deployed by default as `ClusterIP` type services. We can expose the services outside the cluster by either changing the Kubernetes service type to `NodePort` or `LoadBalancer` or by port-forwarding or by configuring Kubernetes Ingress. In this lab, we will briefly demonstrate the `NodePort` and port-forwarding ways of exposing services. - -
Option 1: Expose services with NodePort
- -To expose them using NodePort service type, we can edit the services and change the service type from `ClusterIP` to `NodePort` - -For Jaeger, either of `tracing` or `jaeger-query` can be exposed. - -```sh -kubectl -n istio-system edit svc tracing -``` - -Once this is done the services will be assigned dedicated ports on the hosts. - -To find the assigned ports for Jaeger: - -```sh -kubectl -n istio-system get svc tracing -``` - -
- Option 2: Expose services with port-forwarding -
- -To port-forward Jaeger: - -```sh -kubectl -n istio-system port-forward \ - $(kubectl -n istio-system get pod -l app=jaeger -o jsonpath='{.items[0].metadata.name}') \ - 16686:16686 & -``` - -

View Traces

- -Let us find the port Jaeger is exposed on by running the following command: - -```sh -kubectl -n istio-system get svc tracing -``` - -You can click on the link at the top of the page which maps to the right port and it will open Jaeger UI in a new tab. - -
+--- +docType: "Chapter" +chapterTitle: "Observability" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 4 +--- + + +import ImageAppIcon from "../../../../src/assets/images/learn-layer5/istio/istio-addons.webp"; +import GraffanaDash from "../../../../src/assets/images/learn-layer5/istio/Grafana_Istio_Dashboard.webp"; +import Prometheus from "../../../../src/assets/images/learn-layer5/istio/Prometheus.webp"; +import Jaeger from "../../../../src/assets/images/learn-layer5/istio/jaeger copy.webp"; + + + +

Install Telemetry Add-ons

+ +Using Meshery, install Istio telemetry add-ons. In the Istio management page: + +1. Click the (+) icon on the `Apply Service Mesh Configuration` card. +1. Select each of the following add-ons: + 1. [Prometheus](https://prometheus.io/) + 1. [Grafana](https://grafana.com/) + 1. [Jaeger](https://www.jaegertracing.io/) + + + + + +You will use Prometheus and Grafana for collecting and viewing metrics and [Jaeger](https://www.jaegertracing.io/) collecting and viewing distributed traces. Expose each add-on external to the cluster. Each the service network typs are set to "LoadBalancer". + +

Service Mesh Performance and Telemetry

+ +Many of the labs require load to be placed on the sample apps. Let's generate HTTP traffic against the BookInfo application, so we can see interesting telemetry. + +Verify access through the Ingress Gateway: + +```sh +kubectl get service istio-ingressgateway -n istio-system +``` + +Once we have the port, we can append the IP of one of the nodes to get the host. + +The URL to run a load test against will be `http://:/productpage` + +**Please note:** If you are using Docker Desktop, please use the IP address of your host. You can leave the port blank. For example: `http://1.2.3.4/productpage` + +Use the computed URL above in Meshery, in the browser, to run a load test and see the results. + +

+ Connect Grafana (optionally, Prometheus) to Meshery. +

+ +On the Settings page: + +1. Navigate to the `Metrics` tab. +1. Enter Grafana's URL:port number and submit. + +

+ Use Meshery to generate load and analyze performance. +

+ +On the Performance page: + +1. give this load test a memorable name +1. enter the URL to the BookInfo productpage +1. select `Istio` in the `Service Mesh` dropdown +1. enter a valid number for `Concurrent requests` +1. enter a valid number for `Queries per second` +1. enter a valid `Duration` (a number followed by `s` for seconds (OR) `m` for minutes (OR) `h` for hour) +1. use the host IP address in the request Tab and in the advanced options, type in the header as `Host:` + +Click on `Run Test`. A performance test will run and statistical analysis performed. Examine the results of the test and behavior of the service mesh. + +Next, you will begin controlling requests to BookInfo using traffic management features. + +
+

Alternative: Manual installation

+Follow these steps if the above steps did not work +
+
+ +

Install Add-ons:

+
+ +**Prometheus** + +```sh +kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/addons/prometheus.yaml + +``` + +**Grafana** + +```sh +kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/addons/grafana.yaml + +``` + +**Jaeger** + +```sh +kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/addons/jaeger.yaml + +``` +
+

Exposing services

+ +Istio add-on services are deployed by default as `ClusterIP` type services. We can expose the services outside the cluster by either changing the Kubernetes service type to `NodePort` or `LoadBalancer` or by port-forwarding or by configuring Kubernetes Ingress. + +**Option 1: Expose services with NodePort** +To expose them using NodePort service type, we can edit the services and change the service type from `ClusterIP` to `NodePort` + +**Option 2: Expose services with port-forwarding** +Port-forwarding runs in the foreground. We have appended `&` to the end of the above 2 commands to run them in the background. If you donot want this behavior, please remove the `&` from the end. + +

Prometheus

+ +You will need to expose the Prometheus service on a port either of the two following methods: + +**Option 1: Expose services with NodePort** + +```sh +kubectl -n istio-system edit svc prometheus +``` + +To find the assigned ports for Prometheus: + +```sh +kubectl -n istio-system get svc prometheus +``` + +**Option 2: Expose Prometheus service with port-forwarding:** +\*\* +Expose Prometheus service with port-forwarding: + +```sh +kubectl -n istio-system port-forward \ + $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') \ + 9090:9090 & +``` + +Browse to `http://:` and in the `Expression` input box enter: `istio_request_bytes_count`. Click the Execute button. + +
+ + +
+
+

Grafana

+ +You will need to expose the Grafana service on a port either of the two following methods: + +```sh +kubectl -n istio-system edit svc grafana +``` + +Once this is done the services will be assigned dedicated ports on the hosts. + +To find the assigned ports for Grafana: + +```sh +kubectl -n istio-system get svc grafana +``` + +**Expose Grafana service with port-forwarding:** + +```sh +kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana \ + -o jsonpath='{.items[0].metadata.name}') 3000:3000 & +``` + + + +
+
+

Distributed Tracing

+ +The sample Bookinfo application is configured to collect trace spans using Zipkin or Jaeger. Although Istio proxies are able to automatically send spans, it needs help from the application to tie together the entire trace. To do this applications need to propagate the appropriate HTTP headers so that when the proxies send span information to Zipkin or Jaeger, the spans can be correlated correctly into a single trace. + +To do this the application collects and propagates the following headers from the incoming request to any outgoing requests: + +- `x-request-id` +- `x-b3-traceid` +- `x-b3-spanid` +- `x-b3-parentspanid` +- `x-b3-sampled` +- `x-b3-flags` +- `x-ot-span-context` + +
+ + + + + +
+
+ +

Exposing services

+ +Istio add-on services are deployed by default as `ClusterIP` type services. We can expose the services outside the cluster by either changing the Kubernetes service type to `NodePort` or `LoadBalancer` or by port-forwarding or by configuring Kubernetes Ingress. In this lab, we will briefly demonstrate the `NodePort` and port-forwarding ways of exposing services. + +
Option 1: Expose services with NodePort
+ +To expose them using NodePort service type, we can edit the services and change the service type from `ClusterIP` to `NodePort` + +For Jaeger, either of `tracing` or `jaeger-query` can be exposed. + +```sh +kubectl -n istio-system edit svc tracing +``` + +Once this is done the services will be assigned dedicated ports on the hosts. + +To find the assigned ports for Jaeger: + +```sh +kubectl -n istio-system get svc tracing +``` + +
+ Option 2: Expose services with port-forwarding +
+ +To port-forward Jaeger: + +```sh +kubectl -n istio-system port-forward \ + $(kubectl -n istio-system get pod -l app=jaeger -o jsonpath='{.items[0].metadata.name}') \ + 16686:16686 & +``` + +

View Traces

+ +Let us find the port Jaeger is exposed on by running the following command: + +```sh +kubectl -n istio-system get svc tracing +``` + +You can click on the link at the top of the page which maps to the right port and it will open Jaeger UI in a new tab. + +
diff --git a/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/service-security-capabilities.mdx b/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/service-security-capabilities.mdx index a96ed8405fc5..25460d889330 100644 --- a/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/service-security-capabilities.mdx +++ b/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/service-security-capabilities.mdx @@ -1,284 +1,284 @@ ---- -docType: "Chapter" -chapterTitle: "Service security capabilities" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 6 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; - - - -

Access Control

- -You will start by denying all traffic. - -```yaml -apiVersion: security.istio.io/v1beta1 -kind: AuthorizationPolicy -metadata: - name: deny-all - namespace: default -spec: {} -``` - -

- And then begin poking holes in your service mesh "firewall". -

- -```yaml ---- -apiVersion: "security.istio.io/v1beta1" -kind: "AuthorizationPolicy" -metadata: - name: "allow-get" - namespace: default -spec: - selector: - matchLabels: - app: httpbin - rules: - - to: - - operation: - methods: ["GET"] -``` - -

- Create AuthorizationPolicy for each BookInfo service. -

- -```yaml ---- -apiVersion: "security.istio.io/v1beta1" -kind: "AuthorizationPolicy" -metadata: - name: "view-productpage" - namespace: default -spec: - selector: - matchLabels: - app: productpage - rules: - - to: - - operation: - methods: ["GET", "POST"] # try login with just GET (fails) ---- -apiVersion: "security.istio.io/v1beta1" -kind: "AuthorizationPolicy" -metadata: - name: "view-details" - namespace: default -spec: - selector: - matchLabels: - app: details - rules: - - from: - - source: - principals: ["cluster.local/ns/default/sa/bookinfo-productpage"] - to: - - operation: - methods: ["GET", "POST"] ---- -apiVersion: "security.istio.io/v1beta1" -kind: "AuthorizationPolicy" -metadata: - name: "view-reviews" - namespace: default -spec: - selector: - matchLabels: - app: reviews - rules: - - from: - - source: - principals: ["cluster.local/ns/default/sa/bookinfo-productpage"] - to: - - operation: - methods: ["GET", "POST"] ---- -apiVersion: "security.istio.io/v1beta1" -kind: "AuthorizationPolicy" -metadata: - name: "view-ratings" - namespace: default -spec: - selector: - matchLabels: - app: ratings - rules: - - from: - - source: - principals: ["cluster.local/ns/default/sa/bookinfo-reviews"] - to: - - operation: - methods: ["GET", "POST"] -``` - -

Allow per user access

- -```yaml ---- -apiVersion: "security.istio.io/v1beta1" -kind: "AuthorizationPolicy" -metadata: - name: "view-reviews" - namespace: default -spec: - selector: - matchLabels: - app: reviews - rules: - - from: - - source: - principals: ["cluster.local/ns/default/sa/bookinfo-productpage"] - to: - - operation: - methods: ["GET"] - when: - - key: request.headers[end-user] - values: ["naruto"] -``` - -

- Reset BookInfo Subsets (reset destination rules) -

- -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: - name: productpage -spec: - host: productpage - subsets: - - name: v1 - labels: - version: v1 ---- -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: - name: reviews -spec: - host: reviews - subsets: - - name: v1 - labels: - version: v1 - - name: v2 - labels: - version: v2 - - name: v3 - labels: - version: v3 ---- -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: - name: ratings -spec: - host: ratings - subsets: - - name: v1 - labels: - version: v1 - - name: v2 - labels: - version: v2 - - name: v2-mysql - labels: - version: v2-mysql - - name: v2-mysql-vm - labels: - version: v2-mysql-vm ---- -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: - name: details -spec: - host: details - subsets: - - name: v1 - labels: - version: v1 - - name: v2 - labels: - version: v2 ---- - -``` - -

Identity Verification

- -Note: this lab uses the sample application HTTPbin. - -Using Meshery, deploy the HTTPbin sample application. - -

Add Claims

- -```yaml -apiVersion: security.istio.io/v1beta1 -kind: AuthorizationPolicy -metadata: - name: require-jwt - namespace: foo -spec: - selector: - matchLabels: - app: httpbin - action: ALLOW - rules: - - from: - - source: - requestPrincipals: - ["testing@secure.istio.io/testing@secure.istio.io"] - when: - - key: request.auth.claims[groups] - values: ["group1"] -``` - -

Def

- -```yaml -apiVersion: "security.istio.io/v1beta1" -kind: "RequestAuthentication" -metadata: - name: "jwt" - namespace: default -spec: - selector: - matchLabels: - app: httpbin - jwtRules: - - issuer: "testing@secure.istio.io" - jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.7/security/tools/jwt/samples/jwks.json" -``` - -

Mutual TLS

- -Using Meshery, you can change mTLS enforcement for a namespace. - -To configure mTLS on more selective level, you can change and apply this configuration: - -```yaml -apiVersion: "security.istio.io/v1beta1" -kind: "PeerAuthentication" -metadata: - name: "default" - namespace: "istio-system" -spec: - # selector: - # matchLabels: - # app: httpbin - mtls: - mode: STRICT #ISTIO_MUTUAL,DISABLE - # portLevelMtls: - # 80: - # mode: DISABLE -``` - -
+--- +docType: "Chapter" +chapterTitle: "Service security capabilities" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 6 +--- + + + + + +

Access Control

+ +You will start by denying all traffic. + +```yaml +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: deny-all + namespace: default +spec: {} +``` + +

+ And then begin poking holes in your service mesh "firewall". +

+ +```yaml +--- +apiVersion: "security.istio.io/v1beta1" +kind: "AuthorizationPolicy" +metadata: + name: "allow-get" + namespace: default +spec: + selector: + matchLabels: + app: httpbin + rules: + - to: + - operation: + methods: ["GET"] +``` + +

+ Create AuthorizationPolicy for each BookInfo service. +

+ +```yaml +--- +apiVersion: "security.istio.io/v1beta1" +kind: "AuthorizationPolicy" +metadata: + name: "view-productpage" + namespace: default +spec: + selector: + matchLabels: + app: productpage + rules: + - to: + - operation: + methods: ["GET", "POST"] # try login with just GET (fails) +--- +apiVersion: "security.istio.io/v1beta1" +kind: "AuthorizationPolicy" +metadata: + name: "view-details" + namespace: default +spec: + selector: + matchLabels: + app: details + rules: + - from: + - source: + principals: ["cluster.local/ns/default/sa/bookinfo-productpage"] + to: + - operation: + methods: ["GET", "POST"] +--- +apiVersion: "security.istio.io/v1beta1" +kind: "AuthorizationPolicy" +metadata: + name: "view-reviews" + namespace: default +spec: + selector: + matchLabels: + app: reviews + rules: + - from: + - source: + principals: ["cluster.local/ns/default/sa/bookinfo-productpage"] + to: + - operation: + methods: ["GET", "POST"] +--- +apiVersion: "security.istio.io/v1beta1" +kind: "AuthorizationPolicy" +metadata: + name: "view-ratings" + namespace: default +spec: + selector: + matchLabels: + app: ratings + rules: + - from: + - source: + principals: ["cluster.local/ns/default/sa/bookinfo-reviews"] + to: + - operation: + methods: ["GET", "POST"] +``` + +

Allow per user access

+ +```yaml +--- +apiVersion: "security.istio.io/v1beta1" +kind: "AuthorizationPolicy" +metadata: + name: "view-reviews" + namespace: default +spec: + selector: + matchLabels: + app: reviews + rules: + - from: + - source: + principals: ["cluster.local/ns/default/sa/bookinfo-productpage"] + to: + - operation: + methods: ["GET"] + when: + - key: request.headers[end-user] + values: ["naruto"] +``` + +

+ Reset BookInfo Subsets (reset destination rules) +

+ +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: productpage +spec: + host: productpage + subsets: + - name: v1 + labels: + version: v1 +--- +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: reviews +spec: + host: reviews + subsets: + - name: v1 + labels: + version: v1 + - name: v2 + labels: + version: v2 + - name: v3 + labels: + version: v3 +--- +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: ratings +spec: + host: ratings + subsets: + - name: v1 + labels: + version: v1 + - name: v2 + labels: + version: v2 + - name: v2-mysql + labels: + version: v2-mysql + - name: v2-mysql-vm + labels: + version: v2-mysql-vm +--- +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: details +spec: + host: details + subsets: + - name: v1 + labels: + version: v1 + - name: v2 + labels: + version: v2 +--- + +``` + +

Identity Verification

+ +Note: this lab uses the sample application HTTPbin. + +Using Meshery, deploy the HTTPbin sample application. + +

Add Claims

+ +```yaml +apiVersion: security.istio.io/v1beta1 +kind: AuthorizationPolicy +metadata: + name: require-jwt + namespace: foo +spec: + selector: + matchLabels: + app: httpbin + action: ALLOW + rules: + - from: + - source: + requestPrincipals: + ["testing@secure.istio.io/testing@secure.istio.io"] + when: + - key: request.auth.claims[groups] + values: ["group1"] +``` + +

Def

+ +```yaml +apiVersion: "security.istio.io/v1beta1" +kind: "RequestAuthentication" +metadata: + name: "jwt" + namespace: default +spec: + selector: + matchLabels: + app: httpbin + jwtRules: + - issuer: "testing@secure.istio.io" + jwksUri: "https://raw.githubusercontent.com/istio/istio/release-1.7/security/tools/jwt/samples/jwks.json" +``` + +

Mutual TLS

+ +Using Meshery, you can change mTLS enforcement for a namespace. + +To configure mTLS on more selective level, you can change and apply this configuration: + +```yaml +apiVersion: "security.istio.io/v1beta1" +kind: "PeerAuthentication" +metadata: + name: "default" + namespace: "istio-system" +spec: + # selector: + # matchLabels: + # app: httpbin + mtls: + mode: STRICT #ISTIO_MUTUAL,DISABLE + # portLevelMtls: + # 80: + # mode: DISABLE +``` + +
diff --git a/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/traffic-management.mdx b/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/traffic-management.mdx index 5fa3d3b9735c..1df6c5f85fd7 100644 --- a/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/traffic-management.mdx +++ b/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/traffic-management.mdx @@ -1,448 +1,448 @@ ---- -docType: "Chapter" -chapterTitle: "Traffic management" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 5 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; - - -Service routes and version subsets should be in place given the destination rules applied in Lab 3. If they are not present, re-apply the destination rules: - -
- - -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: - name: productpage -spec: - host: productpage - subsets: - - name: v1 - labels: - version: v1 ---- - -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: -name: reviews -spec: -host: reviews -subsets: - name: v1 -labels: -version: v1 - name: v2 -labels: -version: v2 - name: v3 -labels: -version: v3 - ---- - -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: -name: ratings -spec: -host: ratings -subsets: - name: v1 -labels: -version: v1 - name: v2 -labels: -version: v2 - name: v2-mysql -labels: -version: v2-mysql - name: v2-mysql-vm -labels: -version: v2-mysql-vm - ---- - -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: -name: details -spec: -host: details -subsets: - name: v1 -labels: -version: v1 - name: v2 -labels: -version: v2 - ---- - -``` - -
- -

- Start managing traffic routes -

- - -Some basics to get us started. - -

- Send all requests to Productpage v1 -

- -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: reviews -spec: - hosts: - - reviews - http: - - route: - - destination: - host: reviews - subset: v1 - - -``` -_Using Meshery, apply custom configuration._ - -Refresh BookInfo productpage - -

- Send all requests to Productpage v2 -

- -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: reviews -spec: - hosts: - - reviews - http: - - route: - - destination: - host: reviews - subset: v2 -``` -_Using Meshery, apply custom configuration._ - -Refresh BookInfo productpage. - -

- Traffic routing based on user or user-agent type -

- -
- -

- Redirect requests from mobile devices -

- -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: bookinfo -spec: - hosts: - - "bookinfo.meshery.io" - gateways: - - sample-app-gateway - http: - - match: - - headers: - User-Agent: - regex: ^.*Mobile.*$ - route: - - headers: - request: - set: - x-response: "Success with Mobile" - destination: - host: productpage - port: - number: 9080 - - route: - - destination: - host: product - subset: random - - -``` - -Set your browser to mimic a mobile device. Enable Developer tools, if need. Refresh BookInfo productpage. - -

- Redirect requests based on HTTP header information -

- -Example of using user information from HTTP headers to redirect requests. - -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: reviews -spec: - hosts: - - reviews - http: - - match: - - headers: - end-user: - exact: naruto - route: - - destination: - host: reviews - subset: v2 - - match: - - headers: - end-user: - exact: sasuke - route: - - destination: - host: reviews - subset: v3 - - route: - - destination: - host: reviews - subset: v1 - - -``` - -

- Traffic Mirroring with Istio -

- -You will need to generate load on BookInfo's productpage service. See Lab 4 for instructions for running a performance test. - -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: reviews -spec: - hosts: - - reviews - http: - - route: - - destination: - host: reviews - subset: v1 - weight: 100 - mirror: - host: reviews - subset: v2 - mirror_percent: 100 - -``` -Incrementally increase the traffic split percentage to the higher version service #. Start at 20% traffic split - -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: reviews -spec: - hosts: - - reviews - http: - - route: - - destination: - host: reviews - subset: v1 - weight: 80 - - destination: - host: reviews - subset: v3 - weight: 20 - - -``` - -Move to 50%. Observe in Meshery. - -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: reviews -spec: - hosts: - - reviews - http: - - route: - - destination: - host: reviews - subset: v1 - weight: 50 - - destination: - host: reviews - subset: v3 - weight: 50 - -``` -

- Injecting Latency -

- -Acknowledging the fallacy that the network is always reliable, you will intentionally cause a little chaos. - -

- Exploring timeouts with Reviews service -

- -Note Istio Proxy's default timeout settings. - -```yaml - ---- -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: reviews -spec: - hosts: - - reviews - http: - - match: - - headers: - end-user: - exact: naruto - fault: - delay: - percentage: - value: 100.0 - fixedDelay: 11s - route: - - destination: - host: reviews - subset: v1 - - route: - - destination: - host: reviews - subset: v2 - -``` - -

- Exploring timeouts with Ratings service -

- -```yaml - ---- -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: ratings -spec: - hosts: - - ratings - http: - - match: - - headers: - end-user: - exact: naruto - fault: - delay: - percentage: - value: 100.0 - fixedDelay: 5s - route: - - destination: - host: ratings - subset: v1 - - route: - - destination: - host: ratings - subset: v1 - -``` - -

- Retries -

- -Overcoming the latency issue. - -

- Set 5 retry attempts and a 3 second timeout -

- -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: reviews -spec: - hosts: - - reviews - http: - - route: - - destination: - host: reviews - subset: v1 - retries: - attempts: 5 - perTryTimeout: 3s - -``` - -
-

Alternative: Manual installation

-Follow these steps if the above steps did not work -
-
- -

Traffic management with Istio

- -If you haven't forked or cloned this repository, please do so now: - -```sh -git clone https://github.com/layer5io/advanced-istio-service-mesh-workshop - -``` -

- {" "} - Route all traffic to version V1 - -

- -```sh -kubectl apply -f route-v1-v2/v1.yaml -``` -

- {" "} - Route all traffic to version V2 - -

- -```sh -kubectl apply -f route-v1-v2/v2.yaml -``` - -

- - Traffic routing based on user or user-agent type -

- -

Redirect requests from mobile devices

- -```sh -kubectl apply -f route-header/device.yaml -``` - -

Redirect requests based on Cookie data

- -```sh -kubectl apply -f route-header/user.yaml -``` - -
+--- +docType: "Chapter" +chapterTitle: "Traffic management" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 5 +--- + + + + +Service routes and version subsets should be in place given the destination rules applied in Lab 3. If they are not present, re-apply the destination rules: + +
+ + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: productpage +spec: + host: productpage + subsets: + - name: v1 + labels: + version: v1 +--- + +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: +name: reviews +spec: +host: reviews +subsets: - name: v1 +labels: +version: v1 - name: v2 +labels: +version: v2 - name: v3 +labels: +version: v3 + +--- + +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: +name: ratings +spec: +host: ratings +subsets: - name: v1 +labels: +version: v1 - name: v2 +labels: +version: v2 - name: v2-mysql +labels: +version: v2-mysql - name: v2-mysql-vm +labels: +version: v2-mysql-vm + +--- + +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: +name: details +spec: +host: details +subsets: - name: v1 +labels: +version: v1 - name: v2 +labels: +version: v2 + +--- + +``` + +
+ +

+ Start managing traffic routes +

+ + +Some basics to get us started. + +

+ Send all requests to Productpage v1 +

+ +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: reviews +spec: + hosts: + - reviews + http: + - route: + - destination: + host: reviews + subset: v1 + + +``` +_Using Meshery, apply custom configuration._ + +Refresh BookInfo productpage + +

+ Send all requests to Productpage v2 +

+ +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: reviews +spec: + hosts: + - reviews + http: + - route: + - destination: + host: reviews + subset: v2 +``` +_Using Meshery, apply custom configuration._ + +Refresh BookInfo productpage. + +

+ Traffic routing based on user or user-agent type +

+ +
+ +

+ Redirect requests from mobile devices +

+ +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: bookinfo +spec: + hosts: + - "bookinfo.meshery.io" + gateways: + - sample-app-gateway + http: + - match: + - headers: + User-Agent: + regex: ^.*Mobile.*$ + route: + - headers: + request: + set: + x-response: "Success with Mobile" + destination: + host: productpage + port: + number: 9080 + - route: + - destination: + host: product + subset: random + + +``` + +Set your browser to mimic a mobile device. Enable Developer tools, if need. Refresh BookInfo productpage. + +

+ Redirect requests based on HTTP header information +

+ +Example of using user information from HTTP headers to redirect requests. + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: reviews +spec: + hosts: + - reviews + http: + - match: + - headers: + end-user: + exact: naruto + route: + - destination: + host: reviews + subset: v2 + - match: + - headers: + end-user: + exact: sasuke + route: + - destination: + host: reviews + subset: v3 + - route: + - destination: + host: reviews + subset: v1 + + +``` + +

+ Traffic Mirroring with Istio +

+ +You will need to generate load on BookInfo's productpage service. See Lab 4 for instructions for running a performance test. + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: reviews +spec: + hosts: + - reviews + http: + - route: + - destination: + host: reviews + subset: v1 + weight: 100 + mirror: + host: reviews + subset: v2 + mirror_percent: 100 + +``` +Incrementally increase the traffic split percentage to the higher version service #. Start at 20% traffic split + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: reviews +spec: + hosts: + - reviews + http: + - route: + - destination: + host: reviews + subset: v1 + weight: 80 + - destination: + host: reviews + subset: v3 + weight: 20 + + +``` + +Move to 50%. Observe in Meshery. + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: reviews +spec: + hosts: + - reviews + http: + - route: + - destination: + host: reviews + subset: v1 + weight: 50 + - destination: + host: reviews + subset: v3 + weight: 50 + +``` +

+ Injecting Latency +

+ +Acknowledging the fallacy that the network is always reliable, you will intentionally cause a little chaos. + +

+ Exploring timeouts with Reviews service +

+ +Note Istio Proxy's default timeout settings. + +```yaml + +--- +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: reviews +spec: + hosts: + - reviews + http: + - match: + - headers: + end-user: + exact: naruto + fault: + delay: + percentage: + value: 100.0 + fixedDelay: 11s + route: + - destination: + host: reviews + subset: v1 + - route: + - destination: + host: reviews + subset: v2 + +``` + +

+ Exploring timeouts with Ratings service +

+ +```yaml + +--- +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: ratings +spec: + hosts: + - ratings + http: + - match: + - headers: + end-user: + exact: naruto + fault: + delay: + percentage: + value: 100.0 + fixedDelay: 5s + route: + - destination: + host: ratings + subset: v1 + - route: + - destination: + host: ratings + subset: v1 + +``` + +

+ Retries +

+ +Overcoming the latency issue. + +

+ Set 5 retry attempts and a 3 second timeout +

+ +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: reviews +spec: + hosts: + - reviews + http: + - route: + - destination: + host: reviews + subset: v1 + retries: + attempts: 5 + perTryTimeout: 3s + +``` + +
+

Alternative: Manual installation

+Follow these steps if the above steps did not work +
+
+ +

Traffic management with Istio

+ +If you haven't forked or cloned this repository, please do so now: + +```sh +git clone https://github.com/layer5io/advanced-istio-service-mesh-workshop + +``` +

+ {" "} + Route all traffic to version V1 + +

+ +```sh +kubectl apply -f route-v1-v2/v1.yaml +``` +

+ {" "} + Route all traffic to version V2 + +

+ +```sh +kubectl apply -f route-v1-v2/v2.yaml +``` + +

+ + Traffic routing based on user or user-agent type +

+ +

Redirect requests from mobile devices

+ +```sh +kubectl apply -f route-header/device.yaml +``` + +

Redirect requests based on Cookie data

+ +```sh +kubectl apply -f route-header/user.yaml +``` + +
diff --git a/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/webassembly-and-intelligent-data-planes.mdx b/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/webassembly-and-intelligent-data-planes.mdx index 2624f589540f..7ceb51e538dc 100644 --- a/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/webassembly-and-intelligent-data-planes.mdx +++ b/content-learn/mastering-service-meshes-for-developers/advance-concepts-of-service-mesh/istio/webassembly-and-intelligent-data-planes.mdx @@ -1,148 +1,148 @@ ---- -docType: "Chapter" -chapterTitle: "WebAssembly and intelligent data planes" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 7 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; - -import installimagehub from "../../../../src/assets/images/learn-layer5/istio/install-imagehub.webp"; -import deployenvoyfilter from "../../../../src/assets/images/learn-layer5/istio/deploy-envoyfilter.webp"; - - - -In this lab, you will use the sample application [Image Hub](https://github.com/layer5io/image-hub). This version of the Image Hub filter has been simplified for your lab. To self-study deeper functionality, try the other version of the Image Hub filter that is available in the Image Hub repo. - -

Deploy Sample Application

- -Using Meshery, select Istio from the Management menu. - -In the Istio management page: - -1. Type default into the namespace field. -2. Click the (+) icon on the Manage Sample Application Lifecycle card and select Image Hub Application to install the latest version of Image Hub - - - - -
-
- -

Load the filter

- -Next, load the custom Envoy filter. This filter is written in Rust and is compiled against WebAssembly as it's target runtime. - -Using Meshery, select Istio from the Management menu. - -In the Istio management page: - -1. Type default into the namespace field. -2. Click the (+) icon on the Apply Service Mesh Configuration card and select Envoy Filter for Image Hub to deploy the custom filter. - - - -
-
-

Send traffic

-
-

Analyze behavior

- -Alternative, manual installation steps are provided for reference below. No need to execute these if you have performed the steps above. - -Manually deploy the Image Hub filter. - -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: EnvoyFilter -metadata: - name: custom-filter -spec: - configPatches: - - applyTo: HTTP_FILTER - match: - context: SIDECAR_OUTBOUND # will match outbound listeners in all sidecars - listener: - portNumber: 9080 - filterChain: - name: envoy.http_connection_manager - filter: - name: "envoy.tcp_proxy" - patch: - operation: INSERT_BEFORE - value: - # This is the full filter config including the name and config or typed_config section. - name: "envoy.filters.http.wasm" - config: - config: - name: custom-filter - rootId: my_root_id - vmConfig: - code: - local: - filename: /var/lib/imagehub/filter.wasm - runtime: envoy.wasm.runtime.v8 - vmId: custom-filter - allow_precompiled: true - workloadSelector: - labels: - app: api-v1 - version: v1 - -``` -Manually patch the Image Hub Deployment. - -```yaml ----( - // kubectl patch deployment/api-v1 -p ' - { - "spec": { - "template": { - "metadata": { - "annotations": { - "sidecar.istio.io/userVolumeMount": "[{\"mountPath\":\"/var/lib/imagehub\",\"name\":\"wasm-filter\"}]" - } - }, - "spec": { - "initContainers": [ - { - "command": [ - "curl", - "-L", - "-o", - "/var/lib/imagehub/filter.wasm", - "https://github.com/layer5io/advanced-istio-service-mesh-workshop/raw/master/lab-7/ratelimiter/ratelimit-filter.wasm" - ], - "image": "curlimages/curl", - "imagePullPolicy": "Always", - "name": "add-wasm", - "resources": {}, - "terminationMessagePath": "/dev/termination-log", - "terminationMessagePolicy": "File", - "volumeMounts": [ - { - "mountPath": "/var/lib/imagehub", - "name": "wasm-filter" - } - ] - } - ], - "volumes": [ - { - "emptyDir": {}, - "name": "wasm-filter" - } - ] - } - } - } - } -) -// ' - -``` -A future version of Meshery will allow you to deploy any filter from the [wasm-filters](https://github.com/layer5io/wasm-filters) repo. PR the repo to upload your custom filter and have Meshery deploy it. - -
+--- +docType: "Chapter" +chapterTitle: "WebAssembly and intelligent data planes" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 7 +--- + + + +import installimagehub from "../../../../src/assets/images/learn-layer5/istio/install-imagehub.webp"; +import deployenvoyfilter from "../../../../src/assets/images/learn-layer5/istio/deploy-envoyfilter.webp"; + + + +In this lab, you will use the sample application [Image Hub](https://github.com/layer5io/image-hub). This version of the Image Hub filter has been simplified for your lab. To self-study deeper functionality, try the other version of the Image Hub filter that is available in the Image Hub repo. + +

Deploy Sample Application

+ +Using Meshery, select Istio from the Management menu. + +In the Istio management page: + +1. Type default into the namespace field. +2. Click the (+) icon on the Manage Sample Application Lifecycle card and select Image Hub Application to install the latest version of Image Hub + + + + +
+
+ +

Load the filter

+ +Next, load the custom Envoy filter. This filter is written in Rust and is compiled against WebAssembly as it's target runtime. + +Using Meshery, select Istio from the Management menu. + +In the Istio management page: + +1. Type default into the namespace field. +2. Click the (+) icon on the Apply Service Mesh Configuration card and select Envoy Filter for Image Hub to deploy the custom filter. + + + +
+
+

Send traffic

+
+

Analyze behavior

+ +Alternative, manual installation steps are provided for reference below. No need to execute these if you have performed the steps above. + +Manually deploy the Image Hub filter. + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: custom-filter +spec: + configPatches: + - applyTo: HTTP_FILTER + match: + context: SIDECAR_OUTBOUND # will match outbound listeners in all sidecars + listener: + portNumber: 9080 + filterChain: + name: envoy.http_connection_manager + filter: + name: "envoy.tcp_proxy" + patch: + operation: INSERT_BEFORE + value: + # This is the full filter config including the name and config or typed_config section. + name: "envoy.filters.http.wasm" + config: + config: + name: custom-filter + rootId: my_root_id + vmConfig: + code: + local: + filename: /var/lib/imagehub/filter.wasm + runtime: envoy.wasm.runtime.v8 + vmId: custom-filter + allow_precompiled: true + workloadSelector: + labels: + app: api-v1 + version: v1 + +``` +Manually patch the Image Hub Deployment. + +```yaml +---( + // kubectl patch deployment/api-v1 -p ' + { + "spec": { + "template": { + "metadata": { + "annotations": { + "sidecar.istio.io/userVolumeMount": "[{\"mountPath\":\"/var/lib/imagehub\",\"name\":\"wasm-filter\"}]" + } + }, + "spec": { + "initContainers": [ + { + "command": [ + "curl", + "-L", + "-o", + "/var/lib/imagehub/filter.wasm", + "https://github.com/layer5io/advanced-istio-service-mesh-workshop/raw/master/lab-7/ratelimiter/ratelimit-filter.wasm" + ], + "image": "curlimages/curl", + "imagePullPolicy": "Always", + "name": "add-wasm", + "resources": {}, + "terminationMessagePath": "/dev/termination-log", + "terminationMessagePolicy": "File", + "volumeMounts": [ + { + "mountPath": "/var/lib/imagehub", + "name": "wasm-filter" + } + ] + } + ], + "volumes": [ + { + "emptyDir": {}, + "name": "wasm-filter" + } + ] + } + } + } + } +) +// ' + +``` +A future version of Meshery will allow you to deploy any filter from the [wasm-filters](https://github.com/layer5io/wasm-filters) repo. PR the repo to upload your custom filter and have Meshery deploy it. + +
diff --git a/content-learn/mastering-service-meshes-for-developers/index.mdx b/content-learn/mastering-service-meshes-for-developers/index.mdx index d512ee4381bc..398cc72f2096 100644 --- a/content-learn/mastering-service-meshes-for-developers/index.mdx +++ b/content-learn/mastering-service-meshes-for-developers/index.mdx @@ -1,13 +1,13 @@ ---- -title: 'Mastering Service Meshes for Developers' -description: 'Learn how to setup a service mesh and build an application' -order: 4 -themeColor: '#3C494F' -cardImage: '../../src/assets/images/service-mesh-icons/service-mesh.svg' -courses: 4 ---- - - \ No newline at end of file +--- +title: 'Mastering Service Meshes for Developers' +description: 'Learn how to setup a service mesh and build an application' +order: 4 +themeColor: '#3C494F' +cardImage: '../../src/assets/images/service-mesh-icons/service-mesh.svg' +courses: 4 +--- + +{/* + This file is only used to render the courses list within a learning path. + Check the Learn-Layer5 folder under src/sections/, src/templates for more understanding of how the data is used +*/} \ No newline at end of file diff --git a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/index.mdx b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/index.mdx index e3fdab8cdf30..903a5d2a488a 100644 --- a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/index.mdx +++ b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/index.mdx @@ -1,37 +1,31 @@ ---- -docType: "Course" -title: "Course" -description: "Learn how to setup a service mesh and deploy an application using it." -videos: 4 -lectures: 12 -courseTitle: "Introduction to Service Meshes - Hands On" -themeColor: "#00B39F" -order: 1 -cardImage: "../../../src/assets/images/service-mesh-icons/linkerd-white.svg" -meshesYouLearn: - [ - { - imagepath: "../../../src/assets/images/service-mesh-icons/istio.svg", - name: "Istio", - }, - { - imagepath: "../../../src/assets/images/service-mesh-icons/linkerd.svg", - name: "Linkerd", - }, - ] -toc: - [ - "getting-started", - "deploy-an-application", - "expose-services", - "observability", - "routing-and-canary", - "fault-injection", - "mutual-tls", - "circuit-breaking", - "conclusion", - ] ---- - -A course to help you setup a service-mesh and start using it to build real-life applications using Meshery -as the cloud native management plane. +--- +docType: "Course" +title: "Course" +description: "Learn how to setup a service mesh and deploy an application using it." +videos: 4 +lectures: 12 +courseTitle: "Introduction to Service Meshes - Hands On" +themeColor: "#00B39F" +order: 1 +cardImage: "../../../src/assets/images/service-mesh-icons/linkerd-white.svg" +meshesYouLearn: + - imagepath: "../../../src/assets/images/service-mesh-icons/istio.svg" + name: "Istio" + - imagepath: "../../../src/assets/images/service-mesh-icons/linkerd.svg" + name: "Linkerd" +toc: + [ + "getting-started", + "deploy-an-application", + "expose-services", + "observability", + "routing-and-canary", + "fault-injection", + "mutual-tls", + "circuit-breaking", + "conclusion", + ] +--- + +A course to help you setup a service-mesh and start using it to build real-life applications using Meshery +as the cloud native management plane. diff --git a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/circuit-breaking.mdx b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/circuit-breaking.mdx index f5171ea16a7d..0994f80fb24c 100644 --- a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/circuit-breaking.mdx +++ b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/circuit-breaking.mdx @@ -1,128 +1,128 @@ ---- -docType: "Chapter" -chapterTitle: "Circuit Breaking" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 8 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; -import MesheryInitialLoadTest from "../../../../src/assets/images/learn-layer5/istio/meshery_initial_load_test.webp"; -import MesheryCbLoadTest from "../../../../src/assets/images/learn-layer5/istio/meshery_cb_load_test.webp"; - - - -In this chapter we will configure circuit breaking using Istio. Circuit breaking allows developers to write applications that limit the impact of failures, latency spikes, and other undesirable effects of network peculiarities. This task will show how to configure circuit breaking for connections, requests, and outlier detection. - -

Preparing for circuit breaking

-
- -Before we can configure circuit breaking, please try to access the `product page` app from within `Meshery` to ensure all the calls are making it through **without** errors as we did in [Observability chapter](observability) (see screenshot). - -

Configure circuit breaking

- -
-Now that we have the needed services in place, it is time to configure circuit breaking -using a destination rule. - -Using Meshery, navigate to the Istio management page: - -1. Enter `default` in the `Namespace` field. -2. Click the (+) icon on the `Apply Custom Configuration` card and paste the configuration below. - -

- Manual step for can be found here -

- -This will update the existing destination rule definition for product page service to break the circuit if there are more than one connection and more than one pending request. - -In a few, we should be able to verify the destination rule by using the command below: - -```sh -kubectl get destinationrule productpage -o yaml -``` - -Config: - -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: - name: productpage -spec: - host: productpage - subsets: - - /obserlabels: - version: v1 - name: v1 - trafficPolicy: - connectionPool: - http: - http1MaxPendingRequests: 1 - maxRequestsPerConnection: 1 - tcp: - maxConnections: 1 - outlierDetection: - baseEjectionTime: 3m - consecutiveErrors: 1 - interval: 1s - maxEjectionPercent: 100 - tls: - mode: ISTIO_MUTUAL -``` - -

Time to trip the circuit

- -
-In the circuit-breaker settings, we specified maxRequestsPerConnection: 1 and http1MaxPendingRequests: -1. This should mean that if we exceed more than one request per connection and more -than one pending request, we should see the istio-proxy sidecar open the circuit -for further requests/connections. - -Let us now use Meshery to make several calls to `product page` app by changing the number of concurrent connections to 5 from within Meshery's Performance page. - -Once you have updated the fields, you now click on `Run Test`. - -This will run the load test and show the results in a chart. ( see screenshot ). - -You should only see a percentage of the requests succeed and the rest trapped by the configured circuit breaker. - -
-

- {" "} - Manual Steps -

- -

Configure circuit breaking

- -```sh -kubectl apply -f - < +--- +docType: "Chapter" +chapterTitle: "Circuit Breaking" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 8 +--- + + +import MesheryInitialLoadTest from "../../../../src/assets/images/learn-layer5/istio/meshery_initial_load_test.webp"; +import MesheryCbLoadTest from "../../../../src/assets/images/learn-layer5/istio/meshery_cb_load_test.webp"; + + + +In this chapter we will configure circuit breaking using Istio. Circuit breaking allows developers to write applications that limit the impact of failures, latency spikes, and other undesirable effects of network peculiarities. This task will show how to configure circuit breaking for connections, requests, and outlier detection. + +

Preparing for circuit breaking

+
+ +Before we can configure circuit breaking, please try to access the `product page` app from within `Meshery` to ensure all the calls are making it through **without** errors as we did in [Observability chapter](observability) (see screenshot). + +

Configure circuit breaking

+ +
+Now that we have the needed services in place, it is time to configure circuit breaking +using a destination rule. + +Using Meshery, navigate to the Istio management page: + +1. Enter `default` in the `Namespace` field. +2. Click the (+) icon on the `Apply Custom Configuration` card and paste the configuration below. + +

+ Manual step for can be found here +

+ +This will update the existing destination rule definition for product page service to break the circuit if there are more than one connection and more than one pending request. + +In a few, we should be able to verify the destination rule by using the command below: + +```sh +kubectl get destinationrule productpage -o yaml +``` + +Config: + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: productpage +spec: + host: productpage + subsets: + - /obserlabels: + version: v1 + name: v1 + trafficPolicy: + connectionPool: + http: + http1MaxPendingRequests: 1 + maxRequestsPerConnection: 1 + tcp: + maxConnections: 1 + outlierDetection: + baseEjectionTime: 3m + consecutiveErrors: 1 + interval: 1s + maxEjectionPercent: 100 + tls: + mode: ISTIO_MUTUAL +``` + +

Time to trip the circuit

+ +
+In the circuit-breaker settings, we specified maxRequestsPerConnection: 1 and http1MaxPendingRequests: +1. This should mean that if we exceed more than one request per connection and more +than one pending request, we should see the istio-proxy sidecar open the circuit +for further requests/connections. + +Let us now use Meshery to make several calls to `product page` app by changing the number of concurrent connections to 5 from within Meshery's Performance page. + +Once you have updated the fields, you now click on `Run Test`. + +This will run the load test and show the results in a chart. ( see screenshot ). + +You should only see a percentage of the requests succeed and the rest trapped by the configured circuit breaker. + +
+

+ {" "} + Manual Steps +

+ +

Configure circuit breaking

+ +```sh +kubectl apply -f - < diff --git a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/conclusion.mdx b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/conclusion.mdx index 6af5f0cc1de4..80e1b2f424e7 100644 --- a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/conclusion.mdx +++ b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/conclusion.mdx @@ -1,27 +1,27 @@ ---- -docType: "Chapter" -chapterTitle: "Conclusion" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 9 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; - - - -
- -

Congratulations!

- -
- You have successfully completed the course on{" "} - "Introduction to service meshes - Hands on" using{" "} - - Istio - - . -
- -
+--- +docType: "Chapter" +chapterTitle: "Conclusion" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 9 +--- + + + + + +
+ +

Congratulations!

+ +
+ You have successfully completed the course on{" "} + "Introduction to service meshes - Hands on" using{" "} + + Istio + + . +
+ +
diff --git a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/deploy-an-application.mdx b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/deploy-an-application.mdx index 037630e3a328..5ba0d3246999 100644 --- a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/deploy-an-application.mdx +++ b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/deploy-an-application.mdx @@ -1,219 +1,219 @@ ---- -docType: "Chapter" -chapterTitle: "Deploy a sample application" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 2 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; -import BookInfoOffMesh from "../../../../src/assets/images/learn-layer5/istio/bookinfo-off-mesh.webp"; -import BookInfoOnMesh from "../../../../src/assets/images/learn-layer5/istio/bookinfo-on-mesh.webp"; - - - -To play with Istio and demonstrate some of it's capabilities, you will deploy the example BookInfo application, which is included the Istio package. - -

What is the Bookinfo Application

-
-This application is a polyglot composition of microservices are written in -different languages and sample BookInfo application displays information about a -book, similar to a single catalog entry of an online book store. Displayed on -the page is a description of the book, book details (ISBN, number of pages, and -so on), and a few book reviews. - -The end-to-end architecture of the application is shown in the figure. - -
- - - - -_Figure: BookInfo deployed off the mesh_ - -
-It’s worth noting that these services have no dependencies on Istio, but make an -interesting service mesh example, particularly because of the multitude of services, -languages and versions for the reviews service. - -As shown in the figure below, proxies are sidecarred to each of the application containers. - -
- - - - -_Figure: BookInfo deployed on the mesh_ - -
-Sidecars proxy can be either manually or automatically injected into the pods. Automatic -sidecar injection requires that your Kubernetes api-server supports `admissionregistration.k8s.io/v1` -or `admissionregistration.k8s.io/v1beta1` or `admissionregistration.k8s.io/v1beta2` -APIs. Verify whether your Kubernetes deployment supports these APIs by executing: - -```sh -kubectl api-versions | grep admissionregistration -``` - -If your environment **does NOT** supports either of these two APIs, then you may use [manual sidecar injection](#manual-sidecar-inj) to deploy the sample app. - -As part of Istio deployment in [Previous chapter](./getting-started), you have deployed the sidecar injector. - -
-

- Deploying Sample App with Automatic sidecar injection -

- -
-Istio, deployed as part of this workshop, will also deploy the sidecar injector. -Let us now verify sidecar injector deployment. - -```sh -kubectl -n istio-system get configmaps istio-sidecar-injector -``` - -Output: - -```sh -NAME DATA AGE -istio-sidecar-injector 2 9h -``` - -NamespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the [selector](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors). - -```sh -kubectl get namespace -L istio-injection -``` - -Output: - -```sh -NAME STATUS AGE ISTIO-INJECTION -default Active 1h enabled -istio-system Active 1h disabled -kube-public Active 1h -kube-system Active 1h -``` - -Using Meshery, navigate to the Istio management page. - -1. Enter `default` in the `Namespace` field. -1. Click the (+) icon on the `Sample Application` card and select `BookInfo Application` from the list. - -This will do 3 things: - -1. Label `default` namespace for sidecar injection. -1. Deploys all the BookInfo services in the `default` namespace. -1. Deploys the virtual service and gateway needed to expose the BookInfo's productpage application in the `default` namespace. - -

- Verify Bookinfo deployment{" "} -

- -1. Verify that the deployments are all in a state of AVAILABLE before continuing. - -```sh -watch kubectl get deployment -``` - -2. Choose a service, for instance `productpage`, and view it's container configuration: - -```sh -kubectl get po - -kubectl describe pod productpage-v1-..... -``` - -3. Examine details of the services: - -```sh -kubectl describe svc productpage - ``` - -Next, you will expose the BookInfo application to be accessed external from the cluster. - -
-

Alternative: Manual installation

-Follow this if the above steps did not work for you -
-
- -

Label namespace for injection

- -Label the default namespace with istio-injection=enabled - -```sh -kubectl label namespace default istio-injection=enabled -``` - -```sh -kubectl get namespace -L istio-injection -``` - -Output: - -```sh -NAME STATUS AGE ISTIO-INJECTION -default Active 1h enabled -istio-system Active 1h disabled -kube-public Active 1h -kube-system Active 1h -``` - -

Deploy BookInfo

-
- -Applying this yaml file included in the Istio package you collected in [Getting Started](./getting-started) will deploy the BookInfo app in you cluster. - -```sh -kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -``` - -

- Deploy Gateway and Virtual Service for BookInfo app -

- -```sh -kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml -``` - -
-
- -

- - Manual Sidecar Injection -

- -

Use this only when Automatic Sidecar injection doesn't work

- -To do a manual sidecar injection we will be using `istioctl` command: - -```sh -curl https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/platform/kube/bookinfo.yaml | istioctl kube-inject -f - > newBookInfo.yaml -``` - -Observing the new yaml file reveals that additional container Istio Proxy has been added to the Pods with necessary configurations: - -``` - image: docker.io/istio/proxyv2:1.3.0 - imagePullPolicy: IfNotPresent - name: istio-proxy -``` - -We need to now deploy the new yaml using `kubectl` - -```sh -kubectl apply -f newBookInfo.yaml -``` - -To do both in a single command: - -```sh -kubectl apply -f <(curl https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/platform/kube/bookinfo.yaml | istioctl kube-inject -f -) -``` - -Now continue to [Verify Bookinfo deployment](#verify). - -
+--- +docType: "Chapter" +chapterTitle: "Deploy a sample application" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 2 +--- + + +import BookInfoOffMesh from "../../../../src/assets/images/learn-layer5/istio/bookinfo-off-mesh.webp"; +import BookInfoOnMesh from "../../../../src/assets/images/learn-layer5/istio/bookinfo-on-mesh.webp"; + + + +To play with Istio and demonstrate some of it's capabilities, you will deploy the example BookInfo application, which is included the Istio package. + +

What is the Bookinfo Application

+
+This application is a polyglot composition of microservices are written in +different languages and sample BookInfo application displays information about a +book, similar to a single catalog entry of an online book store. Displayed on +the page is a description of the book, book details (ISBN, number of pages, and +so on), and a few book reviews. + +The end-to-end architecture of the application is shown in the figure. + +
+
+ + + +_Figure: BookInfo deployed off the mesh_ + +
+It’s worth noting that these services have no dependencies on Istio, but make an +interesting service mesh example, particularly because of the multitude of services, +languages and versions for the reviews service. + +As shown in the figure below, proxies are sidecarred to each of the application containers. + +
+ + + + +_Figure: BookInfo deployed on the mesh_ + +
+Sidecars proxy can be either manually or automatically injected into the pods. Automatic +sidecar injection requires that your Kubernetes api-server supports `admissionregistration.k8s.io/v1` +or `admissionregistration.k8s.io/v1beta1` or `admissionregistration.k8s.io/v1beta2` +APIs. Verify whether your Kubernetes deployment supports these APIs by executing: + +```sh +kubectl api-versions | grep admissionregistration +``` + +If your environment **does NOT** supports either of these two APIs, then you may use [manual sidecar injection](#manual-sidecar-inj) to deploy the sample app. + +As part of Istio deployment in [Previous chapter](./getting-started), you have deployed the sidecar injector. + +
+

+ Deploying Sample App with Automatic sidecar injection +

+ +
+Istio, deployed as part of this workshop, will also deploy the sidecar injector. +Let us now verify sidecar injector deployment. + +```sh +kubectl -n istio-system get configmaps istio-sidecar-injector +``` + +Output: + +```sh +NAME DATA AGE +istio-sidecar-injector 2 9h +``` + +NamespaceSelector decides whether to run the webhook on an object based on whether the namespace for that object matches the [selector](https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/#label-selectors). + +```sh +kubectl get namespace -L istio-injection +``` + +Output: + +```sh +NAME STATUS AGE ISTIO-INJECTION +default Active 1h enabled +istio-system Active 1h disabled +kube-public Active 1h +kube-system Active 1h +``` + +Using Meshery, navigate to the Istio management page. + +1. Enter `default` in the `Namespace` field. +1. Click the (+) icon on the `Sample Application` card and select `BookInfo Application` from the list. + +This will do 3 things: + +1. Label `default` namespace for sidecar injection. +1. Deploys all the BookInfo services in the `default` namespace. +1. Deploys the virtual service and gateway needed to expose the BookInfo's productpage application in the `default` namespace. + +

+ Verify Bookinfo deployment{" "} +

+ +1. Verify that the deployments are all in a state of AVAILABLE before continuing. + +```sh +watch kubectl get deployment +``` + +2. Choose a service, for instance `productpage`, and view it's container configuration: + +```sh +kubectl get po + +kubectl describe pod productpage-v1-..... +``` + +3. Examine details of the services: + +```sh +kubectl describe svc productpage + ``` + +Next, you will expose the BookInfo application to be accessed external from the cluster. + +
+

Alternative: Manual installation

+Follow this if the above steps did not work for you +
+
+ +

Label namespace for injection

+ +Label the default namespace with istio-injection=enabled + +```sh +kubectl label namespace default istio-injection=enabled +``` + +```sh +kubectl get namespace -L istio-injection +``` + +Output: + +```sh +NAME STATUS AGE ISTIO-INJECTION +default Active 1h enabled +istio-system Active 1h disabled +kube-public Active 1h +kube-system Active 1h +``` + +

Deploy BookInfo

+
+ +Applying this yaml file included in the Istio package you collected in [Getting Started](./getting-started) will deploy the BookInfo app in you cluster. + +```sh +kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml +``` + +

+ Deploy Gateway and Virtual Service for BookInfo app +

+ +```sh +kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml +``` + +
+
+ +

+ + Manual Sidecar Injection +

+ +

Use this only when Automatic Sidecar injection doesn't work

+ +To do a manual sidecar injection we will be using `istioctl` command: + +```sh +curl https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/platform/kube/bookinfo.yaml | istioctl kube-inject -f - > newBookInfo.yaml +``` + +Observing the new yaml file reveals that additional container Istio Proxy has been added to the Pods with necessary configurations: + +``` + image: docker.io/istio/proxyv2:1.3.0 + imagePullPolicy: IfNotPresent + name: istio-proxy +``` + +We need to now deploy the new yaml using `kubectl` + +```sh +kubectl apply -f newBookInfo.yaml +``` + +To do both in a single command: + +```sh +kubectl apply -f <(curl https://raw.githubusercontent.com/istio/istio/master/samples/bookinfo/platform/kube/bookinfo.yaml | istioctl kube-inject -f -) +``` + +Now continue to [Verify Bookinfo deployment](#verify). + +
diff --git a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/expose-services.mdx b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/expose-services.mdx index a6212a8efa02..2da9d997454c 100644 --- a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/expose-services.mdx +++ b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/expose-services.mdx @@ -1,292 +1,292 @@ ---- -docType: "Chapter" -chapterTitle: "Exposing services through Istio Ingress Gateway" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 3 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; - - -The components deployed on the service mesh by default are not exposed outside the cluster. An Ingress Gateway is deployed as a Kubernetes service of type LoadBalancer (or NodePort). To make Bookinfo accessible external to the cluster, you have to create an `Istio Gateway` for the Bookinfo application and also define an `Istio VirtualService` with the routes we need. - -
-
- -

Inspecting the Istio Ingress Gateway

- -
-The ingress gateway gets exposed as a normal Kubernetes service of type LoadBalancer -(or NodePort): - -```sh -kubectl get svc istio-ingressgateway -n istio-system -o yaml -``` - -Because the Istio Ingress Gateway is an Envoy Proxy you can inspect it using the admin routes. First find the name of the istio-ingressgateway: - -```sh -kubectl get pods -n istio-system -``` - -Copy and paste your ingress gateway's pod name. Execute: - -```sh -kubectl -n istio-system exec -it bash -``` - -You can view the statistics, listeners, routes, clusters and server info for the Envoy proxy by forwarding the local port: - -```sh -curl localhost:15000/help -curl localhost:15000/stats -curl localhost:15000/listeners -curl localhost:15000/clusters -curl localhost:15000/server_info -``` - -See the [admin docs](https://www.envoyproxy.io/docs/envoy/latest/operations/admin) for more details. - -Also it can be helpful to look at the log files of the Istio ingress controller to see what request is being routed. - -Before we check the logs, let us get out of the container back on the host: - -```sh -exit -``` - -Now let us find the ingress pod and output the log: - -```sh -kubectl logs istio-ingressgateway-... -n istio-system -``` - -

View Istio Ingress Gateway for Bookinfo

-
- -

View the Gateway and VirtualServices

- -Check the created `Istio Gateway` and `Istio VirtualService` to see the changes deployed: - -```sh -kubectl get gateway -kubectl get gateway -o yaml - -kubectl get virtualservices -kubectl get virtualservices -o yaml -``` - -

- Find the external port of the Istio Ingress Gateway by running: -

- -```sh -kubectl get service istio-ingressgateway -n istio-system -o wide -``` - -To just get the first port of istio-ingressgateway service, we can run this: - -```sh -kubectl get service istio-ingressgateway -n istio-system --template='{{(index .spec.ports 1).nodePort}}' -``` - -

Create a DNS entry:

- -Modify you local `/etc/hosts` file to add an entry for your sample application. - -`127.0.0.1. bookinfo.meshery.io` - -The HTTP port is usually 31380. - -Or run these commands to retrieve the full URL: - -```sh -echo "http://$(kubectl get nodes --selector=kubernetes.io/role!=master -o jsonpath={.items[0].status.addresses[?\(@.type==\"InternalIP\"\)].address}):$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[1].nodePort}')/productpage" -``` - -Docker Desktop users please use `http://localhost/productpage` to access product page in your browser. - -In case you are using a managed kubernetes cluster like AKS, EKS, or GCE please follow the procedure described below: - -- Get the external IP of the service istio-ingressgateway using the following command: - - ```sh - kubectl get service istio-ingressgateway -n istio-system - ``` - -- Using Meshery, navigate to the Custom yaml page, and apply the manifest given below to allow all hosts instead of allowing bookinfo.meshery.io only and you are good to access the page using the following url `http:///productpage`. - -```yaml -apiVersion: networking.istio.io/v1beta1 -kind: VirtualService -metadata: - name: bookinfo -spec: - gateways: - - sample-app-gateway - hosts: - - "*" - http: - - match: - - uri: - exact: /productpage - - uri: - prefix: /static - - uri: - exact: /login - - uri: - exact: /logout - - uri: - prefix: /api/v1/products - route: - - destination: - host: productpage - port: - number: 9080 -``` - -

Apply default destination rules

- -Before we start playing with Istio's traffic management capabilities we need to define the available versions of the deployed services. They are called subsets, in destination rules. - -Using Meshery, navigate to the Custom yaml page, and apply the below to create the subsets for BookInfo: - -```sh -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: - name: productpage -spec: - host: productpage - subsets: - - name: v1 - labels: - version: v1 ---- -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: - name: reviews -spec: - host: reviews - subsets: - - name: v1 - labels: - version: v1 - - name: v2 - labels: - version: v2 - - name: v3 - labels: - version: v3 ---- -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: - name: ratings -spec: - host: ratings - subsets: - - name: v1 - labels: - version: v1 - - name: v2 - labels: - version: v2 - - name: v2-mysql - labels: - version: v2-mysql - - name: v2-mysql-vm - labels: - version: v2-mysql-vm ---- -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: - name: details -spec: - host: details - subsets: - - name: v1 - labels: - version: v1 - - name: v2 - labels: - version: v2 -``` - -This creates destination rules for each of the BookInfo services and defines version subsets - -In a few seconds we should be able to verify the destination rules created by using the command below: - -```sh -kubectl get destinationrules - - -kubectl get destinationrules -o yaml -``` - -

Browse to BookInfo

- -Browse to the website of the Bookinfo. To view the product page, you will have to append -`/productpage` to the url. - -

Reload Page

- -Now, reload the page multiple times and notice how it round robins between v1, v2 and v3 of the reviews service. - -

- Inspect the Istio proxy of the productpage pod -

- -To better understand the istio proxy, let's inspect the details. Let us `exec` into the productpage pod to find the proxy details. To do so we need to first find the full pod name and then `exec` into the istio-proxy container: - -```sh -kubectl get pods -kubectl exec -it productpage-v1-... -c istio-proxy sh -``` - -Once in the container look at some of the envoy proxy details by inspecting it's config file: - -```sh -ps aux -ls -l /etc/istio/proxy -cat /etc/istio/proxy/envoy-rev0.json -``` - -For more details on envoy proxy please check out their [admin docs](https://www.envoyproxy.io/docs/envoy/v1.5.0/operations/admin). - -As a last step, lets exit the container: - -```sh -exit -``` - -
-

Alternative: Manual installation

-Follow this if the above steps did not work for you - -
-
- -

Default destination rules

- -Run the following command to create default destination rules for the Bookinfo services: - -```sh -kubectl apply -f samples/bookinfo/networking/destination-rule-all-mtls.yaml -``` - -

- Configure the Bookinfo route with the Istio Ingress gateway -

- -We can create a virtualservice & gateway for bookinfo app in the ingress gateway by running the following: - -```sh -kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml -``` - -
+--- +docType: "Chapter" +chapterTitle: "Exposing services through Istio Ingress Gateway" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 3 +--- + + + + +The components deployed on the service mesh by default are not exposed outside the cluster. An Ingress Gateway is deployed as a Kubernetes service of type LoadBalancer (or NodePort). To make Bookinfo accessible external to the cluster, you have to create an `Istio Gateway` for the Bookinfo application and also define an `Istio VirtualService` with the routes we need. + +
+
+ +

Inspecting the Istio Ingress Gateway

+ +
+The ingress gateway gets exposed as a normal Kubernetes service of type LoadBalancer +(or NodePort): + +```sh +kubectl get svc istio-ingressgateway -n istio-system -o yaml +``` + +Because the Istio Ingress Gateway is an Envoy Proxy you can inspect it using the admin routes. First find the name of the istio-ingressgateway: + +```sh +kubectl get pods -n istio-system +``` + +Copy and paste your ingress gateway's pod name. Execute: + +```sh +kubectl -n istio-system exec -it bash +``` + +You can view the statistics, listeners, routes, clusters and server info for the Envoy proxy by forwarding the local port: + +```sh +curl localhost:15000/help +curl localhost:15000/stats +curl localhost:15000/listeners +curl localhost:15000/clusters +curl localhost:15000/server_info +``` + +See the [admin docs](https://www.envoyproxy.io/docs/envoy/latest/operations/admin) for more details. + +Also it can be helpful to look at the log files of the Istio ingress controller to see what request is being routed. + +Before we check the logs, let us get out of the container back on the host: + +```sh +exit +``` + +Now let us find the ingress pod and output the log: + +```sh +kubectl logs istio-ingressgateway-... -n istio-system +``` + +

View Istio Ingress Gateway for Bookinfo

+
+ +

View the Gateway and VirtualServices

+ +Check the created `Istio Gateway` and `Istio VirtualService` to see the changes deployed: + +```sh +kubectl get gateway +kubectl get gateway -o yaml + +kubectl get virtualservices +kubectl get virtualservices -o yaml +``` + +

+ Find the external port of the Istio Ingress Gateway by running: +

+ +```sh +kubectl get service istio-ingressgateway -n istio-system -o wide +``` + +To just get the first port of istio-ingressgateway service, we can run this: + +```sh +kubectl get service istio-ingressgateway -n istio-system --template='{{(index .spec.ports 1).nodePort}}' +``` + +

Create a DNS entry:

+ +Modify you local `/etc/hosts` file to add an entry for your sample application. + +`127.0.0.1. bookinfo.meshery.io` + +The HTTP port is usually 31380. + +Or run these commands to retrieve the full URL: + +```sh +echo "http://$(kubectl get nodes --selector=kubernetes.io/role!=master -o jsonpath={.items[0].status.addresses[?\(@.type==\"InternalIP\"\)].address}):$(kubectl get svc istio-ingressgateway -n istio-system -o jsonpath='{.spec.ports[1].nodePort}')/productpage" +``` + +Docker Desktop users please use `http://localhost/productpage` to access product page in your browser. + +In case you are using a managed kubernetes cluster like AKS, EKS, or GCE please follow the procedure described below: + +- Get the external IP of the service istio-ingressgateway using the following command: + + ```sh + kubectl get service istio-ingressgateway -n istio-system + ``` + +- Using Meshery, navigate to the Custom yaml page, and apply the manifest given below to allow all hosts instead of allowing bookinfo.meshery.io only and you are good to access the page using the following url `http:///productpage`. + +```yaml +apiVersion: networking.istio.io/v1beta1 +kind: VirtualService +metadata: + name: bookinfo +spec: + gateways: + - sample-app-gateway + hosts: + - "*" + http: + - match: + - uri: + exact: /productpage + - uri: + prefix: /static + - uri: + exact: /login + - uri: + exact: /logout + - uri: + prefix: /api/v1/products + route: + - destination: + host: productpage + port: + number: 9080 +``` + +

Apply default destination rules

+ +Before we start playing with Istio's traffic management capabilities we need to define the available versions of the deployed services. They are called subsets, in destination rules. + +Using Meshery, navigate to the Custom yaml page, and apply the below to create the subsets for BookInfo: + +```sh +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: productpage +spec: + host: productpage + subsets: + - name: v1 + labels: + version: v1 +--- +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: reviews +spec: + host: reviews + subsets: + - name: v1 + labels: + version: v1 + - name: v2 + labels: + version: v2 + - name: v3 + labels: + version: v3 +--- +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: ratings +spec: + host: ratings + subsets: + - name: v1 + labels: + version: v1 + - name: v2 + labels: + version: v2 + - name: v2-mysql + labels: + version: v2-mysql + - name: v2-mysql-vm + labels: + version: v2-mysql-vm +--- +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: details +spec: + host: details + subsets: + - name: v1 + labels: + version: v1 + - name: v2 + labels: + version: v2 +``` + +This creates destination rules for each of the BookInfo services and defines version subsets + +In a few seconds we should be able to verify the destination rules created by using the command below: + +```sh +kubectl get destinationrules + + +kubectl get destinationrules -o yaml +``` + +

Browse to BookInfo

+ +Browse to the website of the Bookinfo. To view the product page, you will have to append +`/productpage` to the url. + +

Reload Page

+ +Now, reload the page multiple times and notice how it round robins between v1, v2 and v3 of the reviews service. + +

+ Inspect the Istio proxy of the productpage pod +

+ +To better understand the istio proxy, let's inspect the details. Let us `exec` into the productpage pod to find the proxy details. To do so we need to first find the full pod name and then `exec` into the istio-proxy container: + +```sh +kubectl get pods +kubectl exec -it productpage-v1-... -c istio-proxy sh +``` + +Once in the container look at some of the envoy proxy details by inspecting it's config file: + +```sh +ps aux +ls -l /etc/istio/proxy +cat /etc/istio/proxy/envoy-rev0.json +``` + +For more details on envoy proxy please check out their [admin docs](https://www.envoyproxy.io/docs/envoy/v1.5.0/operations/admin). + +As a last step, lets exit the container: + +```sh +exit +``` + +
+

Alternative: Manual installation

+Follow this if the above steps did not work for you + +
+
+ +

Default destination rules

+ +Run the following command to create default destination rules for the Bookinfo services: + +```sh +kubectl apply -f samples/bookinfo/networking/destination-rule-all-mtls.yaml +``` + +

+ Configure the Bookinfo route with the Istio Ingress gateway +

+ +We can create a virtualservice & gateway for bookinfo app in the ingress gateway by running the following: + +```sh +kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml +``` + +
diff --git a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/fault-injection.mdx b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/fault-injection.mdx index 49fa69a3e96d..75b6176d640e 100644 --- a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/fault-injection.mdx +++ b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/fault-injection.mdx @@ -1,186 +1,186 @@ ---- -docType: "Chapter" -chapterTitle: "Fault Injection" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 6 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; - - - -In this chapter we will learn how to test the resiliency of an application by injecting systematic faults. -Before we start, we will need to reset the virtual services. - -Using Meshery, navigate to the Istio management page: - -1. Enter `default` in the `Namespace` field. -2. Click the (+) icon on the `Apply Custom Configuration` card and paste the configuration below. - -Config: - -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: reviews -spec: - hosts: - - reviews - http: - - route: - - destination: - host: reviews - subset: v2 -``` - -

- Inject a route rule to create a fault using HTTP delay -

- -To start, we will inject a 7s delay for accessing the ratings service for a user `jason`. reviews v2 service has a 10s hard-coded connection timeout for its calls to the ratings service configured globally. - -Using Meshery, navigate to the Istio management page: - -1. Enter `default` in the `Namespace` field. -2. Click the (+) icon on the `Apply Custom Configuration` card and paste the configuration below. - -This will update the existing virtual service definition for ratings to inject a delay for user `jason` to access the ratings V1. - -In a few, we should be able to verify the virtual service by using the command below: - -```sh -kubectl get virtualservice ratings -o yaml -``` - -Config: - -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: ratings -spec: - hosts: - - ratings - http: - - fault: - delay: - fixedDelay: 7s - percentage: - value: 100 - match: - - headers: - end-user: - exact: jason - route: - - destination: - host: ratings - subset: v1 - - route: - - destination: - host: ratings - subset: v1 -``` - -Now we login to `/productpage` as user `jason` and observe that the page loads but because of the induced delay between services the reviews section will show : - -Error fetching product reviews! -Sorry, product reviews are currently unavailable for this book. - -If you logout or login as a different user, the page should load normally without any errors. - -

- Inject a route rule to create a fault using HTTP abort -

- -In this section, , we will introduce an HTTP abort to the ratings microservices for user `jason`. - -Using Meshery, navigate to the Istio management page: - -1. Enter `default` in the `Namespace` field. -2. Click the (+) icon on the `Apply Custom Configuration` card and paste the configuration below. - -This will update the existing virtual service definition for ratings to inject a HTTP abort for user `jason` to access the ratings V1. - -In a few, we should be able to verify the virtual service by using the command below: - -```sh -kubectl get virtualservice ratings -o yaml -``` - -Config: - -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: ratings -spec: - hosts: - - ratings - http: - - fault: - abort: - httpStatus: 500 - percentage: - value: 100 - match: - - headers: - end-user: - exact: jason - route: - - destination: - host: ratings - subset: v1 - - route: - - destination: - host: ratings - subset: v1 -``` - -Now we login to `/productpage` as user `jason` and observe that the page loads without any new delays but because of the induced fault between services the reviews section will show: - -`Ratings service is currently unavailable`. - -

Verify fault injection

- -Verify the fault injection by logging out (or logging in as a different user), the page should load normally without any errors. - -
-

Alternative: Manual installation

-Follow these steps if the above steps did not work -
-
- -

- Route all traffic to version V1 of all services -

- -```sh -kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml -``` - -

- Route all traffic to version V2 of reviews for user Jason -

- -```sh -kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml -``` - -

Inject 7s delay for ratings service

- -```sh -kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml -``` - -

Inject HTTP abort for ratings service

- -```sh -kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml -``` - -
+--- +docType: "Chapter" +chapterTitle: "Fault Injection" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 6 +--- + + + + + +In this chapter we will learn how to test the resiliency of an application by injecting systematic faults. +Before we start, we will need to reset the virtual services. + +Using Meshery, navigate to the Istio management page: + +1. Enter `default` in the `Namespace` field. +2. Click the (+) icon on the `Apply Custom Configuration` card and paste the configuration below. + +Config: + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: reviews +spec: + hosts: + - reviews + http: + - route: + - destination: + host: reviews + subset: v2 +``` + +

+ Inject a route rule to create a fault using HTTP delay +

+ +To start, we will inject a 7s delay for accessing the ratings service for a user `jason`. reviews v2 service has a 10s hard-coded connection timeout for its calls to the ratings service configured globally. + +Using Meshery, navigate to the Istio management page: + +1. Enter `default` in the `Namespace` field. +2. Click the (+) icon on the `Apply Custom Configuration` card and paste the configuration below. + +This will update the existing virtual service definition for ratings to inject a delay for user `jason` to access the ratings V1. + +In a few, we should be able to verify the virtual service by using the command below: + +```sh +kubectl get virtualservice ratings -o yaml +``` + +Config: + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: ratings +spec: + hosts: + - ratings + http: + - fault: + delay: + fixedDelay: 7s + percentage: + value: 100 + match: + - headers: + end-user: + exact: jason + route: + - destination: + host: ratings + subset: v1 + - route: + - destination: + host: ratings + subset: v1 +``` + +Now we login to `/productpage` as user `jason` and observe that the page loads but because of the induced delay between services the reviews section will show : + +Error fetching product reviews! +Sorry, product reviews are currently unavailable for this book. + +If you logout or login as a different user, the page should load normally without any errors. + +

+ Inject a route rule to create a fault using HTTP abort +

+ +In this section, , we will introduce an HTTP abort to the ratings microservices for user `jason`. + +Using Meshery, navigate to the Istio management page: + +1. Enter `default` in the `Namespace` field. +2. Click the (+) icon on the `Apply Custom Configuration` card and paste the configuration below. + +This will update the existing virtual service definition for ratings to inject a HTTP abort for user `jason` to access the ratings V1. + +In a few, we should be able to verify the virtual service by using the command below: + +```sh +kubectl get virtualservice ratings -o yaml +``` + +Config: + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: ratings +spec: + hosts: + - ratings + http: + - fault: + abort: + httpStatus: 500 + percentage: + value: 100 + match: + - headers: + end-user: + exact: jason + route: + - destination: + host: ratings + subset: v1 + - route: + - destination: + host: ratings + subset: v1 +``` + +Now we login to `/productpage` as user `jason` and observe that the page loads without any new delays but because of the induced fault between services the reviews section will show: + +`Ratings service is currently unavailable`. + +

Verify fault injection

+ +Verify the fault injection by logging out (or logging in as a different user), the page should load normally without any errors. + +
+

Alternative: Manual installation

+Follow these steps if the above steps did not work +
+
+ +

+ Route all traffic to version V1 of all services +

+ +```sh +kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml +``` + +

+ Route all traffic to version V2 of reviews for user Jason +

+ +```sh +kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml +``` + +

Inject 7s delay for ratings service

+ +```sh +kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-delay.yaml +``` + +

Inject HTTP abort for ratings service

+ +```sh +kubectl apply -f samples/bookinfo/networking/virtual-service-ratings-test-abort.yaml +``` + +
diff --git a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/getting-started.mdx b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/getting-started.mdx index 83b8badaa503..057e506facd9 100644 --- a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/getting-started.mdx +++ b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/getting-started.mdx @@ -1,134 +1,134 @@ ---- -docType: "Chapter" -chapterTitle: "Getting Started" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 1 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; -import InstallIstio from "../../../../src/assets/images/learn-layer5/istio/install-istio1.webp"; -import IstioDeploy from "../../../../src/assets/images/learn-layer5/istio/install-istio2.webp"; - - - -

Setup Istio

- -Now that we have a Kubernetes cluster and Meshery, we are ready to download and deploy Istio resources. - -

Steps

- -1. [Install Istio](#1) -1. [Verify install](#2) - -Optional (manual install of Istio): - -1. [Download Istio resources](#1.1) -1. [Setup `istioctl`](#1.2) -1. [Install istio](#1.3) - -

- Install Istio -

- -Using Meshery, select `Istio` from the `Lifecycle` menu. - -In the Istio management page: - -1. Type `istio-system` into the namespace field. -2. Click the (+) icon on the `Install` card and click on `Istio Service Mesh` to install latest version of Istio. - - - - - -3. Click the `Deploy` button on the confirmation modal. - - - - - -

Alternative:Manual installation

-Perform the below steps if the above steps doesn't work for you. - -
-
- -

- Download Istio -

- -You will download and deploy the latest Istio resources on your Kubernetes cluster. - -**_Note to Docker Desktop users:_** Please ensure your Docker VM has atleast 4GiB of Memory, which is required for all services to run. - -On your local machine, execute: - -```sh -curl -L https://git.io/getLatestIstio | ISTIO_VERSION=1.7.3 sh - -``` - -

- Setting up istioctl -

- -On a \*nix system, you can setup `istioctl` by doing the following: - -```sh -brew install istioctl -``` - -Alternatively, change into the Istio package directory and add the `istioctl` client to your PATH environment variable. - -```sh -cd istio-* -export PATH=$PWD/bin:$PATH -``` - -Verify `istioctl` is available: - -```sh -istioctl version -``` - -Check if the cluster is ready for installation: - -```sh -istioctl verify-install -``` - -

- Install Istio -

- -To install Istio with a `demo` profile, execute the below command. - -```sh -istioctl install --set profile=demo -``` - -Alternatively, with Envoy logging enabled: - -```sh -istioctl install --set profile=demo --set meshConfig.accessLogFile=/dev/stdout -``` - -

- Verify install -

- -In the Istio management page: - -1. Click the (+) icon on the `Validate Service Mesh Configuration` card. -1. Select `Verify Installation` to verify the installation of Istio. - -

Alternatively:

- -Istio is deployed in a separate Kubernetes namespace `istio-system`. To check if Istio is deployed, and also, to see all the pieces that are deployed, execute the following: - -```sh -kubectl get all -n istio-system -``` - -
+--- +docType: "Chapter" +chapterTitle: "Getting Started" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 1 +--- + + +import InstallIstio from "../../../../src/assets/images/learn-layer5/istio/install-istio1.webp"; +import IstioDeploy from "../../../../src/assets/images/learn-layer5/istio/install-istio2.webp"; + + + +

Setup Istio

+ +Now that we have a Kubernetes cluster and Meshery, we are ready to download and deploy Istio resources. + +

Steps

+ +1. [Install Istio](#1) +1. [Verify install](#2) + +Optional (manual install of Istio): + +1. [Download Istio resources](#1.1) +1. [Setup `istioctl`](#1.2) +1. [Install istio](#1.3) + +

+ Install Istio +

+ +Using Meshery, select `Istio` from the `Lifecycle` menu. + +In the Istio management page: + +1. Type `istio-system` into the namespace field. +2. Click the (+) icon on the `Install` card and click on `Istio Service Mesh` to install latest version of Istio. + + + + + +3. Click the `Deploy` button on the confirmation modal. + + + + + +

Alternative:Manual installation

+Perform the below steps if the above steps doesn't work for you. + +
+
+ +

+ Download Istio +

+ +You will download and deploy the latest Istio resources on your Kubernetes cluster. + +**_Note to Docker Desktop users:_** Please ensure your Docker VM has atleast 4GiB of Memory, which is required for all services to run. + +On your local machine, execute: + +```sh +curl -L https://git.io/getLatestIstio | ISTIO_VERSION=1.7.3 sh - +``` + +

+ Setting up istioctl +

+ +On a \*nix system, you can setup `istioctl` by doing the following: + +```sh +brew install istioctl +``` + +Alternatively, change into the Istio package directory and add the `istioctl` client to your PATH environment variable. + +```sh +cd istio-* +export PATH=$PWD/bin:$PATH +``` + +Verify `istioctl` is available: + +```sh +istioctl version +``` + +Check if the cluster is ready for installation: + +```sh +istioctl verify-install +``` + +

+ Install Istio +

+ +To install Istio with a `demo` profile, execute the below command. + +```sh +istioctl install --set profile=demo +``` + +Alternatively, with Envoy logging enabled: + +```sh +istioctl install --set profile=demo --set meshConfig.accessLogFile=/dev/stdout +``` + +

+ Verify install +

+ +In the Istio management page: + +1. Click the (+) icon on the `Validate Service Mesh Configuration` card. +1. Select `Verify Installation` to verify the installation of Istio. + +

Alternatively:

+ +Istio is deployed in a separate Kubernetes namespace `istio-system`. To check if Istio is deployed, and also, to see all the pieces that are deployed, execute the following: + +```sh +kubectl get all -n istio-system +``` + +
diff --git a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/mutual-tls.mdx b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/mutual-tls.mdx index fd3e3c0c91e1..2e80ae71adce 100644 --- a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/mutual-tls.mdx +++ b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/mutual-tls.mdx @@ -1,203 +1,203 @@ ---- -docType: "Chapter" -chapterTitle: "Mutual TLS & Identity Verification" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 7 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; - - - -Istio provides transparent mutual TLS to services inside the service mesh where both the client and the server authenticate each others' certificates as part of the TLS handshake. As part of this course, we have deployed Istio with mTLS. - -By default istio sets mTLS in `PERMISSIVE` mode which allows plain text traffic to be sent and accepted by a mesh. We first disallow plain text traffic using `PeerAuthentication` and setting mTLS mode to STRICT. - -

Confirm mTLS is being enforced

- -This can be easily done by executing a simple command:- - -```sh -kubectl get peerauthentication --all-namespaces -``` - -

Verify mTLS

- -Citadel is Istio’s key management service. As a first step, confirm that Citadel is up and running: - -```sh -kubectl get deploy -l istio=citadel -n istio-system -``` - -Output will be similar to: - -``` -NAME READY UP-TO-DATE AVAILABLE AGE -istio-citadel 1/1 1 1 3m23s -``` - -To experiment with mTLS, let's do so by logging into the sidecar proxy of the `productpage` pod by executing this command: - -```sh -kubectl exec -it $(kubectl get pod | grep productpage | awk '{ print $1 }') -c istio-proxy -- /bin/bash -``` - -We are now in the proxy of the `productpage` pod. Check that all the ceritificates are loaded in this proxy: - -```sh -ls /etc/certs/ -``` - -You should see 3 entries: - -```sh -cert-chain.pem key.pem root-cert.pem -``` - -Now, try to make a curl call to the `details` service over HTTP: - -```sh -curl http://details:9080/details/0 -``` - -Since, we have TLS between the sidecar's, an HTTP call will not work. The request will timeout. You will see an error like the one below: - -```sh -curl: (7) Failed to connect to details port 9080: Connection timed out -``` - -Let us try to make a curl call to the details service over HTTPS but **WITHOUT** certs: - -```sh -curl https://details:9080/details/0 -k -``` - -The request will be denied and you will see an error like the one below: - -```sh -curl: (16) SSL_write() returned SYSCALL, errno = 104 -``` - -Now, let us use curl over HTTPS with certificates to the details service: - -```sh -curl https://details:9080/details/0 -v --key /etc/certs/key.pem --cert /etc/certs/cert-chain.pem --cacert /etc/certs/root-cert.pem -k -``` - -Output will be similar to this: - -```sh -* Trying 10.107.35.26... -* Connected to details (10.107.35.26) port 9080 (#0) -* found 1 certificates in /etc/certs/root-cert.pem -* found 0 certificates in /etc/ssl/certs -* ALPN, offering http/1.1 -* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256 -* server certificate verification SKIPPED -* server certificate status verification SKIPPED -* error fetching CN from cert:The requested data were not available. -* common name: (does not match 'details') -* server certificate expiration date OK -* server certificate activation date OK -* certificate public key: RSA -* certificate version: #3 -* subject: O=#1300 -* start date: Thu, 26 Oct 2018 14:36:56 GMT -* expire date: Wed, 05 Jan 2019 14:36:56 GMT -* issuer: O=k8s.cluster.local -* compression: NULL -* ALPN, server accepted to use http/1.1 -> GET /details/0 HTTP/1.1 -> Host: details:9080 -> User-Agent: curl/7.47.0 -> Accept: */* -> -< HTTP/1.1 200 OK -< content-type: application/json -< server: envoy -< date: Thu, 07 Jun 2018 15:19:46 GMT -< content-length: 178 -< x-envoy-upstream-service-time: 1 -< x-envoy-decorator-operation: default-route -< -* Connection #0 to host details left intact -{"id":0,"author":"William Shakespeare","year":1595,"type":"paperback","pages":200,"publisher":"PublisherA","language":"English","ISBN-10":"1234567890","ISBN-13":"123-1234567890"} -``` - -This proves the existence of mTLS between the services on the Istio mesh. - -Now lets come out of the container before we go to the next section: - -```sh -exit -``` - -

- Secure Production Identity Framework for Everyone (SPIFFE) -

-
-Istio uses [SPIFFE](https://spiffe.io/) to assert the identify of workloads on -the cluster. SPIFFE consists of a notion of identity and a method of proving it. -A SPIFFE identity consists of an authority part and a path. The meaning of the -path in spiffe land is implementation defined. In k8s it takes the form -`/ns/$namespace/sa/$service-account` with the expected meaning. A SPIFFE -identify is embedded in a document. This document in principle can take many -forms but currently the only defined format is x509. - -To start our investigation, let us check if the certs are in place in the productpage sidecar: - -```sh -kubectl exec $(kubectl get pod -l app=productpage -o jsonpath={.items..metadata.name}) -c istio-proxy -- ls /etc/certs -``` - -Output will be similar to: - -```sh -cert-chain.pem -key.pem -root-cert.pem -``` - -Mac users, MacOS should have openssl available. If your machine does not have openssl install, install it using your preferred method. - -Here is one way to install it on RHEL or CentOS or its derivatives: - -```sh -sudo yum install -y openssl-devel -``` - -Here is one way to install it on Ubuntu or Debian or its derivatives: - -```sh -sudo apt install -y libssl-dev -``` - -Now that we have found the certs, let us verify the certificate of productpage sidecar by running this command: - -```sh -kubectl exec $(kubectl get pod -l app=productpage -o jsonpath={.items..metadata.name}) -c istio-proxy -- cat /etc/certs/cert-chain.pem | openssl x509 -text -noout | grep Validity -A 2 -``` - -Output will be similar to: - -```sh - Not Before: Sep 23 17:32:28 2019 GMT - Not After : Dec 22 17:32:28 2019 GMT -``` - -Lets also verify the URI SAN: - -```sh -kubectl exec $(kubectl get pod -l app=productpage -o jsonpath={.items..metadata.name}) -c istio-proxy -- cat /etc/certs/cert-chain.pem | openssl x509 -text -noout | grep 'Subject Alternative Name' -A 1 -``` - -Output will be similar to: - -```sh -X509v3 Subject Alternative Name: critical - URI:spiffe://cluster.local/ns/default/sa/bookinfo-productpage -``` - -
+--- +docType: "Chapter" +chapterTitle: "Mutual TLS & Identity Verification" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 7 +--- + + + + + +Istio provides transparent mutual TLS to services inside the service mesh where both the client and the server authenticate each others' certificates as part of the TLS handshake. As part of this course, we have deployed Istio with mTLS. + +By default istio sets mTLS in `PERMISSIVE` mode which allows plain text traffic to be sent and accepted by a mesh. We first disallow plain text traffic using `PeerAuthentication` and setting mTLS mode to STRICT. + +

Confirm mTLS is being enforced

+ +This can be easily done by executing a simple command:- + +```sh +kubectl get peerauthentication --all-namespaces +``` + +

Verify mTLS

+ +Citadel is Istio’s key management service. As a first step, confirm that Citadel is up and running: + +```sh +kubectl get deploy -l istio=citadel -n istio-system +``` + +Output will be similar to: + +``` +NAME READY UP-TO-DATE AVAILABLE AGE +istio-citadel 1/1 1 1 3m23s +``` + +To experiment with mTLS, let's do so by logging into the sidecar proxy of the `productpage` pod by executing this command: + +```sh +kubectl exec -it $(kubectl get pod | grep productpage | awk '{ print $1 }') -c istio-proxy -- /bin/bash +``` + +We are now in the proxy of the `productpage` pod. Check that all the ceritificates are loaded in this proxy: + +```sh +ls /etc/certs/ +``` + +You should see 3 entries: + +```sh +cert-chain.pem key.pem root-cert.pem +``` + +Now, try to make a curl call to the `details` service over HTTP: + +```sh +curl http://details:9080/details/0 +``` + +Since, we have TLS between the sidecar's, an HTTP call will not work. The request will timeout. You will see an error like the one below: + +```sh +curl: (7) Failed to connect to details port 9080: Connection timed out +``` + +Let us try to make a curl call to the details service over HTTPS but **WITHOUT** certs: + +```sh +curl https://details:9080/details/0 -k +``` + +The request will be denied and you will see an error like the one below: + +```sh +curl: (16) SSL_write() returned SYSCALL, errno = 104 +``` + +Now, let us use curl over HTTPS with certificates to the details service: + +```sh +curl https://details:9080/details/0 -v --key /etc/certs/key.pem --cert /etc/certs/cert-chain.pem --cacert /etc/certs/root-cert.pem -k +``` + +Output will be similar to this: + +```sh +* Trying 10.107.35.26... +* Connected to details (10.107.35.26) port 9080 (#0) +* found 1 certificates in /etc/certs/root-cert.pem +* found 0 certificates in /etc/ssl/certs +* ALPN, offering http/1.1 +* SSL connection using TLS1.2 / ECDHE_RSA_AES_128_GCM_SHA256 +* server certificate verification SKIPPED +* server certificate status verification SKIPPED +* error fetching CN from cert:The requested data were not available. +* common name: (does not match 'details') +* server certificate expiration date OK +* server certificate activation date OK +* certificate public key: RSA +* certificate version: #3 +* subject: O=#1300 +* start date: Thu, 26 Oct 2018 14:36:56 GMT +* expire date: Wed, 05 Jan 2019 14:36:56 GMT +* issuer: O=k8s.cluster.local +* compression: NULL +* ALPN, server accepted to use http/1.1 +> GET /details/0 HTTP/1.1 +> Host: details:9080 +> User-Agent: curl/7.47.0 +> Accept: */* +> +< HTTP/1.1 200 OK +< content-type: application/json +< server: envoy +< date: Thu, 07 Jun 2018 15:19:46 GMT +< content-length: 178 +< x-envoy-upstream-service-time: 1 +< x-envoy-decorator-operation: default-route +< +* Connection #0 to host details left intact +{"id":0,"author":"William Shakespeare","year":1595,"type":"paperback","pages":200,"publisher":"PublisherA","language":"English","ISBN-10":"1234567890","ISBN-13":"123-1234567890"} +``` + +This proves the existence of mTLS between the services on the Istio mesh. + +Now lets come out of the container before we go to the next section: + +```sh +exit +``` + +

+ Secure Production Identity Framework for Everyone (SPIFFE) +

+
+Istio uses [SPIFFE](https://spiffe.io/) to assert the identify of workloads on +the cluster. SPIFFE consists of a notion of identity and a method of proving it. +A SPIFFE identity consists of an authority part and a path. The meaning of the +path in spiffe land is implementation defined. In k8s it takes the form +`/ns/$namespace/sa/$service-account` with the expected meaning. A SPIFFE +identify is embedded in a document. This document in principle can take many +forms but currently the only defined format is x509. + +To start our investigation, let us check if the certs are in place in the productpage sidecar: + +```sh +kubectl exec $(kubectl get pod -l app=productpage -o jsonpath={.items..metadata.name}) -c istio-proxy -- ls /etc/certs +``` + +Output will be similar to: + +```sh +cert-chain.pem +key.pem +root-cert.pem +``` + +Mac users, MacOS should have openssl available. If your machine does not have openssl install, install it using your preferred method. + +Here is one way to install it on RHEL or CentOS or its derivatives: + +```sh +sudo yum install -y openssl-devel +``` + +Here is one way to install it on Ubuntu or Debian or its derivatives: + +```sh +sudo apt install -y libssl-dev +``` + +Now that we have found the certs, let us verify the certificate of productpage sidecar by running this command: + +```sh +kubectl exec $(kubectl get pod -l app=productpage -o jsonpath={.items..metadata.name}) -c istio-proxy -- cat /etc/certs/cert-chain.pem | openssl x509 -text -noout | grep Validity -A 2 +``` + +Output will be similar to: + +```sh + Not Before: Sep 23 17:32:28 2019 GMT + Not After : Dec 22 17:32:28 2019 GMT +``` + +Lets also verify the URI SAN: + +```sh +kubectl exec $(kubectl get pod -l app=productpage -o jsonpath={.items..metadata.name}) -c istio-proxy -- cat /etc/certs/cert-chain.pem | openssl x509 -text -noout | grep 'Subject Alternative Name' -A 1 +``` + +Output will be similar to: + +```sh +X509v3 Subject Alternative Name: critical + URI:spiffe://cluster.local/ns/default/sa/bookinfo-productpage +``` + +
diff --git a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/observability.mdx b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/observability.mdx index ef5a5ceecc73..c263773c8cf5 100644 --- a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/observability.mdx +++ b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/observability.mdx @@ -1,246 +1,246 @@ ---- -docType: "Chapter" -chapterTitle: "Observability" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 4 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; -import ImageAppIcon from "../../../../src/assets/images/learn-layer5/istio/istio-addons.webp"; -import GraffanaDash from "../../../../src/assets/images/learn-layer5/istio/Grafana_Istio_Dashboard.webp"; -import Prometheus from "../../../../src/assets/images/learn-layer5/istio/Prometheus.webp"; -import Jaeger from "../../../../src/assets/images/learn-layer5/istio/jaeger.webp"; - - - -

Install Telemetry Add-ons

- -Using Meshery, install Istio telemetry add-ons. In the Istio management page: - -1. Click the (+) icon on the `Apply Service Mesh Configuration` card. -1. Select each of the following add-ons: - 1. [Prometheus](https://prometheus.io/) - 1. [Grafana](https://grafana.com/) - 1. [Jaeger](https://www.jaegertracing.io/) - - - - - -You will use Prometheus and Grafana for collecting and viewing metrics and [Jaeger](https://www.jaegertracing.io/) collecting and viewing distributed traces. Expose each add-on external to the cluster. Each the service network typs are set to "LoadBalancer". - -

Service Mesh Performance and Telemetry

- -Many of the labs require load to be placed on the sample apps. Let's generate HTTP traffic against the BookInfo application, so we can see interesting telemetry. - -Verify access through the Ingress Gateway: - -```sh -kubectl get service istio-ingressgateway -n istio-system -``` - -Once we have the port, we can append the IP of one of the nodes to get the host. - -The URL to run a load test against will be `http://:/productpage` - -**Please note:** If you are using Docker Desktop, please use the IP address of your host. You can leave the port blank. For example: `http://1.2.3.4/productpage`. Managed kubernetes service users will need to use `http:///productpage` as done in expose services section. - -Use the computed URL above in Meshery, in the browser, to run a load test and see the results. - -

- Connect Grafana (optionally, Prometheus) to Meshery. -

- -On the Settings page: - -1. Navigate to the `Metrics` tab. -1. Enter Grafana's URL:port number and submit. - -

- Use Meshery to generate load and analyze performance. -

- -On the Performance page: - -1. give this load test a memorable name -1. enter the URL to the BookInfo productpage -1. select `Istio` in the `Service Mesh` dropdown -1. enter a valid number for `Concurrent requests` -1. enter a valid number for `Queries per second` -1. enter a valid `Duration` (a number followed by `s` for seconds (OR) `m` for minutes (OR) `h` for hour) -1. use the host IP address in the request Tab and in the advanced options, type in the header as `Host:` - -Click on `Run Test`. A performance test will run and statistical analysis performed. Examine the results of the test and behavior of the service mesh. - -Next, you will begin controlling requests to BookInfo using traffic management features. - -
-

Alternative: Manual installation

-Follow these steps if the above steps did not work -
-
- -

Install Add-ons:

-
- -**Prometheus** - -```sh -kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/addons/prometheus.yaml - -``` - -**Grafana** - -```sh -kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/addons/grafana.yaml - -``` - -**Jaeger** - -```sh -kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/addons/jaeger.yaml - -``` - -

Exposing services

- -Istio add-on services are deployed by default as `ClusterIP` type services. We can expose the services outside the cluster by either changing the Kubernetes service type to `NodePort` or `LoadBalancer` or by port-forwarding or by configuring Kubernetes Ingress. - -**Option 1: Expose services with NodePort** -To expose them using NodePort service type, we can edit the services and change the service type from `ClusterIP` to `NodePort` - -**Option 2: Expose services with port-forwarding** -Port-forwarding runs in the foreground. We have appeneded `&` to the end of the above 2 commands to run them in the background. If you donot want this behavior, please remove the `&` from the end. - -

Prometheus

- -You will need to expose the Prometheus service on a port either of the two following methods: - -**Option 1: Expose services with NodePort** - -```sh -kubectl -n istio-system edit svc prometheus -``` - -To find the assigned ports for Prometheus: - -```sh -kubectl -n istio-system get svc prometheus -``` - -**Option 2: Expose Prometheus service with port-forwarding:** -\*\* -Expose Prometheus service with port-forwarding: - -```sh -kubectl -n istio-system port-forward \ - $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') \ - 9090:9090 & -``` - -Browse to `http://:` and in the `Expression` input box enter: `istio_request_bytes_count`. Click the Execute button. - -
- - -
-
-

Grafana

- -You will need to expose the Grafana service on a port either of the two following methods: - -```sh -kubectl -n istio-system edit svc grafana -``` - -Once this is done the services will be assigned dedicated ports on the hosts. - -To find the assigned ports for Grafana: - -```sh -kubectl -n istio-system get svc grafana -``` - -**Expose Grafana service with port-forwarding:** - -```sh -kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana \ - -o jsonpath='{.items[0].metadata.name}') 3000:3000 & -``` - - - -
-
-

Distributed Tracing

- -The sample Bookinfo application is configured to collect trace spans using Zipkin or Jaeger. Although Istio proxies are able to automatically send spans, it needs help from the application to tie together the entire trace. To do this applications need to propagate the appropriate HTTP headers so that when the proxies send span information to Zipkin or Jaeger, the spans can be correlated correctly into a single trace. - -To do this the application collects and propagates the following headers from the incoming request to any outgoing requests: - -- `x-request-id` -- `x-b3-traceid` -- `x-b3-spanid` -- `x-b3-parentspanid` -- `x-b3-sampled` -- `x-b3-flags` -- `x-ot-span-context` - -
- - - - - -
-
- -

Exposing services

- -Istio add-on services are deployed by default as `ClusterIP` type services. We can expose the services outside the cluster by either changing the Kubernetes service type to `NodePort` or `LoadBalancer` or by port-forwarding or by configuring Kubernetes Ingress. In this lab, we will briefly demonstrate the `NodePort` and port-forwarding ways of exposing services. - -
Option 1: Expose services with NodePort
- -To expose them using NodePort service type, we can edit the services and change the service type from `ClusterIP` to `NodePort` - -For Jaeger, either of `tracing` or `jaeger-query` can be exposed. - -```sh -kubectl -n istio-system edit svc tracing -``` - -Once this is done the services will be assigned dedicated ports on the hosts. - -To find the assigned ports for Jaeger: - -```sh -kubectl -n istio-system get svc tracing -``` - -
- Option 2: Expose services with port-forwarding -
- -To port-forward Jaeger: - -```sh -kubectl -n istio-system port-forward \ - $(kubectl -n istio-system get pod -l app=jaeger -o jsonpath='{.items[0].metadata.name}') \ - 16686:16686 & -``` - -

View Traces

- -Let us find the port Jaeger is exposed on by running the following command: - -```sh -kubectl -n istio-system get svc tracing -``` - -You can click on the link at the top of the page which maps to the right port and it will open Jaeger UI in a new tab. - -
+--- +docType: "Chapter" +chapterTitle: "Observability" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 4 +--- + + +import ImageAppIcon from "../../../../src/assets/images/learn-layer5/istio/istio-addons.webp"; +import GraffanaDash from "../../../../src/assets/images/learn-layer5/istio/Grafana_Istio_Dashboard.webp"; +import Prometheus from "../../../../src/assets/images/learn-layer5/istio/Prometheus.webp"; +import Jaeger from "../../../../src/assets/images/learn-layer5/istio/jaeger.webp"; + + + +

Install Telemetry Add-ons

+ +Using Meshery, install Istio telemetry add-ons. In the Istio management page: + +1. Click the (+) icon on the `Apply Service Mesh Configuration` card. +1. Select each of the following add-ons: + 1. [Prometheus](https://prometheus.io/) + 1. [Grafana](https://grafana.com/) + 1. [Jaeger](https://www.jaegertracing.io/) + + + + + +You will use Prometheus and Grafana for collecting and viewing metrics and [Jaeger](https://www.jaegertracing.io/) collecting and viewing distributed traces. Expose each add-on external to the cluster. Each the service network typs are set to "LoadBalancer". + +

Service Mesh Performance and Telemetry

+ +Many of the labs require load to be placed on the sample apps. Let's generate HTTP traffic against the BookInfo application, so we can see interesting telemetry. + +Verify access through the Ingress Gateway: + +```sh +kubectl get service istio-ingressgateway -n istio-system +``` + +Once we have the port, we can append the IP of one of the nodes to get the host. + +The URL to run a load test against will be `http://:/productpage` + +**Please note:** If you are using Docker Desktop, please use the IP address of your host. You can leave the port blank. For example: `http://1.2.3.4/productpage`. Managed kubernetes service users will need to use `http:///productpage` as done in expose services section. + +Use the computed URL above in Meshery, in the browser, to run a load test and see the results. + +

+ Connect Grafana (optionally, Prometheus) to Meshery. +

+ +On the Settings page: + +1. Navigate to the `Metrics` tab. +1. Enter Grafana's URL:port number and submit. + +

+ Use Meshery to generate load and analyze performance. +

+ +On the Performance page: + +1. give this load test a memorable name +1. enter the URL to the BookInfo productpage +1. select `Istio` in the `Service Mesh` dropdown +1. enter a valid number for `Concurrent requests` +1. enter a valid number for `Queries per second` +1. enter a valid `Duration` (a number followed by `s` for seconds (OR) `m` for minutes (OR) `h` for hour) +1. use the host IP address in the request Tab and in the advanced options, type in the header as `Host:` + +Click on `Run Test`. A performance test will run and statistical analysis performed. Examine the results of the test and behavior of the service mesh. + +Next, you will begin controlling requests to BookInfo using traffic management features. + +
+

Alternative: Manual installation

+Follow these steps if the above steps did not work +
+
+ +

Install Add-ons:

+
+ +**Prometheus** + +```sh +kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/addons/prometheus.yaml + +``` + +**Grafana** + +```sh +kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/addons/grafana.yaml + +``` + +**Jaeger** + +```sh +kubectl apply -f https://raw.githubusercontent.com/istio/istio/release-1.7/samples/addons/jaeger.yaml + +``` + +

Exposing services

+ +Istio add-on services are deployed by default as `ClusterIP` type services. We can expose the services outside the cluster by either changing the Kubernetes service type to `NodePort` or `LoadBalancer` or by port-forwarding or by configuring Kubernetes Ingress. + +**Option 1: Expose services with NodePort** +To expose them using NodePort service type, we can edit the services and change the service type from `ClusterIP` to `NodePort` + +**Option 2: Expose services with port-forwarding** +Port-forwarding runs in the foreground. We have appeneded `&` to the end of the above 2 commands to run them in the background. If you donot want this behavior, please remove the `&` from the end. + +

Prometheus

+ +You will need to expose the Prometheus service on a port either of the two following methods: + +**Option 1: Expose services with NodePort** + +```sh +kubectl -n istio-system edit svc prometheus +``` + +To find the assigned ports for Prometheus: + +```sh +kubectl -n istio-system get svc prometheus +``` + +**Option 2: Expose Prometheus service with port-forwarding:** +\*\* +Expose Prometheus service with port-forwarding: + +```sh +kubectl -n istio-system port-forward \ + $(kubectl -n istio-system get pod -l app=prometheus -o jsonpath='{.items[0].metadata.name}') \ + 9090:9090 & +``` + +Browse to `http://:` and in the `Expression` input box enter: `istio_request_bytes_count`. Click the Execute button. + +
+ + +
+
+

Grafana

+ +You will need to expose the Grafana service on a port either of the two following methods: + +```sh +kubectl -n istio-system edit svc grafana +``` + +Once this is done the services will be assigned dedicated ports on the hosts. + +To find the assigned ports for Grafana: + +```sh +kubectl -n istio-system get svc grafana +``` + +**Expose Grafana service with port-forwarding:** + +```sh +kubectl -n istio-system port-forward $(kubectl -n istio-system get pod -l app=grafana \ + -o jsonpath='{.items[0].metadata.name}') 3000:3000 & +``` + + + +
+
+

Distributed Tracing

+ +The sample Bookinfo application is configured to collect trace spans using Zipkin or Jaeger. Although Istio proxies are able to automatically send spans, it needs help from the application to tie together the entire trace. To do this applications need to propagate the appropriate HTTP headers so that when the proxies send span information to Zipkin or Jaeger, the spans can be correlated correctly into a single trace. + +To do this the application collects and propagates the following headers from the incoming request to any outgoing requests: + +- `x-request-id` +- `x-b3-traceid` +- `x-b3-spanid` +- `x-b3-parentspanid` +- `x-b3-sampled` +- `x-b3-flags` +- `x-ot-span-context` + +
+ + + + + +
+
+ +

Exposing services

+ +Istio add-on services are deployed by default as `ClusterIP` type services. We can expose the services outside the cluster by either changing the Kubernetes service type to `NodePort` or `LoadBalancer` or by port-forwarding or by configuring Kubernetes Ingress. In this lab, we will briefly demonstrate the `NodePort` and port-forwarding ways of exposing services. + +
Option 1: Expose services with NodePort
+ +To expose them using NodePort service type, we can edit the services and change the service type from `ClusterIP` to `NodePort` + +For Jaeger, either of `tracing` or `jaeger-query` can be exposed. + +```sh +kubectl -n istio-system edit svc tracing +``` + +Once this is done the services will be assigned dedicated ports on the hosts. + +To find the assigned ports for Jaeger: + +```sh +kubectl -n istio-system get svc tracing +``` + +
+ Option 2: Expose services with port-forwarding +
+ +To port-forward Jaeger: + +```sh +kubectl -n istio-system port-forward \ + $(kubectl -n istio-system get pod -l app=jaeger -o jsonpath='{.items[0].metadata.name}') \ + 16686:16686 & +``` + +

View Traces

+ +Let us find the port Jaeger is exposed on by running the following command: + +```sh +kubectl -n istio-system get svc tracing +``` + +You can click on the link at the top of the page which maps to the right port and it will open Jaeger UI in a new tab. + +
diff --git a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/routing-and-canary.mdx b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/routing-and-canary.mdx index 6330ca93a5fc..4a44d45742d9 100644 --- a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/routing-and-canary.mdx +++ b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/istio/routing-and-canary.mdx @@ -1,330 +1,330 @@ ---- -docType: "Chapter" -chapterTitle: "Request Routing and Canary Testing" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 5 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; - - -In this chapter, we are going to get our hands on some of the traffic management capabilities of Istio. - -
-
-

Apply default destination rules

-
- -Before we start playing with Istio's traffic management capabilities, we need to define the available versions of the deployed services. In Istio parlance, versions are called subsets. Subsets are defined in destination rules. - -Run the following in the custom yaml section to create default destination rules for the Bookinfo services: - -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: - name: productpage -spec: - host: productpage - subsets: - - name: v1 - labels: - version: v1 ---- - -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: -name: reviews -spec: -host: reviews -subsets: - name: v1 -labels: -version: v1 - name: v2 -labels: -version: v2 - name: v3 -labels: -version: v3 - ---- - -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: -name: ratings -spec: -host: ratings -subsets: - name: v1 -labels: -version: v1 - name: v2 -labels: -version: v2 - name: v2-mysql -labels: -version: v2-mysql - name: v2-mysql-vm -labels: -version: v2-mysql-vm - ---- - -apiVersion: networking.istio.io/v1alpha3 -kind: DestinationRule -metadata: -name: details -spec: -host: details -subsets: - name: v1 -labels: -version: v1 - name: v2 -labels: -version: v2 - ---- - -``` - -Using Meshery, navigate to the Istio management page: - -1. Enter `default` in the `Namespace` field. -1. Click the (+) icon on the `Apply Service Mesh Configuration` card and select `Bookinfo subsets` from the list. - -This will deploy the destination rules for all the Book info services defining their subsets. Verify the destination rules created by using the command below: - -```sh -kubectl get destinationrules - - -kubectl get destinationrules -o yaml -``` - -

- Configure the default route for all services to V1 -

-
- -As part of the bookinfo sample app, there are multiple versions of reviews service. When we load the `/productpage` in the browser multiple times we have seen the reviews service round robin between v1, v2 or v3. As the first exercise, let us first restrict traffic to just V1 of all the services. - -Using Meshery, navigate to the Istio management page: - -1. Enter `default` in the `Namespace` field. -2. Click the (+) icon on the `Apply Custom Configuration` card and paste the configuration below. - -To view the applied rule: - -```sh -kubectl get virtualservice -``` - -To take a look at a specific one: - -```sh -kubectl get virtualservice reviews -o yaml -``` - -_Please note:_ In the place of the above command, we can either use kubectl or istioctl. - -Config: - -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: reviews -spec: - hosts: - - reviews - http: - - route: - - destination: - host: reviews - subset: v1 ---- - -``` - -Now when we reload the `/productpage` several times, we will ONLY be viewing the data from v1 of all the services, which means we will not see any ratings (any stars). - -

Content-based routing

- -
-Let's replace our first rules with a new set. Enable the `ratings` service for a -user `jason` by routing `productpage` traffic to `reviews` v2: - -Using Meshery, navigate to the Istio management page: - -1. Enter `default` in the `Namespace` field. -2. Click the (+) icon on the `Apply Custom Configuration` card and paste the configuration below. - -This will update the existing virtual service definition for reviews to route all traffic for user `jason` to review V2. - -In a few, we should be able to verify the virtual service by using the command below: - -```sh -kubectl get virtualservice reviews -o yaml -``` - -Config: - -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: reviews -spec: - hosts: - - reviews - http: - - match: - - headers: - end-user: - exact: jason - route: - - destination: - host: reviews - subset: v2 - - route: - - destination: - host: reviews - subset: v1 ---- - -``` - -Now if we login as your `jason`, you will be able to see data from `reviews` v2. While if you NOT logged in or logged in as a different user, you will see data from `reviews` v1. - -

Canary Testing - Traffic Shifting

- -
-

Canary testing w/50% load

- -To start canary testing, let's begin by transferring 50% of the traffic from reviews:v1 to reviews:v3 with the following command: - -Using Meshery, navigate to the Istio management page: - -1. Enter `default` in the `Namespace` field. -2. Click the (+) icon on the `Apply Custom Configuration` card and paste the configuration below. - -This will update the existing virtual service definition for reviews to route 50% of all traffic to review V3. - -In a few, we should be able to verify the virtual service by using the command below: - -```sh -kubectl get virtualservice reviews -o yaml -``` - -Config: - -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: reviews -spec: - hosts: - - reviews - http: - - route: - - destination: - host: reviews - subset: v1 - weight: 50 - - destination: - host: reviews - subset: v3 - weight: 50 ---- - -``` - -Now, if we reload the `/productpage` in your browser several times, you should now see red-colored star ratings approximately 50% of the time. - -

Shift 100% to v3

- -When version v3 of the reviews microservice is considered stable, we can route 100% of the traffic to reviews:v3: - -Using Meshery, navigate to the Istio management page: - -1. Enter `default` in the `Namespace` field. -2. Click the (+) icon on the `Apply Custom Configuration` card and paste the configuration below. - -This will update the existing virtual service definition for reviews to route 100% of all traffic to review V3. - -In a few, we should be able to verify the virtual service by using the command below: - -```sh -kubectl get virtualservice reviews -o yaml -``` - -Config: - -```yaml -apiVersion: networking.istio.io/v1alpha3 -kind: VirtualService -metadata: - name: reviews -spec: - hosts: - - reviews - http: - - route: - - destination: - host: reviews - subset: v3 ---- - -``` - -Now, if we reload the `/productpage` in your browser several times, you should now see red-colored star ratings 100% of the time. - -
-

Alternative: Manual installation

-Follow these steps if the above steps did not work -
-
- -

Default destination rules

- -Run the following command to create default destination rules for the Bookinfo services: - -```sh -kubectl apply -f samples/bookinfo/networking/destination-rule-all-mtls.yaml -``` - -

- {" "} - Route all traffic to version V1 of all services -

- -```sh -kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml -``` - -

- {" "} - Route all traffic to version V2 of reviews for user Jason -

- -```sh -kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml -``` - -

- {" "} - Route 50% of traffic to version V3 of reviews service -

- -```sh -kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml -``` - -

- {" "} - Route 100% of traffic to version V3 of reviews service -

- -```sh -kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-v3.yaml -``` - -
+--- +docType: "Chapter" +chapterTitle: "Request Routing and Canary Testing" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 5 +--- + + + + +In this chapter, we are going to get our hands on some of the traffic management capabilities of Istio. + +
+
+

Apply default destination rules

+
+ +Before we start playing with Istio's traffic management capabilities, we need to define the available versions of the deployed services. In Istio parlance, versions are called subsets. Subsets are defined in destination rules. + +Run the following in the custom yaml section to create default destination rules for the Bookinfo services: + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: + name: productpage +spec: + host: productpage + subsets: + - name: v1 + labels: + version: v1 +--- + +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: +name: reviews +spec: +host: reviews +subsets: - name: v1 +labels: +version: v1 - name: v2 +labels: +version: v2 - name: v3 +labels: +version: v3 + +--- + +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: +name: ratings +spec: +host: ratings +subsets: - name: v1 +labels: +version: v1 - name: v2 +labels: +version: v2 - name: v2-mysql +labels: +version: v2-mysql - name: v2-mysql-vm +labels: +version: v2-mysql-vm + +--- + +apiVersion: networking.istio.io/v1alpha3 +kind: DestinationRule +metadata: +name: details +spec: +host: details +subsets: - name: v1 +labels: +version: v1 - name: v2 +labels: +version: v2 + +--- + +``` + +Using Meshery, navigate to the Istio management page: + +1. Enter `default` in the `Namespace` field. +1. Click the (+) icon on the `Apply Service Mesh Configuration` card and select `Bookinfo subsets` from the list. + +This will deploy the destination rules for all the Book info services defining their subsets. Verify the destination rules created by using the command below: + +```sh +kubectl get destinationrules + + +kubectl get destinationrules -o yaml +``` + +

+ Configure the default route for all services to V1 +

+
+ +As part of the bookinfo sample app, there are multiple versions of reviews service. When we load the `/productpage` in the browser multiple times we have seen the reviews service round robin between v1, v2 or v3. As the first exercise, let us first restrict traffic to just V1 of all the services. + +Using Meshery, navigate to the Istio management page: + +1. Enter `default` in the `Namespace` field. +2. Click the (+) icon on the `Apply Custom Configuration` card and paste the configuration below. + +To view the applied rule: + +```sh +kubectl get virtualservice +``` + +To take a look at a specific one: + +```sh +kubectl get virtualservice reviews -o yaml +``` + +_Please note:_ In the place of the above command, we can either use kubectl or istioctl. + +Config: + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: reviews +spec: + hosts: + - reviews + http: + - route: + - destination: + host: reviews + subset: v1 +--- + +``` + +Now when we reload the `/productpage` several times, we will ONLY be viewing the data from v1 of all the services, which means we will not see any ratings (any stars). + +

Content-based routing

+ +
+Let's replace our first rules with a new set. Enable the `ratings` service for a +user `jason` by routing `productpage` traffic to `reviews` v2: + +Using Meshery, navigate to the Istio management page: + +1. Enter `default` in the `Namespace` field. +2. Click the (+) icon on the `Apply Custom Configuration` card and paste the configuration below. + +This will update the existing virtual service definition for reviews to route all traffic for user `jason` to review V2. + +In a few, we should be able to verify the virtual service by using the command below: + +```sh +kubectl get virtualservice reviews -o yaml +``` + +Config: + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: reviews +spec: + hosts: + - reviews + http: + - match: + - headers: + end-user: + exact: jason + route: + - destination: + host: reviews + subset: v2 + - route: + - destination: + host: reviews + subset: v1 +--- + +``` + +Now if we login as your `jason`, you will be able to see data from `reviews` v2. While if you NOT logged in or logged in as a different user, you will see data from `reviews` v1. + +

Canary Testing - Traffic Shifting

+ +
+

Canary testing w/50% load

+ +To start canary testing, let's begin by transferring 50% of the traffic from reviews:v1 to reviews:v3 with the following command: + +Using Meshery, navigate to the Istio management page: + +1. Enter `default` in the `Namespace` field. +2. Click the (+) icon on the `Apply Custom Configuration` card and paste the configuration below. + +This will update the existing virtual service definition for reviews to route 50% of all traffic to review V3. + +In a few, we should be able to verify the virtual service by using the command below: + +```sh +kubectl get virtualservice reviews -o yaml +``` + +Config: + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: reviews +spec: + hosts: + - reviews + http: + - route: + - destination: + host: reviews + subset: v1 + weight: 50 + - destination: + host: reviews + subset: v3 + weight: 50 +--- + +``` + +Now, if we reload the `/productpage` in your browser several times, you should now see red-colored star ratings approximately 50% of the time. + +

Shift 100% to v3

+ +When version v3 of the reviews microservice is considered stable, we can route 100% of the traffic to reviews:v3: + +Using Meshery, navigate to the Istio management page: + +1. Enter `default` in the `Namespace` field. +2. Click the (+) icon on the `Apply Custom Configuration` card and paste the configuration below. + +This will update the existing virtual service definition for reviews to route 100% of all traffic to review V3. + +In a few, we should be able to verify the virtual service by using the command below: + +```sh +kubectl get virtualservice reviews -o yaml +``` + +Config: + +```yaml +apiVersion: networking.istio.io/v1alpha3 +kind: VirtualService +metadata: + name: reviews +spec: + hosts: + - reviews + http: + - route: + - destination: + host: reviews + subset: v3 +--- + +``` + +Now, if we reload the `/productpage` in your browser several times, you should now see red-colored star ratings 100% of the time. + +
+

Alternative: Manual installation

+Follow these steps if the above steps did not work +
+
+ +

Default destination rules

+ +Run the following command to create default destination rules for the Bookinfo services: + +```sh +kubectl apply -f samples/bookinfo/networking/destination-rule-all-mtls.yaml +``` + +

+ {" "} + Route all traffic to version V1 of all services +

+ +```sh +kubectl apply -f samples/bookinfo/networking/virtual-service-all-v1.yaml +``` + +

+ {" "} + Route all traffic to version V2 of reviews for user Jason +

+ +```sh +kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-test-v2.yaml +``` + +

+ {" "} + Route 50% of traffic to version V3 of reviews service +

+ +```sh +kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-50-v3.yaml +``` + +

+ {" "} + Route 100% of traffic to version V3 of reviews service +

+ +```sh +kubectl apply -f samples/bookinfo/networking/virtual-service-reviews-v3.yaml +``` + +
diff --git a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/conclusion.mdx b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/conclusion.mdx index f20c7d332b20..84af6d476d42 100644 --- a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/conclusion.mdx +++ b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/conclusion.mdx @@ -1,27 +1,27 @@ ---- -docType: "Chapter" -chapterTitle: "Conclusion" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 9 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; - - - -
- -

Congratulations!

- -
- You have successfully completed the course on{" "} - "Introduction to service meshes - Hands on" using{" "} - - Linkerd - - . -
- -
+--- +docType: "Chapter" +chapterTitle: "Conclusion" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 9 +--- + + + + + +
+ +

Congratulations!

+ +
+ You have successfully completed the course on{" "} + "Introduction to service meshes - Hands on" using{" "} + + Linkerd + + . +
+ +
diff --git a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/dashboard.mdx b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/dashboard.mdx index b678e8016966..772d0ec19592 100644 --- a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/dashboard.mdx +++ b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/dashboard.mdx @@ -1,109 +1,109 @@ ---- -docType: "Chapter" -chapterTitle: "Linkerd Dashboard" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 4 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; -import Top from "../../../../src/assets/images/learn-layer5/linkerd/top.webp"; -import Tap from "../../../../src/assets/images/learn-layer5/linkerd/tap.webp"; - - - -

Introduction to Linkerd Dashboard

- -The Dashboard provides a clickable user interface for administration of Linkerd. The Dashboard provides measurements of success rate, requests/second and latency for services on the mesh. Run the Linkerd Dashboard, by executing: - -```sh -linkerd dashboard & -``` - -This command port-forwards from your local system to the `linkerd-web` service. You can also expose the dashboard using Kubernetes `ingress`, which we will see later in this section. - -Since Linkerd's control plane components have the Linkerd proxy sidecarred, you can examine statistics of the traffic you are generating by looking at the dashboard. Execute: - -```sh -linkerd -n linkerd top deploy/linkerd-web -``` - -

Exposing the dashboard

- -Instead of using linkerd dashboard & every time you'd like to see what's going on, you can expose the dashboard via an ingress. We will use the Nginx ingress, which we had deployed and used in Lab 3. - -We will be applying Nginx ingress-traffic rule with basic authentication protocol - -```sh -apiVersion: v1 -kind: Secret -type: Opaque -metadata: - name: web-ingress-auth - namespace: linkerd -data: - auth: YWRtaW46JGFwcjEkbjdDdTZnSGwkRTQ3b2dmN0NPOE5SWWpFakJPa1dNLgoK ---- -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: web-ingress - namespace: linkerd - annotations: - kubernetes.io/ingress.class: "nginx" - nginx.ingress.kubernetes.io/upstream-vhost: $service_name.$namespace.svc.cluster.local:8084 - nginx.ingress.kubernetes.io/configuration-snippet: | - proxy_set_header Origin ""; - proxy_hide_header l5d-remote-ip; - proxy_hide_header l5d-server-id; - nginx.ingress.kubernetes.io/auth-type: basic - nginx.ingress.kubernetes.io/auth-secret: web-ingress-auth - nginx.ingress.kubernetes.io/auth-realm: "Authentication Required" -spec: - rules: - - host: dashboard.example.com - http: - paths: - - backend: - serviceName: linkerd-web - servicePort: 8084 -``` - -This exposes the dashboard at `dashboard.example.com` and protects it with basic auth with credentials admin,admin. - -From here you may need to modify your resolv.conf to add `dashboard.example.com` to localhost or use an alternative approach in order to see the dashboard deployment. We will not cover this in the workshop. - -

Tools exposed by dashboard

- -Linkerd dashboard exposes various CLI tools which may come handy while you debug your application running on mesh. - -Mainly there are three tools which Linkerd exposes as an extension to it's CLI commands - -**stat** - -This will show the “golden” metrics for each deployment: - -1. Success rates -1. Request rates -1. Latency distribution percentiles - -**top** - -To get a real-time view of which paths are being called. - -{" "} - - - - -**tap** - -Shows the stream of requests across a single pod, deployment, or even everything in the emojivoto namespace. - -{" "} - - - - -
+--- +docType: "Chapter" +chapterTitle: "Linkerd Dashboard" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 4 +--- + + +import Top from "../../../../src/assets/images/learn-layer5/linkerd/top.webp"; +import Tap from "../../../../src/assets/images/learn-layer5/linkerd/tap.webp"; + + + +

Introduction to Linkerd Dashboard

+ +The Dashboard provides a clickable user interface for administration of Linkerd. The Dashboard provides measurements of success rate, requests/second and latency for services on the mesh. Run the Linkerd Dashboard, by executing: + +```sh +linkerd dashboard & +``` + +This command port-forwards from your local system to the `linkerd-web` service. You can also expose the dashboard using Kubernetes `ingress`, which we will see later in this section. + +Since Linkerd's control plane components have the Linkerd proxy sidecarred, you can examine statistics of the traffic you are generating by looking at the dashboard. Execute: + +```sh +linkerd -n linkerd top deploy/linkerd-web +``` + +

Exposing the dashboard

+ +Instead of using linkerd dashboard & every time you'd like to see what's going on, you can expose the dashboard via an ingress. We will use the Nginx ingress, which we had deployed and used in Lab 3. + +We will be applying Nginx ingress-traffic rule with basic authentication protocol + +```sh +apiVersion: v1 +kind: Secret +type: Opaque +metadata: + name: web-ingress-auth + namespace: linkerd +data: + auth: YWRtaW46JGFwcjEkbjdDdTZnSGwkRTQ3b2dmN0NPOE5SWWpFakJPa1dNLgoK +--- +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: web-ingress + namespace: linkerd + annotations: + kubernetes.io/ingress.class: "nginx" + nginx.ingress.kubernetes.io/upstream-vhost: $service_name.$namespace.svc.cluster.local:8084 + nginx.ingress.kubernetes.io/configuration-snippet: | + proxy_set_header Origin ""; + proxy_hide_header l5d-remote-ip; + proxy_hide_header l5d-server-id; + nginx.ingress.kubernetes.io/auth-type: basic + nginx.ingress.kubernetes.io/auth-secret: web-ingress-auth + nginx.ingress.kubernetes.io/auth-realm: "Authentication Required" +spec: + rules: + - host: dashboard.example.com + http: + paths: + - backend: + serviceName: linkerd-web + servicePort: 8084 +``` + +This exposes the dashboard at `dashboard.example.com` and protects it with basic auth with credentials admin,admin. + +From here you may need to modify your resolv.conf to add `dashboard.example.com` to localhost or use an alternative approach in order to see the dashboard deployment. We will not cover this in the workshop. + +

Tools exposed by dashboard

+ +Linkerd dashboard exposes various CLI tools which may come handy while you debug your application running on mesh. + +Mainly there are three tools which Linkerd exposes as an extension to it's CLI commands + +**stat** + +This will show the “golden” metrics for each deployment: + +1. Success rates +1. Request rates +1. Latency distribution percentiles + +**top** + +To get a real-time view of which paths are being called. + +{" "} + + + + +**tap** + +Shows the stream of requests across a single pod, deployment, or even everything in the emojivoto namespace. + +{" "} + + + + +
diff --git a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/debugging.mdx b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/debugging.mdx index 66c92495e4ef..fd6546c7d3b4 100644 --- a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/debugging.mdx +++ b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/debugging.mdx @@ -1,61 +1,61 @@ ---- -docType: "Chapter" -chapterTitle: "Debugging (Optional)" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 5 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; -import Octopus from "../../../../src/assets/images/learn-layer5/linkerd/octopus.webp"; -import WebTop from "../../../../src/assets/images/learn-layer5/linkerd/webtop.webp"; -import WebTap from "../../../../src/assets/images/learn-layer5/linkerd/webtap.webp"; - - - -

Debugging application using Linkerd

- -We will be using Linkerd to debug the sample application, we had deployed earlier in the workshop. The demo application emojivoto has some issues. Let's use that and Linkerd to diagnose an application that fails in ways which are a little more subtle than the entire service crashing. - -Let's jump into debugging the Emojivoto application right away. - -
- -

Exploring the Linkerd Dashboard

- -In the event that you look at the Linkerd dashboard (by running the `linkerd dashboard` command), you should see all the resources in the emojivoto namespace, including the deployments. Every deployments running Linkerd shows success rate, requests per second and latency percentiles. If you see closely, you will observe success rate is below 100% because of some buggy endpoint present in the service. - - - - - -The first thing you'll see here is that the web deployment is taking traffic from vote-bot (a deployment included with emojivoto to continually generate a low level of live traffic). The web deployment also has two outgoing dependencies, emoji and voting. - -While the emoji deployment is handling every request from web successfully, it looks like the voting deployment is failing some requests! A failure in a dependent deployment may be exactly what is causing the errors that web is returning. - -

Debugging the application

- -Scrolling down a little from the deployment page, we'll see a live list of all traffic that is incoming to and outgoing from web. - - - - - -There are two calls that are not at 100%: the first is vote-bot's call to the '/api/vote' endpoint. The second is the 'VoteDoughnut' call from the web organization to its needy arrangement, casting a ballot. - -Since '/api/vote' is an approaching call, and 'VoteDoughnut' is an active call, this is a decent sign that this endpoint is what's causing the issue! - -To burrow somewhat more profound, we can click on the `tap` symbol in the extreme right section. This will take us to the live rundown of requests that match just this endpoint. You'll see 'Unknown under the GRPC status section'. - - - - - -This is because the requests are failing with a [gRPC status code 2](https://pkg.go.dev/google.golang.org/grpc/codes#Code), which is a common error response. - -_Note: Linkerd is aware of gRPC's response classification without any other configuration._ - -Now at this point we have all the necessary debugging information which can help us to restore the application to stable/working state. - -
+--- +docType: "Chapter" +chapterTitle: "Debugging (Optional)" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 5 +--- + + +import Octopus from "../../../../src/assets/images/learn-layer5/linkerd/octopus.webp"; +import WebTop from "../../../../src/assets/images/learn-layer5/linkerd/webtop.webp"; +import WebTap from "../../../../src/assets/images/learn-layer5/linkerd/webtap.webp"; + + + +

Debugging application using Linkerd

+ +We will be using Linkerd to debug the sample application, we had deployed earlier in the workshop. The demo application emojivoto has some issues. Let's use that and Linkerd to diagnose an application that fails in ways which are a little more subtle than the entire service crashing. + +Let's jump into debugging the Emojivoto application right away. + +
+ +

Exploring the Linkerd Dashboard

+ +In the event that you look at the Linkerd dashboard (by running the `linkerd dashboard` command), you should see all the resources in the emojivoto namespace, including the deployments. Every deployments running Linkerd shows success rate, requests per second and latency percentiles. If you see closely, you will observe success rate is below 100% because of some buggy endpoint present in the service. + + + + + +The first thing you'll see here is that the web deployment is taking traffic from vote-bot (a deployment included with emojivoto to continually generate a low level of live traffic). The web deployment also has two outgoing dependencies, emoji and voting. + +While the emoji deployment is handling every request from web successfully, it looks like the voting deployment is failing some requests! A failure in a dependent deployment may be exactly what is causing the errors that web is returning. + +

Debugging the application

+ +Scrolling down a little from the deployment page, we'll see a live list of all traffic that is incoming to and outgoing from web. + + + + + +There are two calls that are not at 100%: the first is vote-bot's call to the '/api/vote' endpoint. The second is the 'VoteDoughnut' call from the web organization to its needy arrangement, casting a ballot. + +Since '/api/vote' is an approaching call, and 'VoteDoughnut' is an active call, this is a decent sign that this endpoint is what's causing the issue! + +To burrow somewhat more profound, we can click on the `tap` symbol in the extreme right section. This will take us to the live rundown of requests that match just this endpoint. You'll see 'Unknown under the GRPC status section'. + + + + + +This is because the requests are failing with a [gRPC status code 2](https://pkg.go.dev/google.golang.org/grpc/codes#Code), which is a common error response. + +_Note: Linkerd is aware of gRPC's response classification without any other configuration._ + +Now at this point we have all the necessary debugging information which can help us to restore the application to stable/working state. + +
diff --git a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/deploy-an-application.mdx b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/deploy-an-application.mdx index 88584098cffb..7aa64b843ce2 100644 --- a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/deploy-an-application.mdx +++ b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/deploy-an-application.mdx @@ -1,197 +1,197 @@ ---- -docType: "Chapter" -chapterTitle: "Deploy a sample application" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 2 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; - - - -To play with Linkerd and demonstrate some of it's capabilities, you will deploy the sample application, EmojiVoto. - -

What is the EmojiVoto Application

-
- -Emojivoto is a sample microservice application that allows users to vote for their favorite emoji. -It displays votes received on a leaderboard. Emojivoto has no dependencies on Linkerd, but will run -fine either on or off the service mesh. - -A sidecar injector is used for automating the injection of the Linkerd proxy into your application's pod spec. The Kubernetes admission controller enforces this behavior send -sending a webhook request the the sidecar injector every time a pod is to be scheduled. This injector inspects resources for a Linkerd-specific annotation (linkerd.io/inject: enabled). -When that annotation exists, the injector mutates the pod's specification and adds both an init container as well as a sidecar containing the proxy itself. - -The Linkerd sidecar proxy can be either manually or automatically injected into your application's pods. This can be done from the meshery dashboard for namespace globally by, - -1. Using Meshery, navigate to the Linkerd management page. -1. Click the (+) icon on the `Configure Application` card and select `Annotate Namespace` from the list. - -As part of Linkerd deployment in [Previous chapter](./getting-started), you have deployed the sidecar injector. -To verify, execute this command: - -```sh -kubectl get deployment linkerd-proxy-injector -n linkerd -``` - -Output: - -```sh -NAME READY UP-TO-DATE AVAILABLE AGE -linkerd-proxy-injector 1/1 1 1 9m49s -``` - -Examine the annotation added to the `linkerd` namespace: - -```sh -kubectl describe namespace linkerd -``` - -Output: - -```sh -Name: linkerd -Labels: config.linkerd.io/admission-webhooks=disabled - linkerd.io/control-plane-ns=linkerd - linkerd.io/is-control-plane=true -Annotations: linkerd.io/inject: disabled -Status: Active - -No resource quota. - -No LimitRange resource. -``` - -

Deploy the application

- -Using Meshery, navigate to the Linkerd management page. - -1. Enter `default` in the `Namespace` field. -1. Click the (+) icon on the `Sample Application` card and select `Emojivoto Application` from the list. - -This will do 3 things: - -1. Label the `emojivoto` namespace for sidecar injection. -1. Deploys all the Emojivoto services and replica's in the `emojivoto` namespace. - -
-

Alternative: Manual installation

-Follow this if the above steps did not work for you -
-
- -

Deploy emojivoto application

- -Install emojivoto into the emojivoto namespace by running: - -```sh -curl -sL https://run.linkerd.io/emojivoto.yml \ - | kubectl apply -f - -``` - -Before we mesh it, let's take a look at the app. -If you're using Docker Desktop at this point you can visit http://localhost directly. -If you're not using Docker Desktop, we'll need to forward the web-svc service. -To forward web-svc locally to port 8080, you can run: - -```sh -kubectl -n emojivoto port-forward svc/web-svc 8080:80 -``` - -

- Verify EmojiVoto deployment{" "} -

- -1. Verify that the deployments are all in a state of AVAILABLE before continuing. - - ```sh - watch kubectl get deployment -n emojivoto - ``` - -2. Inspect the details of the pods - - Examine details of the pods: - - ```sh - watch kubectl get po -n emojivoto - ``` - - Examine details of the services: - - ```sh - watch kubectl get svc -n emojivoto - ``` - - Choose one of EmojiVoto's services (e.g. `web-svc`), and view it's sidecar configuration: - - ```sh - kubectl get svc -n emojivoto - - kubectl describe service svc/web-svc -n emojivoto - ``` - -Let's look at the application deployment by port-forwarding the `web-svc` service: - -```sh -kubectl port-forward svc/web-svc 8080:80 -n emojivoto -``` - -You have onboarded emojivoto to the service mesh. Verify your data plane environment with this check: - -```sh -linkerd -n emojivoto check --proxy -``` - -Linkerd, in contrast to Istio annotates the resources (namespaces, deployment workloads) rather than labelling them. - -

Deploy EmojiVoto

- -Applying this yaml file included in the Linkerd package you collected in https://run.linkerd.io/emojivoto.yml -will deploy the sample app into your cluster. - -```sh -kubectl apply -f https://run.linkerd.io/emojivoto.yml -``` - -

- Inject Linkerd proxy into the sample application -

- -The emojivoto application is a standalone Kubernetes application that uses a mix of gRPC and -HTTP calls to allow the users to vote on their favorite emojis, which means the -application can run standalone without support from linkerd service mesh. Now we will -be injecting linkerd into our sample application - -```sh -kubectl get -n emojivoto deploy -o yaml \ - | linkerd inject - \ - | kubectl apply -f - -``` - -Or... - -```sh -kubectl -n emojivoto patch -f https://run.linkerd.io/emojivoto.yml -p ' -spec: - template: - metadata: - annotations: - linkerd.io/inject: enabled -' -``` - -Either of these commands retrieve all of the deployments running in the emojivoto namespace, runs the manifest -through linkerd inject, and then reapplies it to the cluster. The linkerd inject command adds annotations to the pod spec -instructing Linkerd to add (“inject”) the proxy as a container to the pod spec. - -You've now added Linkerd to existing services! Just as with the control plane, it -is possible to verify that everything worked the way it should with the data plane. -To do this check, run: - -```sh -linkerd -n emojivoto check --proxy -``` - -
+--- +docType: "Chapter" +chapterTitle: "Deploy a sample application" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 2 +--- + + + + + +To play with Linkerd and demonstrate some of it's capabilities, you will deploy the sample application, EmojiVoto. + +

What is the EmojiVoto Application

+
+ +Emojivoto is a sample microservice application that allows users to vote for their favorite emoji. +It displays votes received on a leaderboard. Emojivoto has no dependencies on Linkerd, but will run +fine either on or off the service mesh. + +A sidecar injector is used for automating the injection of the Linkerd proxy into your application's pod spec. The Kubernetes admission controller enforces this behavior send +sending a webhook request the the sidecar injector every time a pod is to be scheduled. This injector inspects resources for a Linkerd-specific annotation (linkerd.io/inject: enabled). +When that annotation exists, the injector mutates the pod's specification and adds both an init container as well as a sidecar containing the proxy itself. + +The Linkerd sidecar proxy can be either manually or automatically injected into your application's pods. This can be done from the meshery dashboard for namespace globally by, + +1. Using Meshery, navigate to the Linkerd management page. +1. Click the (+) icon on the `Configure Application` card and select `Annotate Namespace` from the list. + +As part of Linkerd deployment in [Previous chapter](./getting-started), you have deployed the sidecar injector. +To verify, execute this command: + +```sh +kubectl get deployment linkerd-proxy-injector -n linkerd +``` + +Output: + +```sh +NAME READY UP-TO-DATE AVAILABLE AGE +linkerd-proxy-injector 1/1 1 1 9m49s +``` + +Examine the annotation added to the `linkerd` namespace: + +```sh +kubectl describe namespace linkerd +``` + +Output: + +```sh +Name: linkerd +Labels: config.linkerd.io/admission-webhooks=disabled + linkerd.io/control-plane-ns=linkerd + linkerd.io/is-control-plane=true +Annotations: linkerd.io/inject: disabled +Status: Active + +No resource quota. + +No LimitRange resource. +``` + +

Deploy the application

+ +Using Meshery, navigate to the Linkerd management page. + +1. Enter `default` in the `Namespace` field. +1. Click the (+) icon on the `Sample Application` card and select `Emojivoto Application` from the list. + +This will do 3 things: + +1. Label the `emojivoto` namespace for sidecar injection. +1. Deploys all the Emojivoto services and replica's in the `emojivoto` namespace. + +
+

Alternative: Manual installation

+Follow this if the above steps did not work for you +
+
+ +

Deploy emojivoto application

+ +Install emojivoto into the emojivoto namespace by running: + +```sh +curl -sL https://run.linkerd.io/emojivoto.yml \ + | kubectl apply -f - +``` + +Before we mesh it, let's take a look at the app. +If you're using Docker Desktop at this point you can visit http://localhost directly. +If you're not using Docker Desktop, we'll need to forward the web-svc service. +To forward web-svc locally to port 8080, you can run: + +```sh +kubectl -n emojivoto port-forward svc/web-svc 8080:80 +``` + +

+ Verify EmojiVoto deployment{" "} +

+ +1. Verify that the deployments are all in a state of AVAILABLE before continuing. + + ```sh + watch kubectl get deployment -n emojivoto + ``` + +2. Inspect the details of the pods + + Examine details of the pods: + + ```sh + watch kubectl get po -n emojivoto + ``` + + Examine details of the services: + + ```sh + watch kubectl get svc -n emojivoto + ``` + + Choose one of EmojiVoto's services (e.g. `web-svc`), and view it's sidecar configuration: + + ```sh + kubectl get svc -n emojivoto + + kubectl describe service svc/web-svc -n emojivoto + ``` + +Let's look at the application deployment by port-forwarding the `web-svc` service: + +```sh +kubectl port-forward svc/web-svc 8080:80 -n emojivoto +``` + +You have onboarded emojivoto to the service mesh. Verify your data plane environment with this check: + +```sh +linkerd -n emojivoto check --proxy +``` + +Linkerd, in contrast to Istio annotates the resources (namespaces, deployment workloads) rather than labelling them. + +

Deploy EmojiVoto

+ +Applying this yaml file included in the Linkerd package you collected in https://run.linkerd.io/emojivoto.yml +will deploy the sample app into your cluster. + +```sh +kubectl apply -f https://run.linkerd.io/emojivoto.yml +``` + +

+ Inject Linkerd proxy into the sample application +

+ +The emojivoto application is a standalone Kubernetes application that uses a mix of gRPC and +HTTP calls to allow the users to vote on their favorite emojis, which means the +application can run standalone without support from linkerd service mesh. Now we will +be injecting linkerd into our sample application + +```sh +kubectl get -n emojivoto deploy -o yaml \ + | linkerd inject - \ + | kubectl apply -f - +``` + +Or... + +```sh +kubectl -n emojivoto patch -f https://run.linkerd.io/emojivoto.yml -p ' +spec: + template: + metadata: + annotations: + linkerd.io/inject: enabled +' +``` + +Either of these commands retrieve all of the deployments running in the emojivoto namespace, runs the manifest +through linkerd inject, and then reapplies it to the cluster. The linkerd inject command adds annotations to the pod spec +instructing Linkerd to add (“inject”) the proxy as a container to the pod spec. + +You've now added Linkerd to existing services! Just as with the control plane, it +is possible to verify that everything worked the way it should with the data plane. +To do this check, run: + +```sh +linkerd -n emojivoto check --proxy +``` + +
diff --git a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/expose-services.mdx b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/expose-services.mdx index 3518a4a02e4a..b03845d5d500 100644 --- a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/expose-services.mdx +++ b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/expose-services.mdx @@ -1,119 +1,119 @@ ---- -docType: "Chapter" -chapterTitle: "Exposing services through Linkerd Ingress" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 3 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; - - - -

Ingressing and Egressing with Linkerd

- -Linkerd's control plane does not include ingress or egress gateways. Linkerd allows you choice of your preferred ingress (and egress) controller. - -

How to use Ingress with Linkerd

- -In case you're anticipating infusing Linkerd into your ingress controller's pods there is some setup required. Linkerd discovers -services dependent on the `:authority` or `Host` header. This permits Linkerd to comprehend what service a request is bound for without -being subject to DNS or IPs. - -In this workshop, you will use the NGINX Ingress Controller with Linkerd. - -

Installing NGINX Ingress Controller

- -Using Meshery, select the Linkerd from the Management menu, and: - -1. Enter ingress-nginx into the namespace field. -1. Click the (+) icon on the Apply Service Mesh Configuration card and select NGINX Ingress Controller to install the latest version of KIC. - -

Alternative: Manual installation

-Follow this if the above steps did not work for you - -
-
- -

Installing NGINX Ingress Controller

- -Install ingress controller using Docker Desktop - -```sh -kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.40.2/deploy/static/provider/cloud/deploy.yaml -``` - -Install the ingress controller using Minikube - -```sh -minikube addons enable ingress -``` - -

- {" "} - Setting up Ingress controller with the sample application deployed -

- -Using Meshery, click the ➡️ icon on the `Apply Custom Configuration` card and apply the following manifest to your cluster: - -```sh -apiVersion: extensions/v1beta1 -kind: Ingress -metadata: - name: web-ingress - namespace: emojivoto - annotations: - kubernetes.io/ingress.class: "nginx" - nginx.ingress.kubernetes.io/configuration-snippet: | - proxy_set_header l5d-dst-override $service_name.$namespace.svc.cluster.local:$service_port; - grpc_set_header l5d-dst-override $service_name.$namespace.svc.cluster.local:$service_port; - -spec: - rules: - - host: example.com - http: - paths: - - backend: - serviceName: web-svc - servicePort: 80 -``` - -Nginx ingress will include the `l5d-dst-override` header to tell Linkerd where to direct the request. -You'll need to include both the Kubernetes administration FQDN (web-svc.emojivoto.svc.cluster.local) and the destination servicePort. - -To test this, you need to get the external IP of your controller. - -

Docker Desktop

- -You may use http://localhost or http://kubernetes.docker.internal or your host's IP address. - -

Minikube

- -Expose your Kubernetes's cluster services to your localhost network: - -```sh -minikube tunnel -``` - -You may use http://localhost or You may use http://localhost: provided by the output of `minikube tunnel`. - -

Hosted Kubernetes

- -Retrieve the external IP address by running: - -```sh -kubectl get svc --all-namespaces \ - -l app=nginx-ingress,component=controller \ - -o=custom-columns=EXTERNAL-IP:.status.loadBalancer.ingress[0].ip -``` - -You can now curl to your service without using port-forward, like this: - -```sh -curl -H "Host: example.com" http://{external-ip} -``` - -
- -
+--- +docType: "Chapter" +chapterTitle: "Exposing services through Linkerd Ingress" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 3 +--- + + + + + +

Ingressing and Egressing with Linkerd

+ +Linkerd's control plane does not include ingress or egress gateways. Linkerd allows you choice of your preferred ingress (and egress) controller. + +

How to use Ingress with Linkerd

+ +In case you're anticipating infusing Linkerd into your ingress controller's pods there is some setup required. Linkerd discovers +services dependent on the `:authority` or `Host` header. This permits Linkerd to comprehend what service a request is bound for without +being subject to DNS or IPs. + +In this workshop, you will use the NGINX Ingress Controller with Linkerd. + +

Installing NGINX Ingress Controller

+ +Using Meshery, select the Linkerd from the Management menu, and: + +1. Enter ingress-nginx into the namespace field. +1. Click the (+) icon on the Apply Service Mesh Configuration card and select NGINX Ingress Controller to install the latest version of KIC. + +

Alternative: Manual installation

+Follow this if the above steps did not work for you + +
+
+ +

Installing NGINX Ingress Controller

+ +Install ingress controller using Docker Desktop + +```sh +kubectl apply -f https://raw.githubusercontent.com/kubernetes/ingress-nginx/controller-v0.40.2/deploy/static/provider/cloud/deploy.yaml +``` + +Install the ingress controller using Minikube + +```sh +minikube addons enable ingress +``` + +

+ {" "} + Setting up Ingress controller with the sample application deployed +

+ +Using Meshery, click the ➡️ icon on the `Apply Custom Configuration` card and apply the following manifest to your cluster: + +```sh +apiVersion: extensions/v1beta1 +kind: Ingress +metadata: + name: web-ingress + namespace: emojivoto + annotations: + kubernetes.io/ingress.class: "nginx" + nginx.ingress.kubernetes.io/configuration-snippet: | + proxy_set_header l5d-dst-override $service_name.$namespace.svc.cluster.local:$service_port; + grpc_set_header l5d-dst-override $service_name.$namespace.svc.cluster.local:$service_port; + +spec: + rules: + - host: example.com + http: + paths: + - backend: + serviceName: web-svc + servicePort: 80 +``` + +Nginx ingress will include the `l5d-dst-override` header to tell Linkerd where to direct the request. +You'll need to include both the Kubernetes administration FQDN (web-svc.emojivoto.svc.cluster.local) and the destination servicePort. + +To test this, you need to get the external IP of your controller. + +

Docker Desktop

+ +You may use http://localhost or http://kubernetes.docker.internal or your host's IP address. + +

Minikube

+ +Expose your Kubernetes's cluster services to your localhost network: + +```sh +minikube tunnel +``` + +You may use http://localhost or You may use http://localhost: provided by the output of `minikube tunnel`. + +

Hosted Kubernetes

+ +Retrieve the external IP address by running: + +```sh +kubectl get svc --all-namespaces \ + -l app=nginx-ingress,component=controller \ + -o=custom-columns=EXTERNAL-IP:.status.loadBalancer.ingress[0].ip +``` + +You can now curl to your service without using port-forward, like this: + +```sh +curl -H "Host: example.com" http://{external-ip} +``` + +
+ +
diff --git a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/fault-injection.mdx b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/fault-injection.mdx index 6ab8241d6bf9..240c0b20558e 100644 --- a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/fault-injection.mdx +++ b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/fault-injection.mdx @@ -1,175 +1,175 @@ ---- -docType: "Chapter" -chapterTitle: "Fault Injection" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 8 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; - - - -

Fault Injection using SMI in Linkerd

- -Application failure injection is a form of chaos engineering where we artificially increase the error rate of certain services in a microservice application to see what impact that has on the system as a whole. Traditionally, you would need to add some kind of failure injection library into your service code in order to do application failure injection. Thankfully, the service mesh gives us a way to inject application failures without needing to modify or rebuild our services at all. - -

- Using SMI Traffic Split API to inject errors -

- -We can easily inject application failures by using the Traffic Split API of the Service Mesh Interface. This allows us to do failure injection in a way that is implementation agnostic and works across service meshes. - -We will do this first by deploying a new service which only return errored responses. We will be using a simple NGINX service which has configured to only return HTTP 500 responses. - -We will then create a traffic split which would redirect the service mesh to send a sample percentage of traffic to the error service instead, let's say 20% of service's traffic to error, then we would have injected an artificial 20% error rate in service. - -

Deploy Linkerd Books Application

- -We will be deploying [Linkerd Books application](https://github.com/BuoyantIO/booksapp) for this part of the demo - -Use meshery to deploy the bookinfo application : - -- In Meshery, navigate to the Linkerd adapter's management page from the left nav menu. -- On the Linkerd adapter's management page, please enter `default` in the `Namespace` field. -- Then, click the (+) icon on the `Sample Application` card and select `Books Application` from the list. - -Inject linkerd into sample application using - -```sh -linkerd inject https://run.linkerd.io/booksapp.yml | kubectl apply -f - -``` - -In the following, one of the service has already beeen configured with the error let's remove the error rate from the same : - -```sh -kubectl edit deploy/authors -``` - -Remove the lines - -```sh -- name: FAILURE_RATE - value: "0.5 -``` - -Now if you will see `linkerd stat`, the success rate would be 100% - -```sh -linkerd stat deploy -``` - -

Create the errored service

- -Now we will create our error service, we have NGINX pre-configured to only respond with HTTP 500 status code - -```sh -apiVersion: apps/v1 -kind: Deployment -metadata: - name: error-injector - labels: - app: error-injector -spec: - selector: - matchLabels: - app: error-injector - replicas: 1 - template: - metadata: - labels: - app: error-injector - spec: - containers: - - name: nginx - image: nginx:alpine - ports: - - containerPort: 80 - name: nginx - protocol: TCP - volumeMounts: - - name: nginx-config - mountPath: /etc/nginx/nginx.conf - subPath: nginx.conf - volumes: - - name: nginx-config - configMap: - name: error-injector-config ---- -apiVersion: v1 -kind: Service -metadata: - labels: - app: error-injector - name: error-injector -spec: - clusterIP: None - ports: - - name: service - port: 7002 - protocol: TCP - targetPort: nginx - selector: - app: error-injector - type: ClusterIP ---- -apiVersion: v1 -data: - nginx.conf: |2 - - events { - worker_connections 1024; - } - - http { - server { - location / { - return 500; - } - } - } -kind: ConfigMap -metadata: - name: error-injector-config -``` - -After deploying the above errored service, we will create a traffic split resource which will be responsible to direct 20% of the book service to the error. - -```sh -apiVersion: split.smi-spec.io/v1alpha3 -kind: TrafficSplit -metadata: - name: fault-inject -spec: - service: books - backends: - - service: books - weight: 800m - - service: error-injector - weight: 200m -``` - -You can now see an 20% error rate for calls from webapp to books - -```sh -linkerd routes deploy/webapp --to service/books -``` - -You can also see the error on the web browser - -```sh -kubectl port-forward deploy/webapp 7000 && open http://localhost:7000 -``` - -If you refresh page few times, you will see `Internal Server Error`. - -

Cleanup

- -```sh -kubectl delete trafficsplit/error-split -``` - -- Remove the book info application from the `Meshery Dashboard` by clicking on the `trash icon` in the `sample application` card on the linkerd adapters' page. - -
+--- +docType: "Chapter" +chapterTitle: "Fault Injection" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 8 +--- + + + + + +

Fault Injection using SMI in Linkerd

+ +Application failure injection is a form of chaos engineering where we artificially increase the error rate of certain services in a microservice application to see what impact that has on the system as a whole. Traditionally, you would need to add some kind of failure injection library into your service code in order to do application failure injection. Thankfully, the service mesh gives us a way to inject application failures without needing to modify or rebuild our services at all. + +

+ Using SMI Traffic Split API to inject errors +

+ +We can easily inject application failures by using the Traffic Split API of the Service Mesh Interface. This allows us to do failure injection in a way that is implementation agnostic and works across service meshes. + +We will do this first by deploying a new service which only return errored responses. We will be using a simple NGINX service which has configured to only return HTTP 500 responses. + +We will then create a traffic split which would redirect the service mesh to send a sample percentage of traffic to the error service instead, let's say 20% of service's traffic to error, then we would have injected an artificial 20% error rate in service. + +

Deploy Linkerd Books Application

+ +We will be deploying [Linkerd Books application](https://github.com/BuoyantIO/booksapp) for this part of the demo + +Use meshery to deploy the bookinfo application : + +- In Meshery, navigate to the Linkerd adapter's management page from the left nav menu. +- On the Linkerd adapter's management page, please enter `default` in the `Namespace` field. +- Then, click the (+) icon on the `Sample Application` card and select `Books Application` from the list. + +Inject linkerd into sample application using + +```sh +linkerd inject https://run.linkerd.io/booksapp.yml | kubectl apply -f - +``` + +In the following, one of the service has already beeen configured with the error let's remove the error rate from the same : + +```sh +kubectl edit deploy/authors +``` + +Remove the lines + +```sh +- name: FAILURE_RATE + value: "0.5 +``` + +Now if you will see `linkerd stat`, the success rate would be 100% + +```sh +linkerd stat deploy +``` + +

Create the errored service

+ +Now we will create our error service, we have NGINX pre-configured to only respond with HTTP 500 status code + +```sh +apiVersion: apps/v1 +kind: Deployment +metadata: + name: error-injector + labels: + app: error-injector +spec: + selector: + matchLabels: + app: error-injector + replicas: 1 + template: + metadata: + labels: + app: error-injector + spec: + containers: + - name: nginx + image: nginx:alpine + ports: + - containerPort: 80 + name: nginx + protocol: TCP + volumeMounts: + - name: nginx-config + mountPath: /etc/nginx/nginx.conf + subPath: nginx.conf + volumes: + - name: nginx-config + configMap: + name: error-injector-config +--- +apiVersion: v1 +kind: Service +metadata: + labels: + app: error-injector + name: error-injector +spec: + clusterIP: None + ports: + - name: service + port: 7002 + protocol: TCP + targetPort: nginx + selector: + app: error-injector + type: ClusterIP +--- +apiVersion: v1 +data: + nginx.conf: |2 + + events { + worker_connections 1024; + } + + http { + server { + location / { + return 500; + } + } + } +kind: ConfigMap +metadata: + name: error-injector-config +``` + +After deploying the above errored service, we will create a traffic split resource which will be responsible to direct 20% of the book service to the error. + +```sh +apiVersion: split.smi-spec.io/v1alpha3 +kind: TrafficSplit +metadata: + name: fault-inject +spec: + service: books + backends: + - service: books + weight: 800m + - service: error-injector + weight: 200m +``` + +You can now see an 20% error rate for calls from webapp to books + +```sh +linkerd routes deploy/webapp --to service/books +``` + +You can also see the error on the web browser + +```sh +kubectl port-forward deploy/webapp 7000 && open http://localhost:7000 +``` + +If you refresh page few times, you will see `Internal Server Error`. + +

Cleanup

+ +```sh +kubectl delete trafficsplit/error-split +``` + +- Remove the book info application from the `Meshery Dashboard` by clicking on the `trash icon` in the `sample application` card on the linkerd adapters' page. + +
diff --git a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/getting-started.mdx b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/getting-started.mdx index 4082120358c4..0f7b3a1f8059 100644 --- a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/getting-started.mdx +++ b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/getting-started.mdx @@ -1,117 +1,118 @@ ---- -doctype: "Chapter" -chapterTitle: "Getting Started" -description: "Meshery, collaborative Kubernetes manager" -videos: 6 -lectures: 8 -order: 1 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; -import LinkerdAdapter from "../../../../src/assets/images/learn-layer5/linkerd/linkerd-adapter.webp"; -import InstallLinkerd from "../../../../src/assets/images/learn-layer5/linkerd/install-linkerd.webp"; - - - -

Setup Linkerd

- -Now that we have a Kubernetes cluster and Meshery, we are ready to download and deploy Linkerd resources. - -

Steps

- -1. [Install Linkerd](#1) -1. [Verify install](#2) -1. [Confirm add-ons](#3) - -

- Install Linkerd -

- -Using Meshery, select `Linkerd` from the `Management` menu. - - - - - -In the Linkerd management page: - -1. Type `linkerd` into the namespace field. -1. Click the (+) icon on the `Install` card and select `Latest Linkerd` to install the latest version of Linkerd. - - - - {" "} - -

Alternative: Manual Installation

- -Perform the below steps if the above steps doesn't work for you. - -

Download `linkerd` CLI

- -On a \*nix system, you can setup linkerd by doing the following: - -The above command will get the latest Linkerd package and untar it in the same folder. - -Change into the Linkerd package directory and add the linkerd client to your PATH environment variable. - -```sh -curl -sL https://run.linkerd.io/install | sh -export PATH=$PATH:$HOME/.linkerd2/bin -``` - -Alternatively, on MacOS you can sue `HomeBrew` to install `linkerd` - -```sh -brew install linkerd -``` - -To verify `linkerd` is setup lets try to print out the command help - -```sh -linkerd version -``` - -We can use a new feature in linkerd to check if the cluster is ready for install: - -```sh -linkerd check --pre -``` - -

Install Linkerd:

- -Deploy Linkerd custom resources: - -```sh -linkerd install | kubectl apply -f - -``` - -

- Verify install -

- -Linkerd is deployed in the `linkerd` Kubernetes namespace. Verify that Linkerd and its components are deployed, execute the command: - -```sh -linkerd check -``` - -

- Enforce mTLS strict mode -

- -By establishing mutually-authenticated connections between Linkerd proxies , Linkerd automatically enables mutual Transport Layer Security (mTLS) by default for most HTTP-based communication between services. - -

- Confirming Add-ons -

- -Linkerd, as part of this workshop, is installed with several optional addons like: - -1. Prometheus (site) -2. Grafana (site) -3. Jaeger (site) -4. Dashboard (site) - -You will use Meshery for collecting and viewing metrics, and Jaeger for viewing distributed traces. - -
+--- +doctype: "Chapter" +chapterTitle: "Getting Started" +description: "Meshery, collaborative Kubernetes manager" +videos: 6 +lectures: 8 +order: 1 +--- + + +import LinkerdAdapter from "../../../../src/assets/images/learn-layer5/linkerd/linkerd-adapter.webp"; +import InstallLinkerd from "../../../../src/assets/images/learn-layer5/linkerd/install-linkerd.webp"; + + + +

Setup Linkerd

+ +Now that we have a Kubernetes cluster and Meshery, we are ready to download and deploy Linkerd resources. + +

Steps

+ +1. [Install Linkerd](#1) +1. [Verify install](#2) +1. [Confirm add-ons](#3) + +

+ Install Linkerd +

+ +Using Meshery, select `Linkerd` from the `Management` menu. + + + + + +In the Linkerd management page: + +1. Type `linkerd` into the namespace field. +1. Click the (+) icon on the `Install` card and select `Latest Linkerd` to install the latest version of Linkerd. + + + + +{" "} + +

Alternative: Manual Installation

+ +Perform the below steps if the above steps doesn't work for you. + +

Download `linkerd` CLI

+ +On a \*nix system, you can setup linkerd by doing the following: + +The above command will get the latest Linkerd package and untar it in the same folder. + +Change into the Linkerd package directory and add the linkerd client to your PATH environment variable. + +```sh +curl -sL https://run.linkerd.io/install | sh +export PATH=$PATH:$HOME/.linkerd2/bin +``` + +Alternatively, on MacOS you can sue `HomeBrew` to install `linkerd` + +```sh +brew install linkerd +``` + +To verify `linkerd` is setup lets try to print out the command help + +```sh +linkerd version +``` + +We can use a new feature in linkerd to check if the cluster is ready for install: + +```sh +linkerd check --pre +``` + +

Install Linkerd:

+ +Deploy Linkerd custom resources: + +```sh +linkerd install | kubectl apply -f - +``` + +

+ Verify install +

+ +Linkerd is deployed in the `linkerd` Kubernetes namespace. Verify that Linkerd and its components are deployed, execute the command: + +```sh +linkerd check +``` + +

+ Enforce mTLS strict mode +

+ +By establishing mutually-authenticated connections between Linkerd proxies , Linkerd automatically enables mutual Transport Layer Security (mTLS) by default for most HTTP-based communication between services. + +

+ Confirming Add-ons +

+ +Linkerd, as part of this workshop, is installed with several optional addons like: + +1. Prometheus (site) +2. Grafana (site) +3. Jaeger (site) +4. Dashboard (site) + +You will use Meshery for collecting and viewing metrics, and Jaeger for viewing distributed traces. + +
diff --git a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/observability.mdx b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/observability.mdx index 84aa3d895df9..828cfa92f5e8 100644 --- a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/observability.mdx +++ b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/observability.mdx @@ -1,130 +1,130 @@ ---- -docType: "Chapter" -chapterTitle: "Observability" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 6 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; -import Tracing from "../../../../src/assets/images/learn-layer5/linkerd/emojivoto-tracing.webp"; -import JaegerUI from "../../../../src/assets/images/learn-layer5/linkerd/linkerd-jaeger-ui.webp"; - - - -

Linkerd Telemetry and Distributed Tracing

- -
- -

Linkerd Telemetry

- -Linkerd's telemetry and monitoring features function automatically, without requiring any work on the part of the developer. - -We have already looked at Linkerd Telemetry, not by name but by concept. Using stat, top and tap is one of the major and characteristic feature which Linkerd offers out of the box. All of this metrics are also accessible through Grafana Dashboard which Linkerd provides. - -Expose Grafana dashboard: - -```sh -linkerd dashboard & -``` - -- Start `linkerd dashboard` & navigate over the service you would want to see Grafana Dashboard for. -- In the last column, click of the `Grafana Icon` to access the metrics dashboard for the following deployment. - -

Distributed tracing with Linkerd

- -Linkerd added support for Distributed Tracing, which means that if your application has enabled tracing based on B3 Propagation, Linkerd proxies would automatically recognize that (as the trace-id is propagated through http headers) and send their spans, provided that the proxies are configured regarding the meshed trace collector endpoint. - -To enable tracing onto your cluster : - -```sh -cat >> config.yaml << EOF -tracing: - enabled: true -EOF -``` - -This configuration file can also be used to apply Add-On configuration (not just specific to tracing Add-On). - -Let us apply that configuration to the linkerd upgrade command using the --addon-config flag and pipe that output to kubectl apply. - -```sh -linkerd upgrade --addon-config config.yaml | kubectl apply -f - -``` - -Before moving onto the next step, make sure everything is up and running with kubectl: - -```sh -kubectl -n linkerd rollout status deploy/linkerd-collector -kubectl -n linkerd rollout status deploy/linkerd-jaeger -``` - -

Configure your sample application

- -Apply the tracing configuration to the `emojivoto application`: - -```sh -kubectl -n emojivoto patch -f https://run.linkerd.io/emojivoto.yml -p ' -spec: - template: - metadata: - annotations: - config.linkerd.io/trace-collector: linkerd-collector.linkerd:55678 - config.alpha.linkerd.io/trace-collector-service-account: linkerd-collector -' -``` - -Before moving onto the next step, make sure everything is up and running with kubectl: - -```sh -kubectl -n emojivoto rollout status deploy/web -``` - -The above command enables tracing in the linkerd proxies but the application containers still don’t have it enabled. Tracing can be enabled in the sample application can be enabled by - -To enable tracing in emojivoto, run: - -```sh - kubectl -n emojivoto set env --all deploy OC_AGENT_HOST=linkerd-collector.linkerd:55678 -``` - -

Explore Jaeger

- -Now, you can port-forward the `linkerd-jaeger` service to checkout the traces. - -```sh -kubectl -n linkerd port-forward svc/linkerd-jaeger 16686:16686 -``` - -Now let's explore traces of the `vote-bot` endpoint: - - - - - -So, As you can see there are spans of the linkerd-proxy. For each request between two meshed components, you can see there are four linkerd-proxy spans. - -The first two spans would be the spans sent from the proxy of the client component and will be marked as outbound. Again, in these two spans, the first one is the span of the application -> proxy, and the second one is the proxy->otherside. They are differentiated by the server and client tags respectively. - -
- -

Jaeger and Linkerd

-
-In Linkerd, as told above Grafana Integration is present in the `linkerd-web` ui -through which which you can directly jump onto the dashboards of any workload -like deployment, pod, etc. - -Linkerd has done similar thing with Jaeger, if you have `tracing` enabled, if you navigate the Linkerd Dashboard, you should see a Jaeger icon on the right. - - - - - -

Cleanup the tracing components

- -```sh -kubectl delete ns tracing emojivoto -``` - -
+--- +docType: "Chapter" +chapterTitle: "Observability" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 6 +--- + + +import Tracing from "../../../../src/assets/images/learn-layer5/linkerd/emojivoto-tracing.webp"; +import JaegerUI from "../../../../src/assets/images/learn-layer5/linkerd/linkerd-jaeger-ui.webp"; + + + +

Linkerd Telemetry and Distributed Tracing

+ +
+ +

Linkerd Telemetry

+ +Linkerd's telemetry and monitoring features function automatically, without requiring any work on the part of the developer. + +We have already looked at Linkerd Telemetry, not by name but by concept. Using stat, top and tap is one of the major and characteristic feature which Linkerd offers out of the box. All of this metrics are also accessible through Grafana Dashboard which Linkerd provides. + +Expose Grafana dashboard: + +```sh +linkerd dashboard & +``` + +- Start `linkerd dashboard` & navigate over the service you would want to see Grafana Dashboard for. +- In the last column, click of the `Grafana Icon` to access the metrics dashboard for the following deployment. + +

Distributed tracing with Linkerd

+ +Linkerd added support for Distributed Tracing, which means that if your application has enabled tracing based on B3 Propagation, Linkerd proxies would automatically recognize that (as the trace-id is propagated through http headers) and send their spans, provided that the proxies are configured regarding the meshed trace collector endpoint. + +To enable tracing onto your cluster : + +```sh +cat >> config.yaml << EOF +tracing: + enabled: true +EOF +``` + +This configuration file can also be used to apply Add-On configuration (not just specific to tracing Add-On). + +Let us apply that configuration to the linkerd upgrade command using the --addon-config flag and pipe that output to kubectl apply. + +```sh +linkerd upgrade --addon-config config.yaml | kubectl apply -f - +``` + +Before moving onto the next step, make sure everything is up and running with kubectl: + +```sh +kubectl -n linkerd rollout status deploy/linkerd-collector +kubectl -n linkerd rollout status deploy/linkerd-jaeger +``` + +

Configure your sample application

+ +Apply the tracing configuration to the `emojivoto application`: + +```sh +kubectl -n emojivoto patch -f https://run.linkerd.io/emojivoto.yml -p ' +spec: + template: + metadata: + annotations: + config.linkerd.io/trace-collector: linkerd-collector.linkerd:55678 + config.alpha.linkerd.io/trace-collector-service-account: linkerd-collector +' +``` + +Before moving onto the next step, make sure everything is up and running with kubectl: + +```sh +kubectl -n emojivoto rollout status deploy/web +``` + +The above command enables tracing in the linkerd proxies but the application containers still don’t have it enabled. Tracing can be enabled in the sample application can be enabled by + +To enable tracing in emojivoto, run: + +```sh + kubectl -n emojivoto set env --all deploy OC_AGENT_HOST=linkerd-collector.linkerd:55678 +``` + +

Explore Jaeger

+ +Now, you can port-forward the `linkerd-jaeger` service to checkout the traces. + +```sh +kubectl -n linkerd port-forward svc/linkerd-jaeger 16686:16686 +``` + +Now let's explore traces of the `vote-bot` endpoint: + + + + + +So, As you can see there are spans of the linkerd-proxy. For each request between two meshed components, you can see there are four linkerd-proxy spans. + +The first two spans would be the spans sent from the proxy of the client component and will be marked as outbound. Again, in these two spans, the first one is the span of the application -> proxy, and the second one is the proxy->otherside. They are differentiated by the server and client tags respectively. + +
+ +

Jaeger and Linkerd

+
+In Linkerd, as told above Grafana Integration is present in the `linkerd-web` ui +through which which you can directly jump onto the dashboards of any workload +like deployment, pod, etc. + +Linkerd has done similar thing with Jaeger, if you have `tracing` enabled, if you navigate the Linkerd Dashboard, you should see a Jaeger icon on the right. + + + + + +

Cleanup the tracing components

+ +```sh +kubectl delete ns tracing emojivoto +``` + +
diff --git a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/traffic-splitting.mdx b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/traffic-splitting.mdx index 6040f55e6bc7..8e359479eaf7 100644 --- a/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/traffic-splitting.mdx +++ b/content-learn/mastering-service-meshes-for-developers/introduction-to-service-meshes/linkerd/traffic-splitting.mdx @@ -1,127 +1,127 @@ ---- -docType: "Chapter" -chapterTitle: "Traffic Splitting using SMI and Linkerd" -description: "Meshery, collaborative Kubernetes manager" -videos: 4 -lectures: 12 -order: 7 ---- - -import { ChapterStyle } from "../../../../src/components/Learn-Components/Chapters-Style/chapters.style.js"; -import ControlPlane from "../../../../src/assets/images/learn-layer5/linkerd/control-plane-c.webp"; - - - -

How Linkerd handles traffic splitting

- - - - - -The destination component of the control plane looks for changes in configuration of linkerd (actualized as Kubernetes Custom Resource Definitions) and afterward pushes the right config for - -proxies to follow. As opposed to presenting its own configuration format for traffic splitting, Linkerd follows the [SMI spec](https://smi-spec.io/), which plans to give a brought together, summed up setup model for service meshes (simply like ingress, CRI, and so on in Kubernetes). - -

Deploying sample application

- -We will be deploying [istio's bookinfo application](https://istio.io/latest/docs/examples/bookinfo/) for this part of the demo - -Use meshery to deploy the bookinfo application : - -- In Meshery, navigate to the Linkerd adapter's management page from the left nav menu. -- On the Linkerd adapter's management page, please enter `default` in the `Namespace` field. -- Then, click the (+) icon on the `Sample Application` card and select `Bookinfo Application` from the list. - -OR... - -- Download the [./sample/bookinfo.yaml](https://raw.githubusercontent.com/layer5io/linkerd-service-mesh-workshop/master/lab-7/sample/book-info.yaml) -- Inject linkerd into the sample application. - -```sh -linkerd inject ./sample/bookinfo.yaml | kubectl apply -f - -``` - -This will give you the if the Linkerd injection was successful or not. - -```sh -linkerd stat deploy -``` - -You will see the following services running in your cluster - -```sh - kubectl get svc - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE - details ClusterIP 10.96.115.62 9080/TCP 13m - kubernetes ClusterIP 10.96.0.1 443/TCP 7h56m - productpage ClusterIP 10.109.31.20 9080/TCP 13m - ratings ClusterIP 10.101.57.168 9080/TCP 13m - reviews ClusterIP 10.105.52.139 9080/TCP 13m -``` - -You can access the producpage by port-forwarding - -```sh - kubectl port-forward svc/productpage 9080:9080 -``` - -Checking localhost:9080 would show you a product page, with a list of reviews on the right. Those reviews are being loaded from the reviews service which is backed by the 3 reviews pods. The requests to the reviews service are randomly sent to one of the 3 review pods, as they represent different versions of this service. - -The three different versions provide different output: - -- v1 with No stars -- v2 with Orange stars -- v3 with Black stars - -We will have reviews service only split traffic between v1 and v2 of the application. - -In Linkerd’s approach to traffic splitting, services are used as the core primitives. Hence we need to create two new services corresponding to v1 & v2 pods. - -```sh -kubectl apply -f ./sample/service.yaml -``` - -There are two new services created - -```sh - kubectl get svc - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE - details ClusterIP 10.96.115.62 9080/TCP 35m - kubernetes ClusterIP 10.96.0.1 443/TCP 8h - productpage ClusterIP 10.109.31.20 9080/TCP 35m - ratings ClusterIP 10.101.57.168 9080/TCP 35m - reviews ClusterIP 10.105.52.139 9080/TCP 35m - reviews-v2 ClusterIP 10.106.174.219 9080/TCP 7s - reviews-v3 ClusterIP 10.96.125.224 9080/TCP 7s -``` - -Now, let's apply traffic-split CRD from SMI : - -```sh -apiVersion: split.smi-spec.io/v1alpha1 -kind: TrafficSplit -metadata: - name: reviews-split -spec: - service: reviews - backends: - - service: reviews-v1 - weight: 500m - - service: reviews-v2 - weight: 500m -``` - -This tells Linkerd’s control plane that whenever there are requests to the reviews service, to split them across the `reviews-v1` and `reviews-v2` based on the weights provided. - -If we now go back to our product page, we can only see the reviews with orange or no stars appear on each refresh. - -

Cleanup

- -```sh -kubectl delete trafficsplit/reviews-split -kubectl delete -f ./sample/service.yaml -``` - -- Remove the bookinfo application from the `Meshery Dashboard` by clicking on the `trash icon` in the `sample application` card on the linkerd adapters' page. - -
+--- +docType: "Chapter" +chapterTitle: "Traffic Splitting using SMI and Linkerd" +description: "Meshery, collaborative Kubernetes manager" +videos: 4 +lectures: 12 +order: 7 +--- + + +import ControlPlane from "../../../../src/assets/images/learn-layer5/linkerd/control-plane-c.webp"; + + + +

How Linkerd handles traffic splitting

+ + + + + +The destination component of the control plane looks for changes in configuration of linkerd (actualized as Kubernetes Custom Resource Definitions) and afterward pushes the right config for + +proxies to follow. As opposed to presenting its own configuration format for traffic splitting, Linkerd follows the [SMI spec](https://smi-spec.io/), which plans to give a brought together, summed up setup model for service meshes (simply like ingress, CRI, and so on in Kubernetes). + +

Deploying sample application

+ +We will be deploying [istio's bookinfo application](https://istio.io/latest/docs/examples/bookinfo/) for this part of the demo + +Use meshery to deploy the bookinfo application : + +- In Meshery, navigate to the Linkerd adapter's management page from the left nav menu. +- On the Linkerd adapter's management page, please enter `default` in the `Namespace` field. +- Then, click the (+) icon on the `Sample Application` card and select `Bookinfo Application` from the list. + +OR... + +- Download the [./sample/bookinfo.yaml](https://raw.githubusercontent.com/layer5io/linkerd-service-mesh-workshop/master/lab-7/sample/book-info.yaml) +- Inject linkerd into the sample application. + +```sh +linkerd inject ./sample/bookinfo.yaml | kubectl apply -f - +``` + +This will give you the if the Linkerd injection was successful or not. + +```sh +linkerd stat deploy +``` + +You will see the following services running in your cluster + +```sh + kubectl get svc + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + details ClusterIP 10.96.115.62 9080/TCP 13m + kubernetes ClusterIP 10.96.0.1 443/TCP 7h56m + productpage ClusterIP 10.109.31.20 9080/TCP 13m + ratings ClusterIP 10.101.57.168 9080/TCP 13m + reviews ClusterIP 10.105.52.139 9080/TCP 13m +``` + +You can access the producpage by port-forwarding + +```sh + kubectl port-forward svc/productpage 9080:9080 +``` + +Checking localhost:9080 would show you a product page, with a list of reviews on the right. Those reviews are being loaded from the reviews service which is backed by the 3 reviews pods. The requests to the reviews service are randomly sent to one of the 3 review pods, as they represent different versions of this service. + +The three different versions provide different output: + +- v1 with No stars +- v2 with Orange stars +- v3 with Black stars + +We will have reviews service only split traffic between v1 and v2 of the application. + +In Linkerd’s approach to traffic splitting, services are used as the core primitives. Hence we need to create two new services corresponding to v1 & v2 pods. + +```sh +kubectl apply -f ./sample/service.yaml +``` + +There are two new services created + +```sh + kubectl get svc + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + details ClusterIP 10.96.115.62 9080/TCP 35m + kubernetes ClusterIP 10.96.0.1 443/TCP 8h + productpage ClusterIP 10.109.31.20 9080/TCP 35m + ratings ClusterIP 10.101.57.168 9080/TCP 35m + reviews ClusterIP 10.105.52.139 9080/TCP 35m + reviews-v2 ClusterIP 10.106.174.219 9080/TCP 7s + reviews-v3 ClusterIP 10.96.125.224 9080/TCP 7s +``` + +Now, let's apply traffic-split CRD from SMI : + +```sh +apiVersion: split.smi-spec.io/v1alpha1 +kind: TrafficSplit +metadata: + name: reviews-split +spec: + service: reviews + backends: + - service: reviews-v1 + weight: 500m + - service: reviews-v2 + weight: 500m +``` + +This tells Linkerd’s control plane that whenever there are requests to the reviews service, to split them across the `reviews-v1` and `reviews-v2` based on the weights provided. + +If we now go back to our product page, we can only see the reviews with orange or no stars appear on each refresh. + +

Cleanup

+ +```sh +kubectl delete trafficsplit/reviews-split +kubectl delete -f ./sample/service.yaml +``` + +- Remove the bookinfo application from the `Meshery Dashboard` by clicking on the `trash icon` in the `sample application` card on the linkerd adapters' page. + +
diff --git a/gatsby-config.js b/gatsby-config.js index 7f59da1f9a50..96911541c507 100644 --- a/gatsby-config.js +++ b/gatsby-config.js @@ -1,4 +1,9 @@ /* eslint-env node */ +require("dotenv").config({ + path: `.env.${process.env.NODE_ENV}`, +}); + +const devIgnoreArray = require("./gatsby-dev-filesystem-ignore"); module.exports = { siteMetadata: { @@ -17,7 +22,7 @@ module.exports = { }, trailingSlash: "never", plugins: [ - "@mediacurrent/gatsby-plugin-silence-css-order-warning", + "gatsby-plugin-no-sourcemaps", { resolve: "gatsby-plugin-webpack-bundle-analyser-v2", options: { @@ -112,35 +117,36 @@ module.exports = { site.siteMetadata.siteUrl + node.frontmatter.thumbnail.publicURL, }, - custom_elements: [{ "content:encoded": node.html }], + custom_elements: [{ "content:encoded": node.excerpt }], }); }); }, - query: `{ - allPosts: allMdx( - sort: {frontmatter: {date: DESC}} - filter: {fields: {collection: {in: ["blog", "resources", "news"]}}, frontmatter: {published: {eq: true}, category: {nin: ["Programs", "Community", "Events", "FAQ"]}}} - limit: 20 - ) { - nodes { - body - html - frontmatter { - title - author - description - date(formatString: "MMM DD YYYY") - thumbnail { - publicURL - } - } - fields { - collection - slug - } - } - } -}`, + query: ` + { + allPosts: allMdx( + sort: { fields: [frontmatter___date], order: DESC } + filter: { fields: { collection: { in: ["blog", "resources", "news"] } }, frontmatter: { published: { eq: true }, category: { nin: ["Programs", "Community", "Events", "FAQ"] } } } + limit: 20 + ) { + nodes { + excerpt + frontmatter { + title + author + description + date(formatString: "MMM DD YYYY") + thumbnail { + publicURL + } + } + fields { + collection + slug + } + } + } + } + `, output: "/rss.xml", title: "Layer5 Technical Posts", }, @@ -150,7 +156,7 @@ module.exports = { return Object.assign({}, node.frontmatter, { title: node.frontmatter.title, author: node.frontmatter.author, - description: node.body, + description: node.description, date: node.frontmatter.date, url: site.siteMetadata.siteUrl + node.fields.slug, guid: site.siteMetadata.siteUrl + node.fields.slug, @@ -159,34 +165,35 @@ module.exports = { site.siteMetadata.siteUrl + node.frontmatter.thumbnail.publicURL, }, - custom_elements: [{ "content:encoded": node.html }], + custom_elements: [{ "content:encoded": node.excerpt }], }); }); }, - query: `{ - allPosts: allMdx( - sort: {frontmatter: {date: DESC}} - filter: {fields: {collection: {in: ["news"]}}, frontmatter: {published: {eq: true}}} - limit: 20 - ) { - nodes { - body - html - frontmatter { - title - author - date(formatString: "MMM DD YYYY") - thumbnail { - publicURL - } - } - fields { - collection - slug - } - } - } -}`, + query: ` + { + allPosts: allMdx( + sort: { fields: [frontmatter___date], order: DESC } + filter: { fields: { collection: { in: [ "news"] } }, frontmatter: { published: { eq: true } } } + limit: 20 + ) { + nodes { + excerpt + frontmatter { + title + author + date(formatString: "MMM DD YYYY") + thumbnail { + publicURL + } + } + fields { + collection + slug + } + } + } + } + `, output: "/news/feed.xml", title: "Layer5 News", }, @@ -196,7 +203,7 @@ module.exports = { return Object.assign({}, node.frontmatter, { title: node.frontmatter.title, author: node.frontmatter.author, - description: node.body, + description: node.description, date: node.frontmatter.date, url: site.siteMetadata.siteUrl + node.fields.slug, guid: site.siteMetadata.siteUrl + node.fields.slug, @@ -205,37 +212,38 @@ module.exports = { site.siteMetadata.siteUrl + node.frontmatter.thumbnail.publicURL, }, - custom_elements: [{ "content:encoded": node.html }], + custom_elements: [{ "content:encoded": node.excerpt }], }); }); }, - query: `{ - allPosts: allMdx( - sort: {frontmatter: {date: DESC}} - filter: {fields: {collection: {in: ["resources"]}}, frontmatter: {published: {eq: true}}} - limit: 20 - ) { - nodes { - body - html - frontmatter { - title - author - date(formatString: "MMM DD YYYY") - thumbnail { - publicURL - } - darkthumbnail { - publicURL - } - } - fields { - collection - slug - } - } - } -}`, + query: ` + { + allPosts: allMdx( + sort: { fields: [frontmatter___date], order: DESC } + filter: { fields: { collection: { in: [ "resources"] } }, frontmatter: { published: { eq: true } } } + limit: 20 + ) { + nodes { + excerpt + frontmatter { + title + author + date(formatString: "MMM DD YYYY") + thumbnail { + publicURL + } + darkthumbnail { + publicURL + } + } + fields { + collection + slug + } + } + } + } + `, output: "/resources/feed.xml", title: "Layer5 Resources", }, @@ -254,35 +262,36 @@ module.exports = { site.siteMetadata.siteUrl + node.frontmatter.thumbnail.publicURL, }, - custom_elements: [{ "content:encoded": node.html }], + custom_elements: [{ "content:encoded": node.excerpt }], }); }); }, - query: `{ - allPosts: allMdx( - sort: {frontmatter: {date: DESC}} - filter: {fields: {collection: {in: ["blog", "news"]}}, frontmatter: {published: {eq: true}}} - limit: 20 - ) { - nodes { - body - html - frontmatter { - title - author - description - date(formatString: "MMM DD YYYY") - thumbnail { - publicURL - } - } - fields { - collection - slug - } - } - } -}`, + query: ` + { + allPosts: allMdx( + sort: { fields: [frontmatter___date], order: DESC } + filter: { fields: { collection: { in: ["blog", "news"] } }, frontmatter: { published: { eq: true } } } + limit: 20 + ) { + nodes { + excerpt + frontmatter { + title + author + description + date(formatString: "MMM DD YYYY") + thumbnail { + publicURL + } + } + fields { + collection + slug + } + } + } + } + `, output: "/rss-contributors.xml", title: "Layer5 Contributor Feed", }, @@ -299,35 +308,36 @@ module.exports = { enclosure: node.frontmatter.thumbnail && { url: site.siteMetadata.siteUrl + node.frontmatter.thumbnail.publicURL, }, - custom_elements: [{ "content:encoded": node.html }], + custom_elements: [{ "content:encoded": node.excerpt }], }); }); }, - query: `{ - allPosts: allMdx( - sort: {frontmatter: {date: DESC}} - filter: {fields: {collection: {in: ["blog"]}}, frontmatter: {published: {eq: true}}} - limit: 20 - ) { - nodes { - body - html - frontmatter { - title - author - description - date(formatString: "MMM DD YYYY") - thumbnail { - publicURL - } - } - fields { - collection - slug - } - } - } -}`, + query: ` + { + allPosts: allMdx( + sort: { fields: [frontmatter___date], order: DESC } + filter: { fields: { collection: { in: ["blog"] } }, frontmatter: { published: { eq: true }, } } + limit: 20 + ) { + nodes { + excerpt + frontmatter { + title + author + description + date(formatString: "MMM DD YYYY") + thumbnail { + publicURL + } + } + fields { + collection + slug + } + } + } + } + `, output: "/blog/feed.xml", title: "Layer5 Blog" }, @@ -344,35 +354,36 @@ module.exports = { enclosure: node.frontmatter.thumbnail && { url: site.siteMetadata.siteUrl + node.frontmatter.thumbnail.publicURL, }, - custom_elements: [{ "content:encoded": node.html }], + custom_elements: [{ "content:encoded": node.excerpt }], }); }); }, - query: `{ - allPosts: allMdx( - sort: {frontmatter: {date: DESC}} - filter: {fields: {collection: {in: ["events"]}}, frontmatter: {published: {eq: true}}} - limit: 20 - ) { - nodes { - body - html - frontmatter { - title - author - description - date(formatString: "MMM DD YYYY") - thumbnail { - publicURL - } - } - fields { - collection - slug - } - } - } -}`, + query: ` + { + allPosts: allMdx( + sort: { fields: [frontmatter___date], order: DESC } + filter: { fields: { collection: { in: ["events"] } }, frontmatter: { published: { eq: true }, } } + limit: 20 + ) { + nodes { + excerpt + frontmatter { + title + author + description + date(formatString: "MMM DD YYYY") + thumbnail { + publicURL + } + } + fields { + collection + slug + } + } + } + } + `, output: "/events/feed.xml", title: "Layer5 Events" }, @@ -394,7 +405,21 @@ module.exports = { { resolve: "gatsby-plugin-mdx", options: { - extensions: [".mdx", ".md"], + extensions: [".mdx"], + mdxOptions: { + remarkPlugins: [ + // Add GitHub Flavored Markdown (GFM) support + require("remark-gfm"), + ] + }, + gatsbyRemarkPlugins: [ + { + resolve: "gatsby-remark-images", + options: { + maxWidth: 1000, + }, + } + ], }, }, { @@ -409,6 +434,9 @@ module.exports = { options: { path: `${__dirname}/src/collections/blog`, name: "blog", + // ignore: process.env.GATSBY_DEV_AMENDED === "true" + // ? devIgnoreArray("blog") + // : [] }, }, { @@ -416,6 +444,9 @@ module.exports = { options: { path: `${__dirname}/src/collections/news`, name: "news", + // ignore: process.env.GATSBY_DEV_AMENDED === "true" + // ? devIgnoreArray("news") + // : [] }, }, { @@ -451,6 +482,9 @@ module.exports = { options: { path: `${__dirname}/src/collections/members`, name: "members", + ignore: process.env.GATSBY_DEV_AMENDED === "true" + ? devIgnoreArray("members") + : [] }, }, { @@ -479,6 +513,9 @@ module.exports = { options: { path: `${__dirname}/src/collections/events`, name: "events", + // ignore: process.env.GATSBY_DEV_AMENDED === "true" + // ? devIgnoreArray("events") + // : [] }, }, { @@ -493,6 +530,9 @@ module.exports = { options: { path: `${__dirname}/src/collections/integrations`, name: "integrations", + // ignore: process.env.GATSBY_DEV_AMENDED === "true" + // ? devIgnoreArray("integrations") + // : [] }, }, { diff --git a/gatsby-dev-filesystem-ignore.js b/gatsby-dev-filesystem-ignore.js new file mode 100644 index 000000000000..5c3aa1f99ed6 --- /dev/null +++ b/gatsby-dev-filesystem-ignore.js @@ -0,0 +1,37 @@ +const fs = require("fs"); +const path = require("path"); + +function getDirectories(srcpath) { + return fs.readdirSync(srcpath) + .map(file => path.join(srcpath, file)) + .filter(path => fs.statSync(path).isDirectory()); +} + +const collectionWithYears = ["blog", "news"]; + +function devIgnoreArray(folder) { + + const folderMap = getDirectories(`${__dirname}/src/collections/${folder}`).map(url => url.replace(`${__dirname}/src/collections/${folder}/`, "")); + + if (collectionWithYears.includes(folder)) { + const includeArray = []; + let folderCount = 0; + const foldersWithYears = folderMap.map(name => Number(name)).filter(number => !isNaN(number)).sort((a, b) => b - a).map(year => year.toString()); + + for (const itemFolder of foldersWithYears) { + includeArray.push(itemFolder); + const numFolders = getDirectories(`${__dirname}/src/collections/${folder}/${itemFolder}`).length; + folderCount = folderCount + numFolders; + if (folderCount > 10) return folderMap.filter(item => !includeArray.includes(item)).map(item => `**/${item}`); + } + } else if (folder === "members") { + const excludeArray = folderMap.filter(item => item !== "lee-calcote"); + return excludeArray.slice(165).map(item => `**/${item}`); + } else { + return folderMap.length > 12 + ? folderMap.slice(12).map(item => `**/${item}`) + : []; + } +} + +module.exports = devIgnoreArray; \ No newline at end of file diff --git a/gatsby-node.js b/gatsby-node.js index 7f8a6cb95605..b5b8994b027b 100644 --- a/gatsby-node.js +++ b/gatsby-node.js @@ -1037,4 +1037,4 @@ exports.createSchemaCustomization = ({ actions }) => { } `; createTypes(typeDefs); -}; +}; \ No newline at end of file diff --git a/gatsby-ssr.js b/gatsby-ssr.js index a71b435ee356..7065f9fcdfcd 100644 --- a/gatsby-ssr.js +++ b/gatsby-ssr.js @@ -1,3 +1,101 @@ +import { Link } from "gatsby"; +import Button from "./src/reusecore/Button"; +import Blockquote from "./src/reusecore/Blockquote"; +import BlockquoteAlt from "./src/reusecore/Blockquote/Blockquote-alt-style"; +import Code from "./src/components/CodeBlock"; +import Col from "./src/reusecore/Layout/Col"; +import CommonForm from "./src/components/CommonForm"; +import CTA_Bottom from "./src/components/Call-To-Actions/CTA_Bottom"; +import CTA_FullWidth from "./src/components/Call-To-Actions/CTA_FullWidth"; +import CTA_ImageOnly from "./src/components/Call-To-Actions/CTA_ImageOnly"; +import DockerExtensionCTA from "./src/sections/Docker-Meshery/docker-extension-CTA"; +import PlaygroundCTA from "./src/sections/Playground/playground-CTA.js"; +import FAQ from "./src/sections/General/Faq"; +import Table from "./src/components/service-mesh-patterns-Table/Table.js"; + +import blogCategoryListTemplate from "./src/templates/blog-category-list.js"; +import blogPostTemplate from "./src/templates/blog-single.js"; +import blogTagListTemplate from "./src/templates/blog-tag-list.js"; +import BookPostTemplate from "./src/templates/book-single.js"; +import CareerPostTemplate from "./src/templates/career-single.js"; +import chapterTemplate from "./src/templates/learn-chapter.js"; +import courseListTemplate from "./src/templates/courses-list.js"; +import courseOverviewTemplate from "./src/templates/course-overview.js"; +import EventTemplate from "./src/templates/event-single.js"; +import EventsTemplate from "./src/templates/events.js"; +import integrationTemplate from "./src/templates/integrations.js"; +import LabTemplate from "./src/templates/lab-single.js"; +import MemberTemplate from "./src/templates/member-single.js"; +import MemberBioTemplate from "./src/templates/executive-bio.js"; +import MultiProgramPostTemplate from "./src/templates/program-multiple.js"; +import NewsPostTemplate from "./src/templates/news-single.js"; +import ProgramPostTemplate from "./src/templates/program-single.js"; +import resourcePostTemplate from "./src/templates/resource-single.js"; +import WorkshopTemplate from "./src/templates/workshop-single.js"; + +import BlogWrapper from "./src/collections/blog/Blog.style.js"; +import BookWrapper from "./src/collections/service-mesh-books/Book.style.js"; +import CareerWrapper from "./src/collections/careers/Career.style.js"; +import ChapterStyle from "./src/components/Learn-Components/Chapters-Style/chapters.style.js"; +import EventWrapper from "./src/collections/events/Event.style.js"; +import MeetTheMaintainer from "./src/collections/blog/MeetTheMaintainer.style"; +import MeetTheMeshMate from "./src/collections/blog/MeetTheMeshMate.style"; +import NewsWrapper from "./src/collections/news/News.style.js"; +import PositionApply from "./src/collections/careers/how-to-apply.js"; +import ProgramsWrapper from "./src/collections/programs/Programs.style.js"; +import ProjectWrapper from "./src/collections/projects/Project.style.js"; +import ResourcesWrapper from "./src/collections/resources/Resources.style.js"; + +//workaround to resolve build heap OOM error due to mdxv2 upgrade (ref: https://github.com/gatsbyjs/gatsby/issues/36899#issuecomment-1422616312), revisit with upgrade to gatsby v5 and gatsby-plugin-mdx if still applicable +// eslint-disable-next-line no-unused-vars +const MDXComponents = [ + Button, + Blockquote, + BlockquoteAlt, + Code, + Col, + CommonForm, + CTA_Bottom, + CTA_FullWidth, + CTA_ImageOnly, + DockerExtensionCTA, + PlaygroundCTA, + FAQ, + Link, + Table, + blogCategoryListTemplate, + blogPostTemplate, + blogTagListTemplate, + BookPostTemplate, + CareerPostTemplate, + chapterTemplate, + courseListTemplate, + courseOverviewTemplate, + EventTemplate, + EventsTemplate, + integrationTemplate, + LabTemplate, + MemberTemplate, + MemberBioTemplate, + MultiProgramPostTemplate, + NewsPostTemplate, + ProgramPostTemplate, + resourcePostTemplate, + WorkshopTemplate, + BlogWrapper, + BookWrapper, + ChapterStyle, + CareerWrapper, + EventWrapper, + MeetTheMaintainer, + MeetTheMeshMate, + NewsWrapper, + PositionApply, + ProgramsWrapper, + ProjectWrapper, + ResourcesWrapper, +]; + export { onRenderBody } from "./onRenderBody"; export { wrapRootElement } from "./root-wrapper"; export { wrapPageElement } from "./page-wrapper"; diff --git a/package-lock.json b/package-lock.json index fa954b791b47..895009b85471 100644 --- a/package-lock.json +++ b/package-lock.json @@ -12,17 +12,14 @@ "@emotion/react": "^11.11.4", "@emotion/styled": "^11.14.0", "@fullcalendar/core": "^6.1.8", - "@fullcalendar/daygrid": "^6.1.8", - "@fullcalendar/google-calendar": "^6.0.2", - "@fullcalendar/interaction": "^6.0.1", - "@fullcalendar/react": "^6.1.8", - "@layer5/meshery-design-embed": "^0.4.0", - "@layer5/sistent": "^0.14.109", - "@loadable/component": "^5.16.4", - "@mdx-js/mdx": "1.6.22", - "@mdx-js/react": "1.6.22", - "@mediacurrent/gatsby-plugin-silence-css-order-warning": "^1.0.0", - "@mui/icons-material": "^5.16.4", + "@fullcalendar/daygrid": "^5.11.3", + "@fullcalendar/google-calendar": "^6.1.9", + "@fullcalendar/interaction": "^6.1.13", + "@fullcalendar/react": "^5.11.2", + "@layer5/meshery-design-embed": "^0.2.0", + "@layer5/sistent": "^0.14.60", + "@loadable/component": "^5.15.3", + "@mdx-js/react": "^2.3.0", "@mui/material": "^5.15.11", "@react-icons/all-files": "^4.1.0", "@svgr/webpack": "^8.0.1", @@ -46,8 +43,9 @@ "gatsby-plugin-image": "^3.11.0", "gatsby-plugin-loadable-components-ssr": "^4.3.2", "gatsby-plugin-manifest": "^5.11.0", - "gatsby-plugin-mdx": "3.20.0", + "gatsby-plugin-mdx": "^5.0.0", "gatsby-plugin-meta-redirect": "github:layer5labs/gatsby-plugin-meta-redirect", + "gatsby-plugin-no-sourcemaps": "^4.25.0", "gatsby-plugin-preload-fonts": "^4.11.0", "gatsby-plugin-robots-txt": "^1.8.0", "gatsby-plugin-sharp": "^5.11.0", @@ -55,6 +53,7 @@ "gatsby-plugin-styled-components": "^6.11.0", "gatsby-plugin-svgr": "^3.0.0-beta.0", "gatsby-redirect-from": "1.0.4", + "gatsby-remark-images": "^6.25.0", "gatsby-source-filesystem": "^5.14.0", "gatsby-transformer-sharp": "^5.11.0", "gbimage-bridge": "^0.2.2", @@ -67,6 +66,7 @@ "path-browserify": "^1.0.1", "prism-react-renderer": "^2.0.6", "process": "^0.11.10", + "process-top": "^1.2.0", "prop-types": "^15.7.2", "react": "^18.2.0", "react-accessible-accordion": "^5.0.0", @@ -78,6 +78,7 @@ "react-honeycomb": "^0.1.3", "react-intersection-observer": "^9.5.2", "react-loadable": "^5.5.0", + "react-markdown": "^8.0.7", "react-modal": "^3.16.1", "react-player": "^2.12.0", "react-scroll": "^1.9.0", @@ -90,6 +91,8 @@ "react-tsparticles": "^2.11.0", "react-vertical-timeline-component": "^3.5.2", "react-visibility-sensor": "^5.1.1", + "rehype-raw": "^6.1.1", + "remark-gfm": "^1.0.0", "sharp": "^0.33.5", "simple-react-cytoscape": "^1.0.4", "simple-react-lightbox": "^3.6.9-0", @@ -107,8 +110,9 @@ "babel-plugin-module-resolver": "^5.0.0", "cpx": "^1.5.0", "env-cmd": "^10.1.0", - "eslint": "^8.46.0", - "eslint-plugin-react": "^7.37.3", + "eslint": "^8.57.0", + "eslint-plugin-mdx": "^2.1.0", + "eslint-plugin-react": "^7.34.2", "gatsby-plugin-webpack-bundle-analyser-v2": "^1.1.30", "gh-pages": "^6.0.0", "husky": "^8.0.3", @@ -2163,15 +2167,6 @@ "node": ">=10.0.0" } }, - "node_modules/@emnapi/runtime": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/@emnapi/runtime/-/runtime-1.2.0.tgz", - "integrity": "sha512-bV21/9LQmcQeCPEg3BDFtvwL6cwiTMksYNWQQ4KOxCZikEGalWtenoZ0wCiukJINlGCIi2KXx01g4FoH/LxpzQ==", - "optional": true, - "dependencies": { - "tslib": "^2.4.0" - } - }, "node_modules/@emotion/babel-plugin": { "version": "11.13.5", "resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz", @@ -2347,6 +2342,7 @@ "version": "2.1.4", "resolved": "https://registry.npmjs.org/@eslint/eslintrc/-/eslintrc-2.1.4.tgz", "integrity": "sha512-269Z39MS6wVJtsoUl10L60WdkhJVdPG24Q4eZTH3nnF6lpvSShEK3wQjDX9JRWAUPvPh7COouPpU9IrqaZFvtQ==", + "dev": true, "dependencies": { "ajv": "^6.12.4", "debug": "^4.3.2", @@ -2369,6 +2365,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -2384,6 +2381,7 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -2397,12 +2395,14 @@ "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/@eslint/js": { "version": "8.57.1", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.57.1.tgz", "integrity": "sha512-d9zaMRSTIKDLhctzH12MtXvJKSSUhaHcjV+2Z+GK+EEY7XKpP5yR4x+N3TAcHTcu963nIr+TMcCb4DBCYX1z6Q==", + "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } @@ -2429,6 +2429,14 @@ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.8.tgz", "integrity": "sha512-kym7SodPp8/wloecOpcmSnWJsK7M0E5Wg8UcFA+uO4B9s5d0ywXOEro/8HM9x0rW+TljRzul/14UYz3TleT3ig==" }, + "node_modules/@fullcalendar/common": { + "version": "5.11.5", + "resolved": "https://registry.npmjs.org/@fullcalendar/common/-/common-5.11.5.tgz", + "integrity": "sha512-3iAYiUbHXhjSVXnYWz27Od2cslztUPsOwiwKlfGvQxBixv2Kl6a8IPwaijKFYJHXdwYmfPoEgK7rvqAGVoIYwA==", + "dependencies": { + "tslib": "^2.1.0" + } + }, "node_modules/@fullcalendar/core": { "version": "6.1.15", "resolved": "https://registry.npmjs.org/@fullcalendar/core/-/core-6.1.15.tgz", @@ -2438,11 +2446,12 @@ } }, "node_modules/@fullcalendar/daygrid": { - "version": "6.1.15", - "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-6.1.15.tgz", - "integrity": "sha512-j8tL0HhfiVsdtOCLfzK2J0RtSkiad3BYYemwQKq512cx6btz6ZZ2RNc/hVnIxluuWFyvx5sXZwoeTJsFSFTEFA==", - "peerDependencies": { - "@fullcalendar/core": "~6.1.15" + "version": "5.11.5", + "resolved": "https://registry.npmjs.org/@fullcalendar/daygrid/-/daygrid-5.11.5.tgz", + "integrity": "sha512-hMpq0U3Nucys2jDD+crbkJCr+tVt3fDw04OE3fbpisuzqtrHxIzRmnUOdbWUjJQyToAAkt7UVUQ9E7hYdmvyGA==", + "dependencies": { + "@fullcalendar/common": "~5.11.5", + "tslib": "^2.1.0" } }, "node_modules/@fullcalendar/google-calendar": { @@ -2462,13 +2471,16 @@ } }, "node_modules/@fullcalendar/react": { - "version": "6.1.15", - "resolved": "https://registry.npmjs.org/@fullcalendar/react/-/react-6.1.15.tgz", - "integrity": "sha512-L0b9hybS2J4e7lq6G2CD4nqriyLEqOH1tE8iI6JQjAMTVh5JicOo5Mqw+fhU5bJ7hLfMw2K3fksxX3Ul1ssw5w==", + "version": "5.11.5", + "resolved": "https://registry.npmjs.org/@fullcalendar/react/-/react-5.11.5.tgz", + "integrity": "sha512-PbBlDyKJ8IQYf5mBdD1mjDas2v3eEU1UfWYLv0e6uGCktH+g4mgaG/LCDOwE65V5VH5FH8+kVkFjIScwA54WwA==", + "dependencies": { + "@fullcalendar/common": "~5.11.5", + "tslib": "^2.1.0" + }, "peerDependencies": { - "@fullcalendar/core": "~6.1.15", - "react": "^16.7.0 || ^17 || ^18 || ^19", - "react-dom": "^16.7.0 || ^17 || ^18 || ^19" + "react": "^16.7.0 || ^17 || ^18", + "react-dom": "^16.7.0 || ^17 || ^18" } }, "node_modules/@gatsbyjs/parcel-namer-relative-to-cwd": { @@ -2991,6 +3003,7 @@ "resolved": "https://registry.npmjs.org/@humanwhocodes/config-array/-/config-array-0.13.0.tgz", "integrity": "sha512-DZLEEqFWQFiyK6h5YIeynKx7JlvCYWL0cImfSRXZ9l4Sg2efkFGTuFf6vzXjK1cq6IYkU+Eg/JizXw+TD2vRNw==", "deprecated": "Use @eslint/config-array instead", + "dev": true, "dependencies": { "@humanwhocodes/object-schema": "^2.0.3", "debug": "^4.3.1", @@ -3004,6 +3017,7 @@ "version": "1.0.1", "resolved": "https://registry.npmjs.org/@humanwhocodes/module-importer/-/module-importer-1.0.1.tgz", "integrity": "sha512-bxveV4V8v5Yb4ncFTT3rPSgZBOpCkjfK0y4oVVVJwIuDVBRMDXrPyXRL988i5ap9m9bnyEEjWfm5WkBmtffLfA==", + "dev": true, "engines": { "node": ">=12.22" }, @@ -3016,124 +3030,8 @@ "version": "2.0.3", "resolved": "https://registry.npmjs.org/@humanwhocodes/object-schema/-/object-schema-2.0.3.tgz", "integrity": "sha512-93zYdMES/c1D69yZiKDBj0V24vqNzB/koF26KPaagAfd3P/4gUlh3Dys5ogAK+Exi9QyzlD8x/08Zt7wIKcDcA==", - "deprecated": "Use @eslint/object-schema instead" - }, - "node_modules/@img/sharp-darwin-arm64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-arm64/-/sharp-darwin-arm64-0.33.5.tgz", - "integrity": "sha512-UT4p+iz/2H4twwAoLCqfA9UH5pI6DggwKEGuaPy7nCVQ8ZsiY5PIcrRvD1DzuY3qYL07NtIQcWnBSY/heikIFQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-arm64": "1.0.4" - } - }, - "node_modules/@img/sharp-darwin-x64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-darwin-x64/-/sharp-darwin-x64-0.33.5.tgz", - "integrity": "sha512-fyHac4jIc1ANYGRDxtiqelIbdWkIuQaI84Mv45KvGRRxSAa7o7d1ZKAOBaYbnepLC1WqxfpimdeWfvqqSGwR2Q==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-darwin-x64": "1.0.4" - } - }, - "node_modules/@img/sharp-libvips-darwin-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-arm64/-/sharp-libvips-darwin-arm64-1.0.4.tgz", - "integrity": "sha512-XblONe153h0O2zuFfTAbQYAX2JhYmDHeWikp1LM9Hul9gVPjFY427k6dFEcOL72O01QxQsWi761svJ/ev9xEDg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-darwin-x64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-darwin-x64/-/sharp-libvips-darwin-x64-1.0.4.tgz", - "integrity": "sha512-xnGR8YuZYfJGmWPvmlunFaWJsb9T/AO2ykoP3Fz/0X5XV2aoYBPkX6xqCQvUTKKiLddarLaxpzNe+b1hjeWHAQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm/-/sharp-libvips-linux-arm-1.0.5.tgz", - "integrity": "sha512-gvcC4ACAOPRNATg/ov8/MnbxFDJqf/pDePbBnuBDcjsI8PssmjoKMAz4LtLaVi+OnSb5FK/yIOamqDwGmXW32g==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-arm64/-/sharp-libvips-linux-arm64-1.0.4.tgz", - "integrity": "sha512-9B+taZ8DlyyqzZQnoeIvDVR/2F4EbMepXMc/NdVbkzsJbzkUjhXv/70GQJ7tdLA4YJgNP25zukcxpX2/SueNrA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-libvips-linux-s390x": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linux-s390x/-/sharp-libvips-linux-s390x-1.0.4.tgz", - "integrity": "sha512-u7Wz6ntiSSgGSGcjZ55im6uvTrOxSIS8/dgoVMoiGE9I6JAfU50yH5BoDlYA1tcuGS7g/QNtetJnxA6QEsCVTA==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } + "deprecated": "Use @eslint/object-schema instead", + "dev": true }, "node_modules/@img/sharp-libvips-linux-x64": { "version": "1.0.4", @@ -3150,21 +3048,6 @@ "url": "https://opencollective.com/libvips" } }, - "node_modules/@img/sharp-libvips-linuxmusl-arm64": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-arm64/-/sharp-libvips-linuxmusl-arm64-1.0.4.tgz", - "integrity": "sha512-9Ti+BbTYDcsbp4wfYib8Ctm1ilkugkA/uscUn6UXK1ldpC1JjiXbLfFZtRlBhjPZ5o1NCLiDbg8fhUPKStHoTA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "funding": { - "url": "https://opencollective.com/libvips" - } - }, "node_modules/@img/sharp-libvips-linuxmusl-x64": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/@img/sharp-libvips-linuxmusl-x64/-/sharp-libvips-linuxmusl-x64-1.0.4.tgz", @@ -3180,69 +3063,6 @@ "url": "https://opencollective.com/libvips" } }, - "node_modules/@img/sharp-linux-arm": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm/-/sharp-linux-arm-0.33.5.tgz", - "integrity": "sha512-JTS1eldqZbJxjvKaAkxhZmBqPRGmxgu+qFKSInv8moZ2AmT5Yib3EQ1c6gp493HvrvV8QgdOXdyaIBrhvFhBMQ==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm": "1.0.5" - } - }, - "node_modules/@img/sharp-linux-arm64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-arm64/-/sharp-linux-arm64-0.33.5.tgz", - "integrity": "sha512-JMVv+AMRyGOHtO1RFBiJy/MBsgz0x4AWrT6QoEVVTyh1E39TrCUpTRI7mx9VksGX4awWASxqCYLCV4wBZHAYxA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-arm64": "1.0.4" - } - }, - "node_modules/@img/sharp-linux-s390x": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linux-s390x/-/sharp-linux-s390x-0.33.5.tgz", - "integrity": "sha512-y/5PCd+mP4CA/sPDKl2961b+C9d+vPAveS33s6Z3zfASk2j5upL6fXVPZi7ztePZ5CuH+1kW8JtvxgbuXHRa4Q==", - "cpu": [ - "s390x" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linux-s390x": "1.0.4" - } - }, "node_modules/@img/sharp-linux-x64": { "version": "0.33.5", "resolved": "https://registry.npmjs.org/@img/sharp-linux-x64/-/sharp-linux-x64-0.33.5.tgz", @@ -3264,27 +3084,6 @@ "@img/sharp-libvips-linux-x64": "1.0.4" } }, - "node_modules/@img/sharp-linuxmusl-arm64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-arm64/-/sharp-linuxmusl-arm64-0.33.5.tgz", - "integrity": "sha512-XrHMZwGQGvJg2V/oRSUfSAfjfPxO+4DkiRh6p2AFjLQztWUuY/o8Mq0eMQVIY7HJ1CDQUJlxGGZRw1a5bqmd1g==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - }, - "optionalDependencies": { - "@img/sharp-libvips-linuxmusl-arm64": "1.0.4" - } - }, "node_modules/@img/sharp-linuxmusl-x64": { "version": "0.33.5", "resolved": "https://registry.npmjs.org/@img/sharp-linuxmusl-x64/-/sharp-linuxmusl-x64-0.33.5.tgz", @@ -3306,60 +3105,6 @@ "@img/sharp-libvips-linuxmusl-x64": "1.0.4" } }, - "node_modules/@img/sharp-wasm32": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-wasm32/-/sharp-wasm32-0.33.5.tgz", - "integrity": "sha512-ykUW4LVGaMcU9lu9thv85CbRMAwfeadCJHRsg2GmeRa/cJxsVY9Rbd57JcMxBkKHag5U/x7TSBpScF4U8ElVzg==", - "cpu": [ - "wasm32" - ], - "optional": true, - "dependencies": { - "@emnapi/runtime": "^1.2.0" - }, - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-ia32": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-ia32/-/sharp-win32-ia32-0.33.5.tgz", - "integrity": "sha512-T36PblLaTwuVJ/zw/LaH0PdZkRz5rd3SmMHX8GSmR7vtNSP5Z6bQkExdSK7xGWyxLw4sUknBuugTelgw2faBbQ==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, - "node_modules/@img/sharp-win32-x64": { - "version": "0.33.5", - "resolved": "https://registry.npmjs.org/@img/sharp-win32-x64/-/sharp-win32-x64-0.33.5.tgz", - "integrity": "sha512-MpY/o8/8kj+EcnxwvrP4aTJSWw/aZ7JIGR4aBeZkZw5B7/Jn+tY9/VNwtcoGmdT7GfggGIU4kygOMSbYnOrAbg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": "^18.17.0 || ^20.3.0 || >=21.0.0" - }, - "funding": { - "url": "https://opencollective.com/libvips" - } - }, "node_modules/@isaacs/cliui": { "version": "8.0.2", "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", @@ -3503,12 +3248,12 @@ } }, "node_modules/@layer5/meshery-design-embed": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@layer5/meshery-design-embed/-/meshery-design-embed-0.4.0.tgz", - "integrity": "sha512-3a8a/yYnZpcbDHw5nMD0pZgCg/MVzv9LqHaMd4Om2l5cX9NfjIzoR5ROn0JZvyvfmqHV6IzUEBPLAfDjwnfHRg==", + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/@layer5/meshery-design-embed/-/meshery-design-embed-0.2.0.tgz", + "integrity": "sha512-/MJBN3T96LCkOz7oLhlZ0VJJzBKfKzwTHEItXZtdUiZJQWkQsJ+AqhFuTceH74jdlvtVl+UplKWaDgJwqNGQWQ==", "peerDependencies": { - "react": ">=17.0.2", - "react-dom": ">=17.0.2" + "react": "^17.0.2", + "react-dom": "^17.0.2" } }, "node_modules/@layer5/sistent": { @@ -3581,78 +3326,18 @@ "@lezer/common": "^1.0.0" } }, - "node_modules/@lmdb/lmdb-darwin-arm64": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.5.3.tgz", - "integrity": "sha512-RXwGZ/0eCqtCY8FLTM/koR60w+MXyvBUpToXiIyjOcBnC81tAlTUHrRUavCEWPI9zc9VgvpK3+cbumPyR8BSuA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@lmdb/lmdb-darwin-x64": { + "node_modules/@lmdb/lmdb-linux-x64": { "version": "2.5.3", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.5.3.tgz", - "integrity": "sha512-337dNzh5yCdNCTk8kPfoU7jR3otibSlPDGW0vKZT97rKnQMb9tNdto3RtWoGPsQ8hKmlRZpojOJtmwjncq1MoA==", + "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.5.3.tgz", + "integrity": "sha512-qaReO5aV8griBDsBr8uBF/faO3ieGjY1RY4p8JvTL6Mu1ylLrTVvOONqKFlNaCwrmUjWw5jnf7VafxDAeQHTow==", "cpu": [ "x64" ], "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@lmdb/lmdb-linux-arm": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.5.3.tgz", - "integrity": "sha512-mU2HFJDGwECkoD9dHQEfeTG5mp8hNS2BCfwoiOpVPMeapjYpQz9Uw3FkUjRZ4dGHWKbin40oWHuL0bk2bCx+Sg==", - "cpu": [ - "arm" - ], - "optional": true, "os": [ "linux" ] }, - "node_modules/@lmdb/lmdb-linux-arm64": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.5.3.tgz", - "integrity": "sha512-VJw60Mdgb4n+L0fO1PqfB0C7TyEQolJAC8qpqvG3JoQwvyOv6LH7Ib/WE3wxEW9nuHmVz9jkK7lk5HfWWgoO1Q==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@lmdb/lmdb-linux-x64": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.5.3.tgz", - "integrity": "sha512-qaReO5aV8griBDsBr8uBF/faO3ieGjY1RY4p8JvTL6Mu1ylLrTVvOONqKFlNaCwrmUjWw5jnf7VafxDAeQHTow==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@lmdb/lmdb-win32-x64": { - "version": "2.5.3", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.5.3.tgz", - "integrity": "sha512-cK+Elf3RjEzrm3SerAhrFWL5oQAsZSJ/LmjL1joIpTfEP1etJJ9CTRvdaV6XLYAxaEkfdhk/9hOvHLbR9yIhCA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@loadable/babel-plugin": { "version": "5.16.1", "resolved": "https://registry.npmjs.org/@loadable/babel-plugin/-/babel-plugin-5.16.1.tgz", @@ -3743,105 +3428,57 @@ } }, "node_modules/@mdx-js/mdx": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-1.6.22.tgz", - "integrity": "sha512-AMxuLxPz2j5/6TpF/XSdKpQP1NlG0z11dFOlq+2IP/lSgl11GY8ji6S/rgsViN/L0BDvHvUMruRb7ub+24LUYA==", - "dependencies": { - "@babel/core": "7.12.9", - "@babel/plugin-syntax-jsx": "7.12.1", - "@babel/plugin-syntax-object-rest-spread": "7.8.3", - "@mdx-js/util": "1.6.22", - "babel-plugin-apply-mdx-type-prop": "1.6.22", - "babel-plugin-extract-import-names": "1.6.22", - "camelcase-css": "2.0.1", - "detab": "2.0.4", - "hast-util-raw": "6.0.1", - "lodash.uniq": "4.5.0", - "mdast-util-to-hast": "10.0.1", - "remark-footnotes": "2.0.0", - "remark-mdx": "1.6.22", - "remark-parse": "8.0.3", - "remark-squeeze-paragraphs": "4.0.0", - "style-to-object": "0.3.0", - "unified": "9.2.0", - "unist-builder": "2.0.3", - "unist-util-visit": "2.0.3" + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@mdx-js/mdx/-/mdx-2.3.0.tgz", + "integrity": "sha512-jLuwRlz8DQfQNiUCJR50Y09CGPq3fLtmtUQfVrj79E0JWu3dvsVcxVIcfhR5h0iXu+/z++zDrYeiJqifRynJkA==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/mdx": "^2.0.0", + "estree-util-build-jsx": "^2.0.0", + "estree-util-is-identifier-name": "^2.0.0", + "estree-util-to-js": "^1.1.0", + "estree-walker": "^3.0.0", + "hast-util-to-estree": "^2.0.0", + "markdown-extensions": "^1.0.0", + "periscopic": "^3.0.0", + "remark-mdx": "^2.0.0", + "remark-parse": "^10.0.0", + "remark-rehype": "^10.0.0", + "unified": "^10.0.0", + "unist-util-position-from-estree": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "unist-util-visit": "^4.0.0", + "vfile": "^5.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/@mdx-js/mdx/node_modules/@babel/core": { - "version": "7.12.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz", - "integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.5", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.5", - "@babel/parser": "^7.12.7", - "@babel/template": "^7.12.7", - "@babel/traverse": "^7.12.9", - "@babel/types": "^7.12.7", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.19", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "engines": { - "node": ">=6.9.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/babel" - } - }, - "node_modules/@mdx-js/mdx/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, - "node_modules/@mdx-js/mdx/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "bin": { - "semver": "bin/semver" + "node_modules/@mdx-js/mdx/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "^1.0.0" } }, "node_modules/@mdx-js/react": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-1.6.22.tgz", - "integrity": "sha512-TDoPum4SHdfPiGSAaRBw7ECyI8VaHpK8GJugbJIJuqyh6kzw9ZLJZW3HGL3NNrJGxcAixUvqROm+YuQOo5eXtg==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/@mdx-js/react/-/react-2.3.0.tgz", + "integrity": "sha512-zQH//gdOmuu7nt2oJR29vFhDv88oGPmVw6BggmrHeMI+xgEkp1B2dX9/bMBSYtK0dyLX/aOmesKS09g222K1/g==", + "dependencies": { + "@types/mdx": "^2.0.0", + "@types/react": ">=16" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" }, "peerDependencies": { - "react": "^16.13.1 || ^17.0.0" - } - }, - "node_modules/@mdx-js/util": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/@mdx-js/util/-/util-1.6.22.tgz", - "integrity": "sha512-H1rQc1ZOHANWBvPcW+JpGwr+juXSxM8Q8YCkm3GhZd8REu1fHR3z99CErO1p9pkcfcxZnMdIZdIsXkOHY0NilA==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "react": ">=16" } }, - "node_modules/@mediacurrent/gatsby-plugin-silence-css-order-warning": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@mediacurrent/gatsby-plugin-silence-css-order-warning/-/gatsby-plugin-silence-css-order-warning-1.0.0.tgz", - "integrity": "sha512-TiBIncOzH5JtjHxZ43D4KmsZcjaKaGtl4p9+9HbhdDSNC5DcS3KpIJWT0nS0qnSd2QlbDRx44XAkrl4GZpIwTA==", - "license": "MIT" - }, "node_modules/@mischnic/json-sourcemap": { "version": "0.1.1", "resolved": "https://registry.npmjs.org/@mischnic/json-sourcemap/-/json-sourcemap-0.1.1.tgz", @@ -3855,54 +3492,6 @@ "node": ">=12.0.0" } }, - "node_modules/@msgpackr-extract/msgpackr-extract-darwin-arm64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-arm64/-/msgpackr-extract-darwin-arm64-3.0.3.tgz", - "integrity": "sha512-QZHtlVgbAdy2zAqNA9Gu1UpIuI8Xvsd1v8ic6B2pZmeFnFcMWiPLfWXh7TVw4eGEZ/C9TH281KwhVoeQUKbyjw==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@msgpackr-extract/msgpackr-extract-darwin-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-darwin-x64/-/msgpackr-extract-darwin-x64-3.0.3.tgz", - "integrity": "sha512-mdzd3AVzYKuUmiWOQ8GNhl64/IoFGol569zNRdkLReh6LRLHOXxU4U8eq0JwaD8iFHdVGqSy4IjFL4reoWCDFw==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm/-/msgpackr-extract-linux-arm-3.0.3.tgz", - "integrity": "sha512-fg0uy/dG/nZEXfYilKoRe7yALaNmHoYeIoJuJ7KJ+YyU2bvY8vPv27f7UKhGRpY6euFYqEVhxCFZgAUNQBM3nw==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@msgpackr-extract/msgpackr-extract-linux-arm64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-arm64/-/msgpackr-extract-linux-arm64-3.0.3.tgz", - "integrity": "sha512-YxQL+ax0XqBJDZiKimS2XQaf+2wDGVa1enVRGzEvLLVFeqa5kx2bWbtcSXgsxjQB7nRqqIGFIcLteF/sHeVtQg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] - }, "node_modules/@msgpackr-extract/msgpackr-extract-linux-x64": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-linux-x64/-/msgpackr-extract-linux-x64-3.0.3.tgz", @@ -3915,18 +3504,6 @@ "linux" ] }, - "node_modules/@msgpackr-extract/msgpackr-extract-win32-x64": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/@msgpackr-extract/msgpackr-extract-win32-x64/-/msgpackr-extract-win32-x64-3.0.3.tgz", - "integrity": "sha512-x0fWaQtYp4E6sktbsdAqnehxDgEc/VwM7uLsRCYWaiGu0ykYdZPiS8zCWdnjHwyiumousxfBm4SO31eXqwEZhQ==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@mui/core-downloads-tracker": { "version": "5.16.7", "resolved": "https://registry.npmjs.org/@mui/core-downloads-tracker/-/core-downloads-tracker-5.16.7.tgz", @@ -3936,31 +3513,6 @@ "url": "https://opencollective.com/mui-org" } }, - "node_modules/@mui/icons-material": { - "version": "5.16.7", - "resolved": "https://registry.npmjs.org/@mui/icons-material/-/icons-material-5.16.7.tgz", - "integrity": "sha512-UrGwDJCXEszbDI7yV047BYU5A28eGJ79keTCP4cc74WyncuVrnurlmIRxaHL8YK+LI1Kzq+/JM52IAkNnv4u+Q==", - "dependencies": { - "@babel/runtime": "^7.23.9" - }, - "engines": { - "node": ">=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/mui-org" - }, - "peerDependencies": { - "@mui/material": "^5.0.0", - "@types/react": "^17.0.0 || ^18.0.0", - "react": "^17.0.0 || ^18.0.0" - }, - "peerDependenciesMeta": { - "@types/react": { - "optional": true - } - } - }, "node_modules/@mui/material": { "version": "5.16.7", "resolved": "https://registry.npmjs.org/@mui/material/-/material-5.16.7.tgz", @@ -4200,6 +3752,138 @@ "node": ">= 8" } }, + "node_modules/@npmcli/config": { + "version": "6.4.1", + "resolved": "https://registry.npmjs.org/@npmcli/config/-/config-6.4.1.tgz", + "integrity": "sha512-uSz+elSGzjCMANWa5IlbGczLYPkNI/LeR+cHrgaTqTrTSh9RHhOFA4daD2eRUz6lMtOW+Fnsb+qv7V2Zz8ML0g==", + "dev": true, + "dependencies": { + "@npmcli/map-workspaces": "^3.0.2", + "ci-info": "^4.0.0", + "ini": "^4.1.0", + "nopt": "^7.0.0", + "proc-log": "^3.0.0", + "read-package-json-fast": "^3.0.2", + "semver": "^7.3.5", + "walk-up-path": "^3.0.1" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/config/node_modules/ci-info": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-4.1.0.tgz", + "integrity": "sha512-HutrvTNsF48wnxkzERIXOe5/mlcfFcbfCmwcg6CJnizbSue78AbDt+1cgl26zwn61WFxhcPykPfZrbqjGmBb4A==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/sibiraj-s" + } + ], + "engines": { + "node": ">=8" + } + }, + "node_modules/@npmcli/config/node_modules/ini": { + "version": "4.1.3", + "resolved": "https://registry.npmjs.org/ini/-/ini-4.1.3.tgz", + "integrity": "sha512-X7rqawQBvfdjS10YU1y1YVreA3SsLrW9dX2CewP2EbBJM4ypVNLDkO5y04gejPwKIY9lR+7r9gn3rFPt/kmWFg==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/config/node_modules/semver": { + "version": "7.6.3", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", + "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@npmcli/map-workspaces": { + "version": "3.0.6", + "resolved": "https://registry.npmjs.org/@npmcli/map-workspaces/-/map-workspaces-3.0.6.tgz", + "integrity": "sha512-tkYs0OYnzQm6iIRdfy+LcLBjcKuQCeE5YLb8KnrIlutJfheNaPvPpgoFEyEFgbjzl5PLZ3IA/BWAwRU0eHuQDA==", + "dev": true, + "dependencies": { + "@npmcli/name-from-folder": "^2.0.0", + "glob": "^10.2.2", + "minimatch": "^9.0.0", + "read-package-json-fast": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/@npmcli/map-workspaces/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/@npmcli/map-workspaces/node_modules/glob": { + "version": "10.4.5", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.4.5.tgz", + "integrity": "sha512-7Bv8RF0k6xjo7d4A/PxYLbUCfb6c+Vpd2/mB2yRDlew7Jb5hEXiCD9ibfO7wpk8i4sevK6DFny9h7EYbM3/sHg==", + "dev": true, + "dependencies": { + "foreground-child": "^3.1.0", + "jackspeak": "^3.1.2", + "minimatch": "^9.0.4", + "minipass": "^7.1.2", + "package-json-from-dist": "^1.0.0", + "path-scurry": "^1.11.1" + }, + "bin": { + "glob": "dist/esm/bin.mjs" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/map-workspaces/node_modules/minimatch": { + "version": "9.0.5", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.5.tgz", + "integrity": "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=16 || 14 >=14.17" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/@npmcli/map-workspaces/node_modules/minipass": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.1.2.tgz", + "integrity": "sha512-qOOzS1cBTWYF4BH8fVePDBOO9iptMnGUEZwNc/cMWnTV2nVLZ7VoNWEPHkYczZA0pdoA7dl6e7FL659nX9S2aw==", + "dev": true, + "engines": { + "node": ">=16 || 14 >=14.17" + } + }, + "node_modules/@npmcli/name-from-folder": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/@npmcli/name-from-folder/-/name-from-folder-2.0.0.tgz", + "integrity": "sha512-pwK+BfEBZJbKdNYpHHRTNBwBoqrN/iIMO0AiGvYsp3Hoaq0WbgGSWQR6SCldZovoDpY3yje5lkFUe6gsDgJ2vg==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/@parcel/bundler-default": { "version": "2.8.3", "resolved": "https://registry.npmjs.org/@parcel/bundler-default/-/bundler-default-2.8.3.tgz", @@ -4242,54 +3926,6 @@ "@parcel/core": "^2.8.3" } }, - "node_modules/@parcel/cache/node_modules/@lmdb/lmdb-darwin-arm64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-arm64/-/lmdb-darwin-arm64-2.5.2.tgz", - "integrity": "sha512-+F8ioQIUN68B4UFiIBYu0QQvgb9FmlKw2ctQMSBfW2QBrZIxz9vD9jCGqTCPqZBRbPHAS/vG1zSXnKqnS2ch/A==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@parcel/cache/node_modules/@lmdb/lmdb-darwin-x64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-darwin-x64/-/lmdb-darwin-x64-2.5.2.tgz", - "integrity": "sha512-KvPH56KRLLx4KSfKBx0m1r7GGGUMXm0jrKmNE7plbHlesZMuPJICtn07HYgQhj1LNsK7Yqwuvnqh1QxhJnF1EA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ] - }, - "node_modules/@parcel/cache/node_modules/@lmdb/lmdb-linux-arm": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm/-/lmdb-linux-arm-2.5.2.tgz", - "integrity": "sha512-5kQAP21hAkfW5Bl+e0P57dV4dGYnkNIpR7f/GAh6QHlgXx+vp/teVj4PGRZaKAvt0GX6++N6hF8NnGElLDuIDw==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ] - }, - "node_modules/@parcel/cache/node_modules/@lmdb/lmdb-linux-arm64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-arm64/-/lmdb-linux-arm64-2.5.2.tgz", - "integrity": "sha512-aLl89VHL/wjhievEOlPocoefUyWdvzVrcQ/MHQYZm2JfV1jUsrbr/ZfkPPUFvZBf+VSE+Q0clWs9l29PCX1hTQ==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ] - }, "node_modules/@parcel/cache/node_modules/@lmdb/lmdb-linux-x64": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/@lmdb/lmdb-linux-x64/-/lmdb-linux-x64-2.5.2.tgz", @@ -4302,18 +3938,6 @@ "linux" ] }, - "node_modules/@parcel/cache/node_modules/@lmdb/lmdb-win32-x64": { - "version": "2.5.2", - "resolved": "https://registry.npmjs.org/@lmdb/lmdb-win32-x64/-/lmdb-win32-x64-2.5.2.tgz", - "integrity": "sha512-zrBczSbXKxEyK2ijtbRdICDygRqWSRPpZMN5dD1T8VMEW5RIhIbwFWw2phDRXuBQdVDpSjalCIUMWMV2h3JaZA==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ] - }, "node_modules/@parcel/cache/node_modules/lmdb": { "version": "2.5.2", "resolved": "https://registry.npmjs.org/lmdb/-/lmdb-2.5.2.tgz", @@ -5097,149 +4721,16 @@ "@parcel/watcher-win32-x64": "2.4.1" } }, - "node_modules/@parcel/watcher-android-arm64": { + "node_modules/@parcel/watcher-linux-x64-glibc": { "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-android-arm64/-/watcher-android-arm64-2.4.1.tgz", - "integrity": "sha512-LOi/WTbbh3aTn2RYddrO8pnapixAziFl6SMxHM69r3tvdSm94JtCenaKgk1GRg5FJ5wpMCpHeW+7yqPlvZv7kg==", + "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.4.1.tgz", + "integrity": "sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==", "cpu": [ - "arm64" + "x64" ], "optional": true, "os": [ - "android" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-arm64/-/watcher-darwin-arm64-2.4.1.tgz", - "integrity": "sha512-ln41eihm5YXIY043vBrrHfn94SIBlqOWmoROhsMVTSXGh0QahKGy77tfEywQ7v3NywyxBBkGIfrWRHm0hsKtzA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-darwin-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-darwin-x64/-/watcher-darwin-x64-2.4.1.tgz", - "integrity": "sha512-yrw81BRLjjtHyDu7J61oPuSoeYWR3lDElcPGJyOvIXmor6DEo7/G2u1o7I38cwlcoBHQFULqF6nesIX3tsEXMg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-freebsd-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-freebsd-x64/-/watcher-freebsd-x64-2.4.1.tgz", - "integrity": "sha512-TJa3Pex/gX3CWIx/Co8k+ykNdDCLx+TuZj3f3h7eOjgpdKM+Mnix37RYsYU4LHhiYJz3DK5nFCCra81p6g050w==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "freebsd" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm-glibc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm-glibc/-/watcher-linux-arm-glibc-2.4.1.tgz", - "integrity": "sha512-4rVYDlsMEYfa537BRXxJ5UF4ddNwnr2/1O4MHM5PjI9cvV2qymvhwZSFgXqbS8YoTk5i/JR0L0JDs69BUn45YA==", - "cpu": [ - "arm" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-glibc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-glibc/-/watcher-linux-arm64-glibc-2.4.1.tgz", - "integrity": "sha512-BJ7mH985OADVLpbrzCLgrJ3TOpiZggE9FMblfO65PlOCdG++xJpKUJ0Aol74ZUIYfb8WsRlUdgrZxKkz3zXWYA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-arm64-musl": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-arm64-musl/-/watcher-linux-arm64-musl-2.4.1.tgz", - "integrity": "sha512-p4Xb7JGq3MLgAfYhslU2SjoV9G0kI0Xry0kuxeG/41UfpjHGOhv7UoUDAz/jb1u2elbhazy4rRBL8PegPJFBhA==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "linux" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-linux-x64-glibc": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-linux-x64-glibc/-/watcher-linux-x64-glibc-2.4.1.tgz", - "integrity": "sha512-s9O3fByZ/2pyYDPoLM6zt92yu6P4E39a03zvO0qCHOTjxmt3GHRMLuRZEWhWLASTMSrrnVNWdVI/+pUElJBBBg==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "linux" + "linux" ], "engines": { "node": ">= 10.0.0" @@ -5268,63 +4759,6 @@ "url": "https://opencollective.com/parcel" } }, - "node_modules/@parcel/watcher-win32-arm64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-arm64/-/watcher-win32-arm64-2.4.1.tgz", - "integrity": "sha512-Uq2BPp5GWhrq/lcuItCHoqxjULU1QYEcyjSO5jqqOK8RNFDBQnenMMx4gAl3v8GiWa59E9+uDM7yZ6LxwUIfRg==", - "cpu": [ - "arm64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-ia32": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-ia32/-/watcher-win32-ia32-2.4.1.tgz", - "integrity": "sha512-maNRit5QQV2kgHFSYwftmPBxiuK5u4DXjbXx7q6eKjq5dsLXZ4FJiVvlcw35QXzk0KrUecJmuVFbj4uV9oYrcw==", - "cpu": [ - "ia32" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, - "node_modules/@parcel/watcher-win32-x64": { - "version": "2.4.1", - "resolved": "https://registry.npmjs.org/@parcel/watcher-win32-x64/-/watcher-win32-x64-2.4.1.tgz", - "integrity": "sha512-+DvS92F9ezicfswqrvIRM2njcYJbd5mb9CUgtrHCHmvn7pPPa+nMDRu1o1bYYz/l5IB2NVGNJWiH7h1E58IF2A==", - "cpu": [ - "x64" - ], - "optional": true, - "os": [ - "win32" - ], - "engines": { - "node": ">= 10.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/parcel" - } - }, "node_modules/@parcel/workers": { "version": "2.8.3", "resolved": "https://registry.npmjs.org/@parcel/workers/-/workers-2.8.3.tgz", @@ -5358,6 +4792,18 @@ "node": ">=14" } }, + "node_modules/@pkgr/core": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@pkgr/core/-/core-0.1.1.tgz", + "integrity": "sha512-cq8o4cWH0ibXh9VGi5P20Tu9XF/0fFXl9EUinr9QfTM7a7p0oTA4iJRCQWppXR1Pg8dSM0UCItCkPwsk9qWWYA==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.15", "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.15.tgz", @@ -5869,6 +5315,14 @@ "resolved": "https://registry.npmjs.org/@turist/time/-/time-0.0.2.tgz", "integrity": "sha512-qLOvfmlG2vCVw5fo/oz8WAZYlpe5a5OurgTj3diIxJCdjRHpapC+vQCz3er9LV79Vcat+DifBjeAhOAdmndtDQ==" }, + "node_modules/@types/acorn": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@types/acorn/-/acorn-4.0.6.tgz", + "integrity": "sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==", + "dependencies": { + "@types/estree": "*" + } + }, "node_modules/@types/cacheable-request": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", @@ -5885,6 +5339,15 @@ "resolved": "https://registry.npmjs.org/@types/common-tags/-/common-tags-1.8.4.tgz", "integrity": "sha512-S+1hLDJPjWNDhcGxsxEbepzaxWqURP/o+3cP4aa2w7yBXgdcmKGQtZzP8JbyfOd0m+33nh+8+kvxYE2UJtBDkg==" }, + "node_modules/@types/concat-stream": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/@types/concat-stream/-/concat-stream-2.0.3.tgz", + "integrity": "sha512-3qe4oQAPNwVNwK4C9c8u+VJqv9kez+2MR4qJpoPFfXtgxxif1QbFusvXzK0/Wra2VX07smostI2VMmJNSpZjuQ==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/configstore": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/@types/configstore/-/configstore-2.1.1.tgz", @@ -5922,6 +5385,19 @@ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.6.tgz", "integrity": "sha512-AYnb1nQyY49te+VRAVgmzfcgjYS91mY5P0TKUDCLEM+gNnA+3T6rWITXRLYCpahpqSQbN5cE+gHpnPyXjHWxcw==" }, + "node_modules/@types/estree-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/@types/estree-jsx/-/estree-jsx-1.0.5.tgz", + "integrity": "sha512-52CcUVNFyfb1A2ALocQw/Dd1BQFNmSdkuC3BkZ6iqhdMfQz7JWOFRuJFloOzjk+6WijU56m9oKXFAXc7o3Towg==", + "dependencies": { + "@types/estree": "*" + } + }, + "node_modules/@types/extend": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/@types/extend/-/extend-3.0.4.tgz", + "integrity": "sha512-ArMouDUTJEz1SQRpFsT2rIw7DeqICFv5aaVzLSIYMYQSLcwcGOfT3VyglQs/p7K3F7fT4zxr0NWxYZIdifD6dA==" + }, "node_modules/@types/get-port": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/@types/get-port/-/get-port-3.2.0.tgz", @@ -5966,6 +5442,12 @@ "@types/node": "*" } }, + "node_modules/@types/is-empty": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/@types/is-empty/-/is-empty-1.2.3.tgz", + "integrity": "sha512-4J1l5d79hoIvsrKh5VUKVRA1aIdsOb10Hu5j3J2VfP/msDnfTdGPmNp2E1Wg+vs97Bktzo+MZePFFXSGoykYJw==", + "dev": true + }, "node_modules/@types/js-cookie": { "version": "2.2.7", "resolved": "https://registry.npmjs.org/@types/js-cookie/-/js-cookie-2.2.7.tgz", @@ -6002,6 +5484,11 @@ "@types/unist": "^2" } }, + "node_modules/@types/mdx": { + "version": "2.0.13", + "resolved": "https://registry.npmjs.org/@types/mdx/-/mdx-2.0.13.tgz", + "integrity": "sha512-+OWZQfAYyio6YkJb3HLxDrvnx6SWWDbC0zVPfBRzUk0/nqoDyf6dNxQi3eArPe8rJ473nobTMQ/8Zk+LxJ+Yuw==" + }, "node_modules/@types/minimatch": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-5.1.2.tgz", @@ -6020,6 +5507,11 @@ "@types/node": "*" } }, + "node_modules/@types/ms": { + "version": "0.7.34", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-0.7.34.tgz", + "integrity": "sha512-nG96G3Wp6acyAgJqGasjODb+acrI7KltPiRxzHPXnP3NgI28bpQDRv53olbqGXbfcgF5aiiHmO3xpwEpS5Ld9g==" + }, "node_modules/@types/mui-datatables": { "version": "4.3.12", "resolved": "https://registry.npmjs.org/@types/mui-datatables/-/mui-datatables-4.3.12.tgz", @@ -6065,9 +5557,9 @@ "integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==" }, "node_modules/@types/parse5": { - "version": "5.0.3", - "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-5.0.3.tgz", - "integrity": "sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==" + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/parse5/-/parse5-6.0.3.tgz", + "integrity": "sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==" }, "node_modules/@types/prismjs": { "version": "1.26.4", @@ -6139,6 +5631,12 @@ "resolved": "https://registry.npmjs.org/@types/stylis/-/stylis-4.2.5.tgz", "integrity": "sha512-1Xve+NMN7FWjY14vLoY5tL3BVEQ/n42YLwaqJIPYhotZ9uBHt87VceMwWQpzmdEt2TNXIorIFG+YeCUUW7RInw==" }, + "node_modules/@types/supports-color": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/@types/supports-color/-/supports-color-8.1.3.tgz", + "integrity": "sha512-Hy6UMpxhE3j1tLpl27exp1XqHD7n8chAiNPzWfz16LPZoMMoSc4dzLl6w9qijkEb/r5O1ozdu1CWGA2L83ZeZg==", + "dev": true + }, "node_modules/@types/tmp": { "version": "0.0.33", "resolved": "https://registry.npmjs.org/@types/tmp/-/tmp-0.0.33.tgz", @@ -6149,25 +5647,6 @@ "resolved": "https://registry.npmjs.org/@types/unist/-/unist-2.0.11.tgz", "integrity": "sha512-CmBKiL6NNo/OqgmMn95Fk9Whlp2mtvIv+KNpQKN2F4SjvrEesubTRWGYSg+BnWZOnlCaSTU1sMpsBOzgbYhnsA==" }, - "node_modules/@types/vfile": { - "version": "3.0.2", - "resolved": "https://registry.npmjs.org/@types/vfile/-/vfile-3.0.2.tgz", - "integrity": "sha512-b3nLFGaGkJ9rzOcuXRfHkZMdjsawuDD0ENL9fzTophtBg8FJHSGbH7daXkEpcwy3v7Xol3pAvsmlYyFhR4pqJw==", - "dependencies": { - "@types/node": "*", - "@types/unist": "*", - "@types/vfile-message": "*" - } - }, - "node_modules/@types/vfile-message": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/@types/vfile-message/-/vfile-message-2.0.0.tgz", - "integrity": "sha512-GpTIuDpb9u4zIO165fUy9+fXcULdD8HFRNli04GehoMVbeNq7D6OBnqSmg3lxZnC+UvgUhEWKxdKiwYUkGltIw==", - "deprecated": "This is a stub types definition. vfile-message provides its own type definitions, so you do not need this installed.", - "dependencies": { - "vfile-message": "*" - } - }, "node_modules/@types/yauzl": { "version": "2.10.3", "resolved": "https://registry.npmjs.org/@types/yauzl/-/yauzl-2.10.3.tgz", @@ -6182,31 +5661,25 @@ "resolved": "https://registry.npmjs.org/@types/yoga-layout/-/yoga-layout-1.9.2.tgz", "integrity": "sha512-S9q47ByT2pPvD65IvrWp7qppVMpk9WGMbVq9wbWZOHg6tnXSD4vyhao6nOSBwwfDdV2p3Kx9evA9vI+XWTfDvw==" }, - "node_modules/@typescript-eslint/eslint-plugin": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/eslint-plugin/-/eslint-plugin-4.33.0.tgz", - "integrity": "sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==", - "peer": true, + "node_modules/@typescript-eslint/type-utils": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", + "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", "dependencies": { - "@typescript-eslint/experimental-utils": "4.33.0", - "@typescript-eslint/scope-manager": "4.33.0", - "debug": "^4.3.1", - "functional-red-black-tree": "^1.0.1", - "ignore": "^5.1.8", - "regexpp": "^3.1.0", - "semver": "^7.3.5", + "@typescript-eslint/typescript-estree": "5.62.0", + "@typescript-eslint/utils": "5.62.0", + "debug": "^4.3.4", "tsutils": "^3.21.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" }, "peerDependencies": { - "@typescript-eslint/parser": "^4.0.0", - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" + "eslint": "*" }, "peerDependenciesMeta": { "typescript": { @@ -6214,157 +5687,33 @@ } } }, - "node_modules/@typescript-eslint/eslint-plugin/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "peer": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/@typescript-eslint/experimental-utils": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/experimental-utils/-/experimental-utils-4.33.0.tgz", - "integrity": "sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==", - "peer": true, - "dependencies": { - "@types/json-schema": "^7.0.7", - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "eslint-scope": "^5.1.1", - "eslint-utils": "^3.0.0" - }, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", + "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", "engines": { - "node": "^10.12.0 || >=12.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - } - }, - "node_modules/@typescript-eslint/experimental-utils/node_modules/eslint-utils": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-3.0.0.tgz", - "integrity": "sha512-uuQC43IGctw68pJA1RgbQS8/NP7rch6Cwd4j3ZBtgo4/8Flj4eGE7ZYSZRN3iq5pVUv6GPdW5Z1RFleo84uLDA==", - "peer": true, - "dependencies": { - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^10.0.0 || ^12.0.0 || >= 14.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/mysticatea" - }, - "peerDependencies": { - "eslint": ">=5" } }, - "node_modules/@typescript-eslint/parser": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/parser/-/parser-4.33.0.tgz", - "integrity": "sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==", - "peer": true, + "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { + "version": "5.62.0", + "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", + "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", "dependencies": { - "@typescript-eslint/scope-manager": "4.33.0", - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/typescript-estree": "4.33.0", - "debug": "^4.3.1" + "@typescript-eslint/types": "5.62.0", + "@typescript-eslint/visitor-keys": "5.62.0", + "debug": "^4.3.4", + "globby": "^11.1.0", + "is-glob": "^4.0.3", + "semver": "^7.3.7", + "tsutils": "^3.21.0" }, "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "^5.0.0 || ^6.0.0 || ^7.0.0" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/scope-manager": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/scope-manager/-/scope-manager-4.33.0.tgz", - "integrity": "sha512-5IfJHpgTsTZuONKbODctL4kKuQje/bzBRkwHE8UOZ4f89Zeddg+EGZs8PD8NcN4LdM3ygHWYB3ukPAYjvl/qbQ==", - "peer": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/type-utils/-/type-utils-5.62.0.tgz", - "integrity": "sha512-xsSQreu+VnfbqQpW5vnCJdq1Z3Q0U31qiWmRhr98ONQmcp/yhiPJFPq8MXiJVLiksmOKSjIldZzkebzHuCGzew==", - "dependencies": { - "@typescript-eslint/typescript-estree": "5.62.0", - "@typescript-eslint/utils": "5.62.0", - "debug": "^4.3.4", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependencies": { - "eslint": "*" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/types": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-5.62.0.tgz", - "integrity": "sha512-87NVngcbVXUahrRTqIK27gD2t5Cu1yuCXxbLcFtCzZGlfyVWWh8mLHkoxzjsB6DDNnvdL+fW8MiwPEJyGJQDgQ==", - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/type-utils/node_modules/@typescript-eslint/typescript-estree": { - "version": "5.62.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-5.62.0.tgz", - "integrity": "sha512-CmcQ6uY7b9y694lKdRB8FEel7JbU/40iSAPomu++SjLMntB+2Leay2LO6i8VnJk58MtE9/nQSFIH6jpyRWyYzA==", - "dependencies": { - "@typescript-eslint/types": "5.62.0", - "@typescript-eslint/visitor-keys": "5.62.0", - "debug": "^4.3.4", - "globby": "^11.1.0", - "is-glob": "^4.0.3", - "semver": "^7.3.7", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, "funding": { "type": "opencollective", @@ -6414,58 +5763,6 @@ "node": ">=10" } }, - "node_modules/@typescript-eslint/types": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/types/-/types-4.33.0.tgz", - "integrity": "sha512-zKp7CjQzLQImXEpLt2BUw1tvOMPfNoTAfb8l51evhYbOEEzdWyQNmHWWGPR6hwKJDAi+1VXSBmnhL9kyVTTOuQ==", - "peer": true, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, - "node_modules/@typescript-eslint/typescript-estree": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/typescript-estree/-/typescript-estree-4.33.0.tgz", - "integrity": "sha512-rkWRY1MPFzjwnEVHsxGemDzqqddw2QbTJlICPD9p9I9LfsO8fdmfQPOX3uKfUaGRDFJbfrtm/sXhVXN4E+bzCA==", - "peer": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "@typescript-eslint/visitor-keys": "4.33.0", - "debug": "^4.3.1", - "globby": "^11.0.3", - "is-glob": "^4.0.1", - "semver": "^7.3.5", - "tsutils": "^3.21.0" - }, - "engines": { - "node": "^10.12.0 || >=12.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - }, - "peerDependenciesMeta": { - "typescript": { - "optional": true - } - } - }, - "node_modules/@typescript-eslint/typescript-estree/node_modules/semver": { - "version": "7.6.3", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.6.3.tgz", - "integrity": "sha512-oVekP1cKtI+CTDvHWYFUcMtsK/00wmAEfyqKfNdARm8u1wNVhSgaX7A8d4UuIlUI5e84iEwOhs7ZPYRmzU9U6A==", - "peer": true, - "bin": { - "semver": "bin/semver.js" - }, - "engines": { - "node": ">=10" - } - }, "node_modules/@typescript-eslint/utils": { "version": "5.62.0", "resolved": "https://registry.npmjs.org/@typescript-eslint/utils/-/utils-5.62.0.tgz", @@ -6583,27 +5880,11 @@ "node": ">=10" } }, - "node_modules/@typescript-eslint/visitor-keys": { - "version": "4.33.0", - "resolved": "https://registry.npmjs.org/@typescript-eslint/visitor-keys/-/visitor-keys-4.33.0.tgz", - "integrity": "sha512-uqi/2aSz9g2ftcHWf8uLPJA70rUv6yuMW5Bohw+bwcuzaxQIHaKFZCKGoGXIrc9vkTJ3+0txM73K0Hq3d5wgIg==", - "peer": true, - "dependencies": { - "@typescript-eslint/types": "4.33.0", - "eslint-visitor-keys": "^2.0.0" - }, - "engines": { - "node": "^8.10.0 || ^10.13.0 || >=11.10.1" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/typescript-eslint" - } - }, "node_modules/@ungap/structured-clone": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@ungap/structured-clone/-/structured-clone-1.2.0.tgz", - "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==" + "integrity": "sha512-zuVdFrMJiuCDQUMCzQaD6KL28MjnqqN8XnAqiEq9PNm/hCPTSGfrXCOfwj1ow4LFb/tNymJPwsNbVePc1xFqrQ==", + "dev": true }, "node_modules/@vercel/webpack-asset-relocator-loader": { "version": "1.7.3", @@ -6793,25 +6074,6 @@ "resolved": "https://registry.npmjs.org/@xobotyi/scrollbar-width/-/scrollbar-width-1.9.5.tgz", "integrity": "sha512-N8tkAACJx2ww8vFMneJmaAgmjAG1tnVBZJRLRcx061tmsLRZHSEZSLuGWnwPtunsSLvSqXQ2wfp7Mgqg1I+2dQ==" }, - "node_modules/@xstate/react": { - "version": "4.1.3", - "resolved": "https://registry.npmjs.org/@xstate/react/-/react-4.1.3.tgz", - "integrity": "sha512-zhE+ZfrcCR87bu71Rkh5Z5ruZBivR/7uD/dkelzJqjQdI45IZc9DqTI8lL4Cg5+VN2p5k86KxDsusqW1kW11Tg==", - "peer": true, - "dependencies": { - "use-isomorphic-layout-effect": "^1.1.2", - "use-sync-external-store": "^1.2.0" - }, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0", - "xstate": "^5.18.2" - }, - "peerDependenciesMeta": { - "xstate": { - "optional": true - } - } - }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz", @@ -6822,6 +6084,15 @@ "resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz", "integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==" }, + "node_modules/abbrev": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/abbrev/-/abbrev-2.0.0.tgz", + "integrity": "sha512-6/mh1E2u2YgEsCHdY0Yx5oW+61gZU+1vXaoiHHrpKeuRNNgFvS+/jrwHiQhB5apAf5oB7UB7E19ol2R2LKH8hQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/abortcontroller-polyfill": { "version": "1.7.5", "resolved": "https://registry.npmjs.org/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.5.tgz", @@ -7147,15 +6418,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/array-iterate": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/array-iterate/-/array-iterate-1.1.4.tgz", - "integrity": "sha512-sNRaPGh9nnmdC8Zf+pT3UqP8rnWj5Hf9wiFGsX3wUQ2yVSIhO2ShFwCoceIPpB41QF6i2OEmrHmCo36xronCVA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -7324,6 +6586,14 @@ "node": ">=8" } }, + "node_modules/astring": { + "version": "1.9.0", + "resolved": "https://registry.npmjs.org/astring/-/astring-1.9.0.tgz", + "integrity": "sha512-LElXdjswlqjWrPpJFg1Fx4wpkOCxj1TDHlSV4PlaRxHGWko024xICaa97ZkMfs6DRKlCguiAI+rbXv5GWwXIkg==", + "bin": { + "astring": "bin/astring" + } + }, "node_modules/async": { "version": "1.5.2", "resolved": "https://registry.npmjs.org/async/-/async-1.5.2.tgz", @@ -7458,36 +6728,6 @@ "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.7.tgz", "integrity": "sha512-OnAYlL5b7LEkALw87fUVafQw5rVR9RjwGd4KUwNQ6DrrNmaVaUCgLipfVlzrPQ4tWOR9P0IXGNOx50jYCCdSJg==" }, - "node_modules/babel-eslint": { - "version": "10.1.0", - "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", - "integrity": "sha512-ifWaTHQ0ce+448CYop8AdrQiBsGrnC+bMgfyKFdi6EsPLTAWG+QfyDeM6OH+FmWnKvEq5NnBMLvlBUPKQZoDSg==", - "deprecated": "babel-eslint is now @babel/eslint-parser. This package will no longer receive updates.", - "peer": true, - "dependencies": { - "@babel/code-frame": "^7.0.0", - "@babel/parser": "^7.7.0", - "@babel/traverse": "^7.7.0", - "@babel/types": "^7.7.0", - "eslint-visitor-keys": "^1.0.0", - "resolve": "^1.12.0" - }, - "engines": { - "node": ">=6" - }, - "peerDependencies": { - "eslint": ">= 4.12.1" - } - }, - "node_modules/babel-eslint/node_modules/eslint-visitor-keys": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.3.0.tgz", - "integrity": "sha512-6J72N8UNa462wa/KFODt/PJ3IU60SDpC3QXC1Hjc1BXXpfL2C9R5+AU7jhe0F6GREqVMh4Juu+NY7xn+6dipUQ==", - "peer": true, - "engines": { - "node": ">=4" - } - }, "node_modules/babel-jsx-utils": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/babel-jsx-utils/-/babel-jsx-utils-1.1.0.tgz", @@ -7575,27 +6815,6 @@ "resolved": "https://registry.npmjs.org/babel-plugin-add-module-exports/-/babel-plugin-add-module-exports-1.0.4.tgz", "integrity": "sha512-g+8yxHUZ60RcyaUpfNzy56OtWW+x9cyEe9j+CranqLiqbju2yf/Cy6ZtYK40EZxtrdHllzlVZgLmcOUCTlJ7Jg==" }, - "node_modules/babel-plugin-apply-mdx-type-prop": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/babel-plugin-apply-mdx-type-prop/-/babel-plugin-apply-mdx-type-prop-1.6.22.tgz", - "integrity": "sha512-VefL+8o+F/DfK24lPZMtJctrCVOfgbqLAGZSkxwhazQv4VxPg3Za/i40fu22KR2m8eEda+IfSOlPLUSIiLcnCQ==", - "dependencies": { - "@babel/helper-plugin-utils": "7.10.4", - "@mdx-js/util": "1.6.22" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - }, - "peerDependencies": { - "@babel/core": "^7.11.6" - } - }, - "node_modules/babel-plugin-apply-mdx-type-prop/node_modules/@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" - }, "node_modules/babel-plugin-dynamic-import-node": { "version": "2.3.3", "resolved": "https://registry.npmjs.org/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz", @@ -7604,23 +6823,6 @@ "object.assign": "^4.1.0" } }, - "node_modules/babel-plugin-extract-import-names": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/babel-plugin-extract-import-names/-/babel-plugin-extract-import-names-1.6.22.tgz", - "integrity": "sha512-yJ9BsJaISua7d8zNT7oRG1ZLBJCIdZ4PZqmH8qa9N5AK01ifk3fnkc98AXhtzE7UkfCsEumvoQWgoYLhOnJ7jQ==", - "dependencies": { - "@babel/helper-plugin-utils": "7.10.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/babel-plugin-extract-import-names/node_modules/@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" - }, "node_modules/babel-plugin-macros": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz", @@ -7888,9 +7090,9 @@ "dev": true }, "node_modules/bail": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/bail/-/bail-1.0.5.tgz", - "integrity": "sha512-xFbRxM1tahm08yHBP16MMjVUAvDaBMD38zsM9EMAUN61omwLmKlOpB/Zku5QkjZ8TZ4vn53pj+t518cH0S03RQ==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/bail/-/bail-2.0.2.tgz", + "integrity": "sha512-0xO6mYd7JB2YesxDKplafRpsiOzPt9V02ddPCLbY1xYGPOX24NTyN50qnUxgCPcSoYMhKpAuBTjQoRZCAkUDRw==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -7918,6 +7120,11 @@ "bare-stream": "^2.0.0" } }, + "node_modules/bare-hrtime": { + "version": "2.0.10", + "resolved": "https://registry.npmjs.org/bare-hrtime/-/bare-hrtime-2.0.10.tgz", + "integrity": "sha512-minvIHeR6YIRfxsjgFhk9O//lesw9k5pAeWtZHlA2u3nX1F//TFNoC3lKEDAmMRZSao5PeERZhRaomnCQ7hLQA==" + }, "node_modules/bare-os": { "version": "2.4.4", "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-2.4.4.tgz", @@ -8008,6 +7215,15 @@ "node": "^4.5.0 || >= 5.9" } }, + "node_modules/bcp-47-match": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/bcp-47-match/-/bcp-47-match-2.0.3.tgz", + "integrity": "sha512-JtTezzbAibu8G0R9op9zb3vcWZd9JF6M0xOYGPn0fNCd7wOpRB1mU2mH9T8gaBGbAAyIIVgB2G7xG0GP98zMAQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/better-opn": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/better-opn/-/better-opn-2.1.1.tgz", @@ -8038,16 +7254,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/bindings": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/bindings/-/bindings-1.5.0.tgz", - "integrity": "sha512-p2q/t/mhvuOj/UeLlV6566GD/guowlr0hHxClI0W9m7MWYkL1F0hLo+0Aexs9HSPCtR1SXQ0TD3MMKrXZajbiQ==", - "dev": true, - "optional": true, - "dependencies": { - "file-uri-to-path": "1.0.0" - } - }, "node_modules/bl": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/bl/-/bl-4.1.0.tgz", @@ -8476,14 +7682,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/camelcase-css": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/camelcase-css/-/camelcase-css-2.0.1.tgz", - "integrity": "sha512-QOSvevhslijgYwRx6Rv7zKdMF8lbRmx+uQGx2+vDc+KI/eBnsy9kit5aj23AgGu3pa4t9AgwbnXWqS+iOY+2aA==", - "engines": { - "node": ">= 6" - } - }, "node_modules/camelcase-keys": { "version": "6.2.2", "resolved": "https://registry.npmjs.org/camelcase-keys/-/camelcase-keys-6.2.2.tgz", @@ -8565,9 +7763,9 @@ } }, "node_modules/ccount": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", - "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-2.0.1.tgz", + "integrity": "sha512-eyrF0jiFpY+3drT6383f1qhkbGsLSifNAjA61IUjZjmLCWjItY6LB9ft9YhoDgwfmclB2zhu51Lc7+95b8NRAg==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -8631,18 +7829,18 @@ } }, "node_modules/character-entities": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", - "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-2.0.2.tgz", + "integrity": "sha512-shx7oQ0Awen/BRIdkjkvz54PnEEI/EjwXDSIZp86/KKdbafHh1Df/RYGBhn4hbe2+uKC9FnT5UCEdyPz3ai9hQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, "node_modules/character-entities-html4": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-1.1.4.tgz", - "integrity": "sha512-HRcDxZuZqMx3/a+qrzxdBKBPUpxWEq9xw2OPZ3a/174ihfrQKVsFhqtthBInFy1zZ9GgZyFXOatNujm8M+El3g==", + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/character-entities-html4/-/character-entities-html4-2.1.0.tgz", + "integrity": "sha512-1v7fgQRj6hnSwFpq1Eu0ynr/CDEw0rXo2B61qXrLNdHZmPKgb7fqS1a2JwF0rISo9q77jDI8VMEHoApn8qDoZA==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -8672,118 +7870,156 @@ "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==" }, "node_modules/cheerio": { - "version": "0.22.0", - "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-0.22.0.tgz", - "integrity": "sha512-8/MzidM6G/TgRelkzDG13y3Y9LxBjCb+8yOEZ9+wwq5gVF2w2pV0wmHvjfT0RvuxGyR7UEuK36r+yYMbT4uKgA==", - "dependencies": { - "css-select": "~1.2.0", - "dom-serializer": "~0.1.0", - "entities": "~1.1.1", - "htmlparser2": "^3.9.1", - "lodash.assignin": "^4.0.9", - "lodash.bind": "^4.1.4", - "lodash.defaults": "^4.0.1", - "lodash.filter": "^4.4.0", - "lodash.flatten": "^4.2.0", - "lodash.foreach": "^4.3.0", - "lodash.map": "^4.4.0", - "lodash.merge": "^4.4.0", - "lodash.pick": "^4.2.1", - "lodash.reduce": "^4.4.0", - "lodash.reject": "^4.4.0", - "lodash.some": "^4.4.0" + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/cheerio/-/cheerio-1.0.0.tgz", + "integrity": "sha512-quS9HgjQpdaXOvsZz82Oz7uxtXiy6UIsIQcpBj7HRw2M63Skasm9qlDocAM7jNuaxdhpPU7c4kJN+gA5MCu4ww==", + "dependencies": { + "cheerio-select": "^2.1.0", + "dom-serializer": "^2.0.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "encoding-sniffer": "^0.2.0", + "htmlparser2": "^9.1.0", + "parse5": "^7.1.2", + "parse5-htmlparser2-tree-adapter": "^7.0.0", + "parse5-parser-stream": "^7.1.2", + "undici": "^6.19.5", + "whatwg-mimetype": "^4.0.0" }, "engines": { - "node": ">= 0.6" + "node": ">=18.17" + }, + "funding": { + "url": "https://github.com/cheeriojs/cheerio?sponsor=1" } }, - "node_modules/cheerio/node_modules/css-select": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/css-select/-/css-select-1.2.0.tgz", - "integrity": "sha512-dUQOBoqdR7QwV90WysXPLXG5LO7nhYBgiWVfxF80DKPF8zx1t/pUd2FYy73emg3zrjtM6dzmYgbHKfV2rxiHQA==", + "node_modules/cheerio-select": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cheerio-select/-/cheerio-select-2.1.0.tgz", + "integrity": "sha512-9v9kG0LvzrlcungtnJtpGNxY+fzECQKhK4EGJX2vByejiMX84MFNQw4UxPJl3bFbTMw+Dfs37XaIkCwTZfLh4g==", "dependencies": { - "boolbase": "~1.0.0", - "css-what": "2.1", - "domutils": "1.5.1", - "nth-check": "~1.0.1" + "boolbase": "^1.0.0", + "css-select": "^5.1.0", + "css-what": "^6.1.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" } }, - "node_modules/cheerio/node_modules/css-what": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/css-what/-/css-what-2.1.3.tgz", - "integrity": "sha512-a+EPoD+uZiNfh+5fxw2nO9QwFa6nJe2Or35fGY6Ipw1R3R4AGz1d1TEZrCegvw2YTmZ0jXirGYlzxxpYSHwpEg==", - "engines": { - "node": "*" + "node_modules/cheerio-select/node_modules/css-select": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/css-select/-/css-select-5.1.0.tgz", + "integrity": "sha512-nwoRF1rvRRnnCqqY7updORDsuqKzqYJ28+oSMaJMMgOauh3fvwHqMS7EZpIPqK8GL+g9mKxF1vP/ZjSeNjEVHg==", + "dependencies": { + "boolbase": "^1.0.0", + "css-what": "^6.1.0", + "domhandler": "^5.0.2", + "domutils": "^3.0.1", + "nth-check": "^2.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/fb55" } }, - "node_modules/cheerio/node_modules/dom-serializer": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-0.1.1.tgz", - "integrity": "sha512-l0IU0pPzLWSHBcieZbpOKgkIn3ts3vAh7ZuFyXNwJxJXk/c4Gwj9xaTJwIDVQCXawWD0qb3IzMGH5rglQaO0XA==", + "node_modules/cheerio-select/node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", "dependencies": { - "domelementtype": "^1.3.0", - "entities": "^1.1.1" + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/cheerio/node_modules/domelementtype": { - "version": "1.3.1", - "resolved": "https://registry.npmjs.org/domelementtype/-/domelementtype-1.3.1.tgz", - "integrity": "sha512-BSKB+TSpMpFI/HOxCNr1O8aMOTZ8hT3pM3GQ0w/mWRmkhEDSFJkkyzz4XQsBV44BChwGkrDfMyjVD0eA2aFV3w==" - }, - "node_modules/cheerio/node_modules/domhandler": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-2.4.2.tgz", - "integrity": "sha512-JiK04h0Ht5u/80fdLMCEmV4zkNh2BcoMFBmZ/91WtYZ8qVXSKjiw7fXMgFPnHcSZgOo3XdinHvmnDUeMf5R4wA==", + "node_modules/cheerio-select/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dependencies": { - "domelementtype": "1" + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "node_modules/cheerio/node_modules/domutils": { - "version": "1.5.1", - "resolved": "https://registry.npmjs.org/domutils/-/domutils-1.5.1.tgz", - "integrity": "sha512-gSu5Oi/I+3wDENBsOWBiRK1eoGxcywYSqg3rR960/+EfY0CF4EX1VPkgHOZ3WiS/Jg2DtliF6BhWcHlfpYUcGw==", + "node_modules/cheerio-select/node_modules/domutils": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.1.tgz", + "integrity": "sha512-xWXmuRnN9OMP6ptPd2+H0cCbcYBULa5YDTbMm/2lvkWvNA3O4wcW+GvzooqBuNM8yy6pl3VIAeJTUUWUbfI5Fw==", "dependencies": { - "dom-serializer": "0", - "domelementtype": "1" + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" + }, + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" } }, - "node_modules/cheerio/node_modules/entities": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/entities/-/entities-1.1.2.tgz", - "integrity": "sha512-f2LZMYl1Fzu7YSBKg+RoROelpOaNrcGmE9AZubeDfrCEia483oW4MI4VyFd5VNHIgQ/7qm1I0wUHK1eJnn2y2w==" - }, - "node_modules/cheerio/node_modules/htmlparser2": { - "version": "3.10.1", - "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-3.10.1.tgz", - "integrity": "sha512-IgieNijUMbkDovyoKObU1DUhm1iwNYE/fuifEoEHfd1oZKZDaONBSkal7Y01shxsM49R4XaMdGez3WnF9UfiCQ==", - "dependencies": { - "domelementtype": "^1.3.1", - "domhandler": "^2.3.0", - "domutils": "^1.5.1", - "entities": "^1.1.1", - "inherits": "^2.0.1", - "readable-stream": "^3.1.1" + "node_modules/cheerio/node_modules/dom-serializer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/dom-serializer/-/dom-serializer-2.0.0.tgz", + "integrity": "sha512-wIkAryiqt/nV5EQKqQpo3SToSOV9J0DnbJqwK7Wv/Trc92zIAYZ4FlMu+JPFW1DfGFt81ZTCGgDEabffXeLyJg==", + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.2", + "entities": "^4.2.0" + }, + "funding": { + "url": "https://github.com/cheeriojs/dom-serializer?sponsor=1" } }, - "node_modules/cheerio/node_modules/nth-check": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/nth-check/-/nth-check-1.0.2.tgz", - "integrity": "sha512-WeBOdju8SnzPN5vTUJYxYUxLeXpCaVP5i5e0LF8fg7WORF2Wd7wFX/pk0tYZk7s8T+J7VLy0Da6J1+wCT0AtHg==", + "node_modules/cheerio/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", "dependencies": { - "boolbase": "~1.0.0" + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" } }, - "node_modules/cheerio/node_modules/readable-stream": { - "version": "3.6.2", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", - "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "node_modules/cheerio/node_modules/domutils": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/domutils/-/domutils-3.2.1.tgz", + "integrity": "sha512-xWXmuRnN9OMP6ptPd2+H0cCbcYBULa5YDTbMm/2lvkWvNA3O4wcW+GvzooqBuNM8yy6pl3VIAeJTUUWUbfI5Fw==", "dependencies": { - "inherits": "^2.0.3", - "string_decoder": "^1.1.1", - "util-deprecate": "^1.0.1" + "dom-serializer": "^2.0.0", + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3" }, - "engines": { - "node": ">= 6" + "funding": { + "url": "https://github.com/fb55/domutils?sponsor=1" + } + }, + "node_modules/cheerio/node_modules/htmlparser2": { + "version": "9.1.0", + "resolved": "https://registry.npmjs.org/htmlparser2/-/htmlparser2-9.1.0.tgz", + "integrity": "sha512-5zfg6mHUoaer/97TxnGpxmbR7zJtPwIYFMZ/H5ucTlPZhKvtum05yiPK3Mgai3a0DyVxv7qYqoweaEd2nrYQzQ==", + "funding": [ + "https://github.com/fb55/htmlparser2?sponsor=1", + { + "type": "github", + "url": "https://github.com/sponsors/fb55" + } + ], + "dependencies": { + "domelementtype": "^2.3.0", + "domhandler": "^5.0.3", + "domutils": "^3.1.0", + "entities": "^4.5.0" } }, "node_modules/chokidar": { @@ -9135,15 +8371,6 @@ "node": ">=6" } }, - "node_modules/collapse-white-space": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/collapse-white-space/-/collapse-white-space-1.0.6.tgz", - "integrity": "sha512-jEovNnrhMuqyCcjfEJA56v0Xq8SkIoPKDyaHahwo3POf4qcSXqMYuwNcOTzp74vTsR9Tn08z4MxWqAhcekogkQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/collection-visit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", @@ -9230,9 +8457,9 @@ } }, "node_modules/comma-separated-tokens": { - "version": "1.0.8", - "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-1.0.8.tgz", - "integrity": "sha512-GHuDRO12Sypu2cV70d1dkA2EUmXHgntrzbpvOB+Qy+49ypNfGgFQIC2fhhXbnyrJRynDCAARsT7Ou0M6hirpfw==", + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/comma-separated-tokens/-/comma-separated-tokens-2.0.3.tgz", + "integrity": "sha512-Fu4hJdvzeylCfQPp9SGWidpzrMs7tTrlu6Vb8XGaRGck8QSNZJJp538Wrb60Lax4fPwR64ViY468OIUTbRlGZg==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -9648,25 +8875,6 @@ "node": ">=0.10.0" } }, - "node_modules/cpx/node_modules/fsevents": { - "version": "1.2.13", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.13.tgz", - "integrity": "sha512-oWb1Z6mkHIskLzEJ/XWX0srkpkTQ7vaopMQkyaEIoq0fmtFVxOthb8cCxeT+p3ynTdkk/RZwbgG4brR5BeWECw==", - "deprecated": "Upgrade to fsevents v2 to mitigate potential security issues", - "dev": true, - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "dependencies": { - "bindings": "^1.5.0", - "nan": "^2.12.1" - }, - "engines": { - "node": ">= 4.0" - } - }, "node_modules/cpx/node_modules/glob-parent": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-2.0.0.tgz", @@ -10229,6 +9437,11 @@ "url": "https://github.com/sponsors/fb55" } }, + "node_modules/css-selector-parser": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/css-selector-parser/-/css-selector-parser-1.4.1.tgz", + "integrity": "sha512-HYPSb7y/Z7BNDCOrakL4raGO2zltZkbeXyAd6Tg9obzix6QhzxCotdBl6VT0Dv4vZfJGVz3WL/xaEI9Ly3ul0g==" + }, "node_modules/css-to-react-native": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/css-to-react-native/-/css-to-react-native-3.2.0.tgz", @@ -10502,11 +9715,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/dataloader": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-1.4.0.tgz", - "integrity": "sha512-68s5jYdlvasItOJnCuI2Q9s4q98g0pCyL3HrcKJu8KNugUl8ahgmZYg38ysLTgQjjXX3H8CJLkAvWrclWfcalw==" - }, "node_modules/date-fns": { "version": "2.30.0", "resolved": "https://registry.npmjs.org/date-fns/-/date-fns-2.30.0.tgz", @@ -10575,6 +9783,18 @@ "node": ">=0.10.0" } }, + "node_modules/decode-named-character-reference": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/decode-named-character-reference/-/decode-named-character-reference-1.0.2.tgz", + "integrity": "sha512-O8x12RzrUF8xyVcY0KJowWsmaJxQbmy0/EtnNtHRpsOcT7dFk5W598coHqBVpmWo1oQQfsCqfCmkZN5DJrZVdg==", + "dependencies": { + "character-entities": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/decode-uri-component": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.2.tgz", @@ -10758,6 +9978,14 @@ "node": ">= 0.6.0" } }, + "node_modules/dequal": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", + "integrity": "sha512-0je+qPKHEMohvfRTCEo3CrPG6cAzAYgmzKyxRiYSSDkS6eGJdyVJm7WaYA5ECaAD9wLB2T4EEeymA5aFVcYXCA==", + "engines": { + "node": ">=6" + } + }, "node_modules/destroy": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/destroy/-/destroy-1.2.0.tgz", @@ -10767,18 +9995,6 @@ "npm": "1.2.8000 || >= 1.4.16" } }, - "node_modules/detab": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/detab/-/detab-2.0.4.tgz", - "integrity": "sha512-8zdsQA5bIkoRECvCrNKPla84lyoR7DSAyf7p0YgXzBO9PDJx8KntPUay7NS6yp+KdxdVtiE5SpHKtbp2ZQyA9g==", - "dependencies": { - "repeat-string": "^1.5.4" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/detect-libc": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz", @@ -10906,6 +10122,14 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, + "node_modules/diff": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/diff/-/diff-5.2.0.tgz", + "integrity": "sha512-uIFDxqpRZGZ6ThOk84hEfqWoHx2devRFvpTZcTHur85vImfaxUbTW9Ryh4CpCuDnToOP1CEtXKIgytHBPVff5A==", + "engines": { + "node": ">=0.3.1" + } + }, "node_modules/dir-glob": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz", @@ -10917,6 +10141,18 @@ "node": ">=8" } }, + "node_modules/direction": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/direction/-/direction-2.0.1.tgz", + "integrity": "sha512-9S6m9Sukh1cZNknO1CWAr2QAWsbKLafQiyM5gZ7VgXHeuaoUwffKN4q6NC4A/Mf9iiPlOXQEKW/Mv/mh9/3YFA==", + "bin": { + "direction": "cli.js" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/dnd-core": { "version": "11.1.3", "resolved": "https://registry.npmjs.org/dnd-core/-/dnd-core-11.1.3.tgz", @@ -11113,6 +10349,29 @@ "node": ">= 0.8" } }, + "node_modules/encoding-sniffer": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/encoding-sniffer/-/encoding-sniffer-0.2.0.tgz", + "integrity": "sha512-ju7Wq1kg04I3HtiYIOrUrdfdDvkyO9s5XM8QAj/bN61Yo/Vb4vgJxy5vi4Yxk01gWHbrofpPtpxM8bKger9jhg==", + "dependencies": { + "iconv-lite": "^0.6.3", + "whatwg-encoding": "^3.1.1" + }, + "funding": { + "url": "https://github.com/fb55/encoding-sniffer?sponsor=1" + } + }, + "node_modules/encoding-sniffer/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/end-of-stream": { "version": "1.4.4", "resolved": "https://registry.npmjs.org/end-of-stream/-/end-of-stream-1.4.4.tgz", @@ -11563,6 +10822,7 @@ "version": "8.57.1", "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.1.tgz", "integrity": "sha512-ypowyDxpVSYpkXr9WPv2PAZCtNip1Mv5KTW0SCurXv/9iOpcrH9PaqUElksqEB6pChqHGDRCFTyrZlGhnLNGiA==", + "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.6.1", @@ -11663,6 +10923,38 @@ "ms": "^2.1.1" } }, + "node_modules/eslint-mdx": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/eslint-mdx/-/eslint-mdx-2.3.4.tgz", + "integrity": "sha512-u4NszEUyoGtR7Q0A4qs0OymsEQdCO6yqWlTzDa9vGWsK7aMotdnW0hqifHTkf6lEtA2vHk2xlkWHTCrhYLyRbw==", + "dev": true, + "dependencies": { + "acorn": "^8.10.0", + "acorn-jsx": "^5.3.2", + "espree": "^9.6.1", + "estree-util-visit": "^1.2.1", + "remark-mdx": "^2.3.0", + "remark-parse": "^10.0.2", + "remark-stringify": "^10.0.3", + "synckit": "^0.9.0", + "tslib": "^2.6.1", + "unified": "^10.1.2", + "unified-engine": "^10.1.0", + "unist-util-visit": "^4.1.2", + "uvu": "^0.5.6", + "vfile": "^5.3.7" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "eslint": ">=8.0.0" + } + }, "node_modules/eslint-module-utils": { "version": "2.11.1", "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.11.1.tgz", @@ -11781,6 +11073,47 @@ "eslint": "^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9" } }, + "node_modules/eslint-plugin-markdown": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-markdown/-/eslint-plugin-markdown-3.0.1.tgz", + "integrity": "sha512-8rqoc148DWdGdmYF6WSQFT3uQ6PO7zXYgeBpHAOAakX/zpq+NvFYbDA/H7PYzHajwtmaOzAwfxyl++x0g1/N9A==", + "dev": true, + "dependencies": { + "mdast-util-from-markdown": "^0.8.5" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "peerDependencies": { + "eslint": "^6.0.0 || ^7.0.0 || ^8.0.0" + } + }, + "node_modules/eslint-plugin-mdx": { + "version": "2.3.4", + "resolved": "https://registry.npmjs.org/eslint-plugin-mdx/-/eslint-plugin-mdx-2.3.4.tgz", + "integrity": "sha512-kr6tgaifKL+AVGYMtdYc2VCsIjfYQXuUCKz4rK58d2DpnPFHrmgXIOC7NcMvaEld+VOEpxBSCCnjnsf4IVCQGg==", + "dev": true, + "dependencies": { + "eslint-mdx": "^2.3.4", + "eslint-plugin-markdown": "^3.0.1", + "remark-mdx": "^2.3.0", + "remark-parse": "^10.0.2", + "remark-stringify": "^10.0.3", + "tslib": "^2.6.1", + "unified": "^10.1.2", + "vfile": "^5.3.7" + }, + "engines": { + "node": "^12.20.0 || ^14.18.0 || >=16.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "eslint": ">=8.0.0" + } + }, "node_modules/eslint-plugin-react": { "version": "7.37.3", "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.37.3.tgz", @@ -12008,6 +11341,7 @@ "version": "6.12.6", "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", @@ -12023,6 +11357,7 @@ "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, "dependencies": { "color-convert": "^2.0.1" }, @@ -12037,6 +11372,7 @@ "version": "4.1.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dev": true, "dependencies": { "ansi-styles": "^4.1.0", "supports-color": "^7.1.0" @@ -12052,6 +11388,7 @@ "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, "dependencies": { "color-name": "~1.1.4" }, @@ -12062,12 +11399,14 @@ "node_modules/eslint/node_modules/color-name": { "version": "1.1.4", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true }, "node_modules/eslint/node_modules/eslint-scope": { "version": "7.2.2", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-7.2.2.tgz", "integrity": "sha512-dOt21O7lTMhDM+X9mB4GX+DZrZtCUJPL/wlcTqxyrx5IvO0IYtILdtrQGQp+8n5S0gwSVmOf9NQrjMOgfQZlIg==", + "dev": true, "dependencies": { "esrecurse": "^4.3.0", "estraverse": "^5.2.0" @@ -12083,6 +11422,7 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -12094,6 +11434,7 @@ "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", "integrity": "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A==", + "dev": true, "dependencies": { "is-glob": "^4.0.3" }, @@ -12105,6 +11446,7 @@ "version": "13.24.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.24.0.tgz", "integrity": "sha512-AhO5QUcj8llrbG09iWhPU2B204J1xnPeL8kQmVorSsy+Sjj1sk8gIyh6cUocGmH4L0UuhAJy+hJMRA4mgA4mFQ==", + "dev": true, "dependencies": { "type-fest": "^0.20.2" }, @@ -12119,6 +11461,7 @@ "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "dev": true, "engines": { "node": ">=8" } @@ -12126,12 +11469,14 @@ "node_modules/eslint/node_modules/json-schema-traverse": { "version": "0.4.1", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==" + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true }, "node_modules/eslint/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dev": true, "dependencies": { "has-flag": "^4.0.0" }, @@ -12157,6 +11502,7 @@ "version": "9.6.1", "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", + "dev": true, "dependencies": { "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", @@ -12173,6 +11519,7 @@ "version": "3.4.3", "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", + "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" }, @@ -12222,6 +11569,84 @@ "node": ">=4.0" } }, + "node_modules/estree-util-attach-comments": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/estree-util-attach-comments/-/estree-util-attach-comments-2.1.1.tgz", + "integrity": "sha512-+5Ba/xGGS6mnwFbXIuQiDPTbuTxuMCooq3arVv7gPZtYpjp+VXH/NkHAP35OOefPhNG/UGqU3vt/LTABwcHX0w==", + "dependencies": { + "@types/estree": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/estree-util-build-jsx/-/estree-util-build-jsx-2.2.2.tgz", + "integrity": "sha512-m56vOXcOBuaF+Igpb9OPAy7f9w9OIkb5yhjsZuaPm7HoGi4oTOQi0h2+yZ+AtKklYFZ+rPC4n0wYCJCEU1ONqg==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "estree-util-is-identifier-name": "^2.0.0", + "estree-walker": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-build-jsx/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, + "node_modules/estree-util-is-identifier-name": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/estree-util-is-identifier-name/-/estree-util-is-identifier-name-2.1.0.tgz", + "integrity": "sha512-bEN9VHRyXAUOjkKVQVvArFym08BTWB0aJPppZZr0UNyAqWsLaVfAqP7hbaTJjzHifmB5ebnR8Wm7r7yGN/HonQ==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/estree-util-to-js/-/estree-util-to-js-1.2.0.tgz", + "integrity": "sha512-IzU74r1PK5IMMGZXUVZbmiu4A1uhiPgW5hm1GjcOfr4ZzHaMPpLNJjR7HjXiIOzi25nZDrgFTobHTkV5Q6ITjA==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "astring": "^1.8.0", + "source-map": "^0.7.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/estree-util-to-js/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/estree-util-visit": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/estree-util-visit/-/estree-util-visit-1.2.1.tgz", + "integrity": "sha512-xbgqcrkIVbIG+lI/gzbvd9SGTJL4zqJKBFttUl5pP27KhAjtMKbX/mQXJ7qgyXpMgVy/zvpm0xoQQaGL8OloOw==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/estree-walker": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.6.1.tgz", @@ -12243,25 +11668,21 @@ "node": ">= 0.6" } }, - "node_modules/eval": { - "version": "0.1.8", - "resolved": "https://registry.npmjs.org/eval/-/eval-0.1.8.tgz", - "integrity": "sha512-EzV94NYKoO09GLXGjXj9JIlXijVck4ONSr5wiCWDvhsvj5jxSrzTmRU/9C1DyB6uToszLs8aifA6NQ7lEQdvFw==", + "node_modules/event-emitter": { + "version": "0.3.5", + "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", + "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", "dependencies": { - "@types/node": "*", - "require-like": ">= 0.1.1" - }, - "engines": { - "node": ">= 0.8" + "d": "1", + "es5-ext": "~0.10.14" } }, - "node_modules/event-emitter": { - "version": "0.3.5", - "resolved": "https://registry.npmjs.org/event-emitter/-/event-emitter-0.3.5.tgz", - "integrity": "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA==", + "node_modules/event-loop-delay": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/event-loop-delay/-/event-loop-delay-1.1.0.tgz", + "integrity": "sha512-2kyV9oJBJFXjfiMXZKQ2KADeGTQtCsVzU6bWwMPcT7rXPk6Xa4qIXYHO16bBETGA642u5hdsbnH6v3f61jn4Rw==", "dependencies": { - "d": "1", - "es5-ext": "~0.10.14" + "bare-hrtime": "^2.0.9" } }, "node_modules/event-source-polyfill": { @@ -12269,11 +11690,6 @@ "resolved": "https://registry.npmjs.org/event-source-polyfill/-/event-source-polyfill-1.0.31.tgz", "integrity": "sha512-4IJSItgS/41IxN5UVAVuAyczwZF7ZIEsM1XAoUzIHA6A+xzusEZUutdXz2Nr+MQPLxfTiCvqE79/C8HT8fKFvA==" }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==" - }, "node_modules/events": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz", @@ -12712,6 +12128,19 @@ "reusify": "^1.0.4" } }, + "node_modules/fault": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fault/-/fault-2.0.1.tgz", + "integrity": "sha512-WtySTkS4OKev5JtpHXnib4Gxiurzh5NCGvWrFaZ34m6JehfTUhKZvn9njTfw48t6JumVQOmrKqpmGcdwxnhqBQ==", + "dev": true, + "dependencies": { + "format": "^0.2.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/fb-watchman": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/fb-watchman/-/fb-watchman-2.0.2.tgz", @@ -12860,13 +12289,6 @@ "url": "https://github.com/sindresorhus/file-type?sponsor=1" } }, - "node_modules/file-uri-to-path": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/file-uri-to-path/-/file-uri-to-path-1.0.0.tgz", - "integrity": "sha512-0Zt+s3L7Vf1biwWZ29aARiVYLx7iMGnEUl9x33fbB/j3jR81u/O2LbqK+Bm1CDSNDKVtJ/YjwY7TUd5SkeLQLw==", - "dev": true, - "optional": true - }, "node_modules/filename-regex": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/filename-regex/-/filename-regex-2.0.1.tgz", @@ -13363,6 +12785,15 @@ "node": ">= 14.17" } }, + "node_modules/format": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/format/-/format-0.2.2.tgz", + "integrity": "sha512-wzsgA6WOq+09wrU1tsJ09udeR/YZRaeArL9e1wPbFg3GG2yDnC2ldKpxs4xunpFF9DgqCqOIra3bc1HWrJ37Ww==", + "dev": true, + "engines": { + "node": ">=0.4.x" + } + }, "node_modules/formik": { "version": "2.4.6", "resolved": "https://registry.npmjs.org/formik/-/formik-2.4.6.tgz", @@ -13516,19 +12947,6 @@ "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==" }, - "node_modules/fsevents": { - "version": "2.3.3", - "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz", - "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==", - "hasInstallScript": true, - "optional": true, - "os": [ - "darwin" - ], - "engines": { - "node": "^8.16.0 || ^10.6.0 || >=11.0.0" - } - }, "node_modules/function-bind": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", @@ -14205,114 +13623,47 @@ } }, "node_modules/gatsby-plugin-mdx": { - "version": "3.20.0", - "resolved": "https://registry.npmjs.org/gatsby-plugin-mdx/-/gatsby-plugin-mdx-3.20.0.tgz", - "integrity": "sha512-v2cFqe1g8lmM745q2DUoqWca0MT/tX++jykBDqpsLDswushpJgUfZeJ8OhSFgBZIfuVk1LoDi5yf4iWfz/UTwQ==", - "dependencies": { - "@babel/core": "^7.15.5", - "@babel/generator": "^7.15.4", - "@babel/helper-plugin-utils": "^7.14.0", - "@babel/plugin-proposal-object-rest-spread": "^7.14.7", - "@babel/preset-env": "^7.15.4", - "@babel/preset-react": "^7.14.0", - "@babel/runtime": "^7.15.4", - "@babel/types": "^7.15.4", - "camelcase-css": "^2.0.1", - "change-case": "^3.1.0", - "core-js": "^3.22.3", - "dataloader": "^1.4.0", - "debug": "^4.3.1", - "escape-string-regexp": "^1.0.5", - "eval": "^0.1.4", - "fs-extra": "^10.1.0", - "gatsby-core-utils": "^3.20.0", - "gray-matter": "^4.0.2", - "json5": "^2.1.3", - "loader-utils": "^1.4.0", - "lodash": "^4.17.21", - "mdast-util-to-string": "^1.1.0", - "mdast-util-toc": "^3.1.0", - "mime": "^2.4.6", - "mkdirp": "^1.0.4", - "p-queue": "^6.6.2", - "pretty-bytes": "^5.3.0", - "remark": "^10.0.1", - "remark-retext": "^3.1.3", - "retext-english": "^3.0.4", - "slugify": "^1.4.4", - "static-site-generator-webpack-plugin": "^3.4.2", - "style-to-object": "^0.3.0", - "underscore.string": "^3.3.5", - "unified": "^8.4.2", - "unist-util-map": "^1.0.5", - "unist-util-remove": "^1.0.3", - "unist-util-visit": "^1.4.1" - }, - "peerDependencies": { - "@mdx-js/mdx": "^1.0.0", - "@mdx-js/react": "^1.0.0", - "gatsby": "^4.0.0-next", - "react": "^16.9.0 || ^17.0.0 || ^18.0.0", - "react-dom": "^16.9.0 || ^17.0.0 || ^18.0.0" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/camel-case": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/camel-case/-/camel-case-3.0.0.tgz", - "integrity": "sha512-+MbKztAYHXPr1jNTSKQF52VpcFjwY5RkR7fxksV8Doo4KAYc5Fl4UJRgthBbTmEx8C54DqahhbLJkDwjI3PI/w==", - "dependencies": { - "no-case": "^2.2.0", - "upper-case": "^1.1.1" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/change-case": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/change-case/-/change-case-3.1.0.tgz", - "integrity": "sha512-2AZp7uJZbYEzRPsFoa+ijKdvp9zsrnnt6+yFokfwEpeJm0xuJDVoxiRCAaTzyJND8GJkofo2IcKWaUZ/OECVzw==", - "dependencies": { - "camel-case": "^3.0.0", - "constant-case": "^2.0.0", - "dot-case": "^2.1.0", - "header-case": "^1.0.0", - "is-lower-case": "^1.1.0", - "is-upper-case": "^1.1.0", - "lower-case": "^1.1.1", - "lower-case-first": "^1.0.0", - "no-case": "^2.3.2", - "param-case": "^2.1.0", - "pascal-case": "^2.0.0", - "path-case": "^2.1.0", - "sentence-case": "^2.1.0", - "snake-case": "^2.1.0", - "swap-case": "^1.1.0", - "title-case": "^2.1.0", - "upper-case": "^1.1.1", - "upper-case-first": "^1.1.0" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/constant-case": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/constant-case/-/constant-case-2.0.0.tgz", - "integrity": "sha512-eS0N9WwmjTqrOmR3o83F5vW8Z+9R1HnVz3xmzT2PMFug9ly+Au/fxRWlEBSb6LcZwspSsEn9Xs1uw9YgzAg1EQ==", - "dependencies": { - "snake-case": "^2.1.0", - "upper-case": "^1.1.1" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/dot-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/dot-case/-/dot-case-2.1.1.tgz", - "integrity": "sha512-HnM6ZlFqcajLsyudHq7LeeLDr2rFAVYtDv/hV5qchQEidSck8j9OPUsXY9KwJv/lHMtYlX4DjRQqwFYa+0r8Ug==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/gatsby-plugin-mdx/-/gatsby-plugin-mdx-5.0.0.tgz", + "integrity": "sha512-4OkotIxp5rpQ1CNFoWrF2XtvwjK0wkvoJrLaHcO+ykQHAa0aU72MJl91RjpIA4iiSQJEMG8HBrSvqIQoKmo51w==", "dependencies": { - "no-case": "^2.2.0" + "@mdx-js/mdx": "^2.1.1", + "acorn": "^7.4.1", + "acorn-jsx": "^5.3.2", + "astring": "^1.8.3", + "deepmerge": "^4.2.2", + "estree-util-build-jsx": "^2.1.0", + "fs-extra": "^10.1.0", + "gatsby-core-utils": "^4.0.0", + "gatsby-plugin-utils": "^4.0.0", + "gray-matter": "^4.0.3", + "mdast-util-mdx": "^2.0.0", + "mdast-util-to-hast": "^10.2.0", + "mdast-util-to-markdown": "^1.3.0", + "mdast-util-toc": "^6.1.0", + "rehype-infer-description-meta": "^1.0.1", + "remark-unwrap-images": "^3.0.1", + "unified": "^10.1.2", + "unist-util-visit": "^4.1.0", + "vfile": "^5.3.2" + }, + "peerDependencies": { + "@mdx-js/react": "^2.0.0", + "gatsby": "^5.0.0-next", + "gatsby-source-filesystem": "^5.0.0-next", + "react": "^18.0.0 || ^0.0.0", + "react-dom": "^18.0.0 || ^0.0.0" } }, - "node_modules/gatsby-plugin-mdx/node_modules/escape-string-regexp": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "node_modules/gatsby-plugin-mdx/node_modules/acorn": { + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-7.4.1.tgz", + "integrity": "sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==", + "bin": { + "acorn": "bin/acorn" + }, "engines": { - "node": ">=0.8.0" + "node": ">=0.4.0" } }, "node_modules/gatsby-plugin-mdx/node_modules/fs-extra": { @@ -14328,241 +13679,6 @@ "node": ">=12" } }, - "node_modules/gatsby-plugin-mdx/node_modules/gatsby-core-utils": { - "version": "3.25.0", - "resolved": "https://registry.npmjs.org/gatsby-core-utils/-/gatsby-core-utils-3.25.0.tgz", - "integrity": "sha512-lmMDwbnKpqAi+8WWd7MvCTCx3E0u7j8sbVgydERNCYVxKVpzD/aLCH4WPb4EE9m1H1rSm76w0Z+MaentyB/c/Q==", - "dependencies": { - "@babel/runtime": "^7.15.4", - "ci-info": "2.0.0", - "configstore": "^5.0.1", - "fastq": "^1.13.0", - "file-type": "^16.5.3", - "fs-extra": "^10.1.0", - "got": "^11.8.5", - "import-from": "^4.0.0", - "lmdb": "2.5.3", - "lock": "^1.1.0", - "node-object-hash": "^2.3.10", - "proper-lockfile": "^4.1.2", - "resolve-from": "^5.0.0", - "tmp": "^0.2.1", - "xdg-basedir": "^4.0.0" - }, - "engines": { - "node": ">=14.15.0" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/header-case": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/header-case/-/header-case-1.0.1.tgz", - "integrity": "sha512-i0q9mkOeSuhXw6bGgiQCCBgY/jlZuV/7dZXyZ9c6LcBrqwvT8eT719E9uxE5LiZftdl+z81Ugbg/VvXV4OJOeQ==", - "dependencies": { - "no-case": "^2.2.0", - "upper-case": "^1.1.3" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/is-lower-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/is-lower-case/-/is-lower-case-1.1.3.tgz", - "integrity": "sha512-+5A1e/WJpLLXZEDlgz4G//WYSHyQBD32qa4Jd3Lw06qQlv3fJHnp3YIHjTQSGzHMgzmVKz2ZP3rBxTHkPw/lxA==", - "dependencies": { - "lower-case": "^1.1.0" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", - "engines": { - "node": ">=8" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/is-upper-case": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/is-upper-case/-/is-upper-case-1.1.2.tgz", - "integrity": "sha512-GQYSJMgfeAmVwh9ixyk888l7OIhNAGKtY6QA+IrWlu9MDTCaXmeozOZ2S9Knj7bQwBO/H6J2kb+pbyTUiMNbsw==", - "dependencies": { - "upper-case": "^1.1.0" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/loader-utils": { - "version": "1.4.2", - "resolved": "https://registry.npmjs.org/loader-utils/-/loader-utils-1.4.2.tgz", - "integrity": "sha512-I5d00Pd/jwMD2QCduo657+YM/6L3KZu++pmX9VFncxaxvHcru9jx1lBaFft+r4Mt2jK0Yhp41XlRAihzPxHNCg==", - "dependencies": { - "big.js": "^5.2.2", - "emojis-list": "^3.0.0", - "json5": "^1.0.1" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/loader-utils/node_modules/json5": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", - "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", - "dependencies": { - "minimist": "^1.2.0" - }, - "bin": { - "json5": "lib/cli.js" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/lower-case": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-1.1.4.tgz", - "integrity": "sha512-2Fgx1Ycm599x+WGpIYwJOvsjmXFzTSc34IwDWALRA/8AopUKAVPwfJ+h5+f85BCp0PWmmJcWzEpxOpoXycMpdA==" - }, - "node_modules/gatsby-plugin-mdx/node_modules/lower-case-first": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/lower-case-first/-/lower-case-first-1.0.2.tgz", - "integrity": "sha512-UuxaYakO7XeONbKrZf5FEgkantPf5DUqDayzP5VXZrtRPdH86s4kN47I8B3TW10S4QKiE3ziHNf3kRN//okHjA==", - "dependencies": { - "lower-case": "^1.1.2" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/mime": { - "version": "2.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", - "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4.0.0" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/mkdirp": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz", - "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", - "bin": { - "mkdirp": "bin/cmd.js" - }, - "engines": { - "node": ">=10" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/no-case": { - "version": "2.3.2", - "resolved": "https://registry.npmjs.org/no-case/-/no-case-2.3.2.tgz", - "integrity": "sha512-rmTZ9kz+f3rCvK2TD1Ue/oZlns7OGoIWP4fc3llxxRXlOkHKoWPPWJOfFYpITabSow43QJbRIoHQXtt10VldyQ==", - "dependencies": { - "lower-case": "^1.1.1" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/param-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/param-case/-/param-case-2.1.1.tgz", - "integrity": "sha512-eQE845L6ot89sk2N8liD8HAuH4ca6Vvr7VWAWwt7+kvvG5aBcPmmphQ68JsEG2qa9n1TykS2DLeMt363AAH8/w==", - "dependencies": { - "no-case": "^2.2.0" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/pascal-case": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/pascal-case/-/pascal-case-2.0.1.tgz", - "integrity": "sha512-qjS4s8rBOJa2Xm0jmxXiyh1+OFf6ekCWOvUaRgAQSktzlTbMotS0nmG9gyYAybCWBcuP4fsBeRCKNwGBnMe2OQ==", - "dependencies": { - "camel-case": "^3.0.0", - "upper-case-first": "^1.1.0" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/path-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/path-case/-/path-case-2.1.1.tgz", - "integrity": "sha512-Ou0N05MioItesaLr9q8TtHVWmJ6fxWdqKB2RohFmNWVyJ+2zeKIeDNWAN6B/Pe7wpzWChhZX6nONYmOnMeJQ/Q==", - "dependencies": { - "no-case": "^2.2.0" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/sentence-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/sentence-case/-/sentence-case-2.1.1.tgz", - "integrity": "sha512-ENl7cYHaK/Ktwk5OTD+aDbQ3uC8IByu/6Bkg+HDv8Mm+XnBnppVNalcfJTNsp1ibstKh030/JKQQWglDvtKwEQ==", - "dependencies": { - "no-case": "^2.2.0", - "upper-case-first": "^1.1.2" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/snake-case": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/snake-case/-/snake-case-2.1.0.tgz", - "integrity": "sha512-FMR5YoPFwOLuh4rRz92dywJjyKYZNLpMn1R5ujVpIYkbA9p01fq8RMg0FkO4M+Yobt4MjHeLTJVm5xFFBHSV2Q==", - "dependencies": { - "no-case": "^2.2.0" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/swap-case": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/swap-case/-/swap-case-1.1.2.tgz", - "integrity": "sha512-BAmWG6/bx8syfc6qXPprof3Mn5vQgf5dwdUNJhsNqU9WdPt5P+ES/wQ5bxfijy8zwZgZZHslC3iAsxsuQMCzJQ==", - "dependencies": { - "lower-case": "^1.1.1", - "upper-case": "^1.1.1" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/title-case": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/title-case/-/title-case-2.1.1.tgz", - "integrity": "sha512-EkJoZ2O3zdCz3zJsYCsxyq2OC5hrxR9mfdd5I+w8h/tmFfeOxJ+vvkxsKxdmN0WtS9zLdHEgfgVOiMVgv+Po4Q==", - "dependencies": { - "no-case": "^2.2.0", - "upper-case": "^1.0.3" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/unified": { - "version": "8.4.2", - "resolved": "https://registry.npmjs.org/unified/-/unified-8.4.2.tgz", - "integrity": "sha512-JCrmN13jI4+h9UAyKEoGcDZV+i1E7BLFuG7OsaDvTXI5P0qhHX+vZO/kOhz9jn8HGENDKbwSeB0nVOg4gVStGA==", - "dependencies": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^2.0.0", - "trough": "^1.0.0", - "vfile": "^4.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/unist-util-is": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", - "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==" - }, - "node_modules/gatsby-plugin-mdx/node_modules/unist-util-visit": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", - "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", - "dependencies": { - "unist-util-visit-parents": "^2.0.0" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/unist-util-visit-parents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", - "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", - "dependencies": { - "unist-util-is": "^3.0.0" - } - }, - "node_modules/gatsby-plugin-mdx/node_modules/upper-case": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/upper-case/-/upper-case-1.1.3.tgz", - "integrity": "sha512-WRbjgmYzgXkCV7zNVpy5YgrHgbBv126rMALQQMrmzOVC4GM2waQ9x7xtm8VU+1yF2kWyPzI9zbZ48n4vSxwfSA==" - }, - "node_modules/gatsby-plugin-mdx/node_modules/upper-case-first": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/upper-case-first/-/upper-case-first-1.1.2.tgz", - "integrity": "sha512-wINKYvI3Db8dtjikdAqoBbZoP6Q+PZUyfMR7pmwHzjC2quzSkUq5DmPrTtPEqHaz8AGtmsB4TqwapMTM1QAQOQ==", - "dependencies": { - "upper-case": "^1.1.1" - } - }, "node_modules/gatsby-plugin-meta-redirect": { "version": "1.1.3", "resolved": "git+ssh://git@github.com/layer5labs/gatsby-plugin-meta-redirect.git#734c1628a490bd0f58075bbf7d4396f9ee1ee566", @@ -14603,6 +13719,20 @@ "node": ">= 4.0.0" } }, + "node_modules/gatsby-plugin-no-sourcemaps": { + "version": "4.25.0", + "resolved": "https://registry.npmjs.org/gatsby-plugin-no-sourcemaps/-/gatsby-plugin-no-sourcemaps-4.25.0.tgz", + "integrity": "sha512-gurzjbY7TPrGim69x+P0D11f6t5VMqK460KEtDB5LYitDVCnNJ2KDfy3J0cg6eGWWq646vGVEMaFQ5HdioMdJg==", + "dependencies": { + "@babel/runtime": "^7.15.4" + }, + "engines": { + "node": ">=14.15.0" + }, + "peerDependencies": { + "gatsby": "^4.0.0-next" + } + }, "node_modules/gatsby-plugin-page-creator": { "version": "5.13.1", "resolved": "https://registry.npmjs.org/gatsby-plugin-page-creator/-/gatsby-plugin-page-creator-5.13.1.tgz", @@ -14955,31 +14085,157 @@ "gatsby-plugin-meta-redirect": ">=1.1.0" } }, - "node_modules/gatsby-script": { - "version": "2.13.0", - "resolved": "https://registry.npmjs.org/gatsby-script/-/gatsby-script-2.13.0.tgz", - "integrity": "sha512-TGNQGerf1NMJrgJkWxWrW6FFMAuC0L76WlyZgGXmhckPW/x7V1SxZrm0a2Q99kRHyoC59RYl2gTQWHaIwV+ZjA==", + "node_modules/gatsby-remark-images": { + "version": "6.25.0", + "resolved": "https://registry.npmjs.org/gatsby-remark-images/-/gatsby-remark-images-6.25.0.tgz", + "integrity": "sha512-NNJ17OxA8xPFtTHBfWCxAGqU9ciOielWALUlzY1YdCvYl2rcDmw498tjx77wC995yCBkcwe7yfL1tgky9bxdqQ==", + "dependencies": { + "@babel/runtime": "^7.15.4", + "chalk": "^4.1.2", + "cheerio": "^1.0.0-rc.10", + "gatsby-core-utils": "^3.25.0", + "is-relative-url": "^3.0.0", + "lodash": "^4.17.21", + "mdast-util-definitions": "^4.0.0", + "query-string": "^6.14.1", + "unist-util-select": "^3.0.4", + "unist-util-visit-parents": "^3.1.1" + }, "engines": { - "node": ">=18.0.0" + "node": ">=14.15.0" }, "peerDependencies": { - "@gatsbyjs/reach-router": "^2.0.0", - "react": "^18.0.0 || ^0.0.0", - "react-dom": "^18.0.0 || ^0.0.0" + "gatsby": "^4.0.0-next", + "gatsby-plugin-sharp": "^4.0.0-next" } }, - "node_modules/gatsby-sharp": { - "version": "1.13.0", - "resolved": "https://registry.npmjs.org/gatsby-sharp/-/gatsby-sharp-1.13.0.tgz", - "integrity": "sha512-DviUtgm7tatSd1Hm54o/orHimOcyXBO9OJkSfzEchPFClvOza+2Qe/lqZShio0gFDxmG0Jgn0XCLzG7uH5VyJQ==", + "node_modules/gatsby-remark-images/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", "dependencies": { - "sharp": "^0.32.6" + "color-convert": "^2.0.1" }, "engines": { - "node": ">=18.0.0" - } - }, - "node_modules/gatsby-sharp/node_modules/detect-libc": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/gatsby-remark-images/node_modules/chalk": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", + "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", + "dependencies": { + "ansi-styles": "^4.1.0", + "supports-color": "^7.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" + } + }, + "node_modules/gatsby-remark-images/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/gatsby-remark-images/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==" + }, + "node_modules/gatsby-remark-images/node_modules/fs-extra": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz", + "integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==", + "dependencies": { + "graceful-fs": "^4.2.0", + "jsonfile": "^6.0.1", + "universalify": "^2.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/gatsby-remark-images/node_modules/gatsby-core-utils": { + "version": "3.25.0", + "resolved": "https://registry.npmjs.org/gatsby-core-utils/-/gatsby-core-utils-3.25.0.tgz", + "integrity": "sha512-lmMDwbnKpqAi+8WWd7MvCTCx3E0u7j8sbVgydERNCYVxKVpzD/aLCH4WPb4EE9m1H1rSm76w0Z+MaentyB/c/Q==", + "dependencies": { + "@babel/runtime": "^7.15.4", + "ci-info": "2.0.0", + "configstore": "^5.0.1", + "fastq": "^1.13.0", + "file-type": "^16.5.3", + "fs-extra": "^10.1.0", + "got": "^11.8.5", + "import-from": "^4.0.0", + "lmdb": "2.5.3", + "lock": "^1.1.0", + "node-object-hash": "^2.3.10", + "proper-lockfile": "^4.1.2", + "resolve-from": "^5.0.0", + "tmp": "^0.2.1", + "xdg-basedir": "^4.0.0" + }, + "engines": { + "node": ">=14.15.0" + } + }, + "node_modules/gatsby-remark-images/node_modules/has-flag": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", + "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/gatsby-remark-images/node_modules/supports-color": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", + "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", + "dependencies": { + "has-flag": "^4.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/gatsby-script": { + "version": "2.13.0", + "resolved": "https://registry.npmjs.org/gatsby-script/-/gatsby-script-2.13.0.tgz", + "integrity": "sha512-TGNQGerf1NMJrgJkWxWrW6FFMAuC0L76WlyZgGXmhckPW/x7V1SxZrm0a2Q99kRHyoC59RYl2gTQWHaIwV+ZjA==", + "engines": { + "node": ">=18.0.0" + }, + "peerDependencies": { + "@gatsbyjs/reach-router": "^2.0.0", + "react": "^18.0.0 || ^0.0.0", + "react-dom": "^18.0.0 || ^0.0.0" + } + }, + "node_modules/gatsby-sharp": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/gatsby-sharp/-/gatsby-sharp-1.13.0.tgz", + "integrity": "sha512-DviUtgm7tatSd1Hm54o/orHimOcyXBO9OJkSfzEchPFClvOza+2Qe/lqZShio0gFDxmG0Jgn0XCLzG7uH5VyJQ==", + "dependencies": { + "sharp": "^0.32.6" + }, + "engines": { + "node": ">=18.0.0" + } + }, + "node_modules/gatsby-sharp/node_modules/detect-libc": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.0.3.tgz", "integrity": "sha512-bwy0MGW55bG41VqxxypOsdSdGqLwXPI/focwgTYCFMbdUiBAxLg9CFzG08sz2aqzknwiX7Hkl0bQENjg8iLByw==", @@ -15677,14 +14933,6 @@ "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==" }, - "node_modules/gatsby/node_modules/style-to-object": { - "version": "0.4.4", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", - "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", - "dependencies": { - "inline-style-parser": "0.1.1" - } - }, "node_modules/gatsby/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -15937,9 +15185,9 @@ "integrity": "sha512-SyHy3T1v2NUXn29OsWdxmK6RwHD+vkj3v8en8AOBZ1wBQ/hCAQ5bAQTD02kW4W9tUp/3Qh6J8r9EvntiyCmOOw==" }, "node_modules/github-slugger": { - "version": "1.5.0", - "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-1.5.0.tgz", - "integrity": "sha512-wIh+gKBI9Nshz2o46B0B3f5k/W+WI9ZAv6y5Dn5WJ5SK1t0TnDimB4WE5rmTD05ZAIn8HALCZVmCsvj0w0v0lw==" + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/github-slugger/-/github-slugger-2.0.0.tgz", + "integrity": "sha512-IaOQ9puYtjrkq7Y0Ygl9KDZnrf/aiUJYUpVf89y8kyaxbRG7Y1SrX/jaumrv81vc61+kiMempujsM3Yw7w5qcw==" }, "node_modules/glob": { "version": "7.2.3", @@ -16485,18 +15733,13 @@ "node": ">= 0.4" } }, - "node_modules/hast-to-hyperscript": { - "version": "9.0.1", - "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz", - "integrity": "sha512-zQgLKqF+O2F72S1aa4y2ivxzSlko3MAvxkwG8ehGmNiqd98BIN3JM1rAJPmplEyLmGLO2QZYJtIneOSZ2YbJuA==", + "node_modules/hast-util-excerpt": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hast-util-excerpt/-/hast-util-excerpt-1.0.2.tgz", + "integrity": "sha512-5q3+CAQwLBzcw4/1nwkdh91BSmoXmJSJQ1fYflhm2XpbYbrnXL+rgAbZsioVgVKV3xBlO1C9jp0wQ3ZYzfWibg==", "dependencies": { - "@types/unist": "^2.0.3", - "comma-separated-tokens": "^1.0.0", - "property-information": "^5.3.0", - "space-separated-tokens": "^1.0.0", - "style-to-object": "^0.3.0", - "unist-util-is": "^4.0.0", - "web-namespaces": "^1.0.0" + "@types/hast": "^2.0.0", + "hast-util-truncate": "^1.0.0" }, "funding": { "type": "opencollective", @@ -16504,16 +15747,39 @@ } }, "node_modules/hast-util-from-parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-6.0.1.tgz", - "integrity": "sha512-jeJUWiN5pSxW12Rh01smtVkZgZr33wBokLzKLwinYOUfSzm1Nl/c3GUGebDyOKjdsRgMvoVbV0VpAcpjF4NrJA==", + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/hast-util-from-parse5/-/hast-util-from-parse5-7.1.2.tgz", + "integrity": "sha512-Nz7FfPBuljzsN3tCQ4kCBKqdNhQE2l0Tn+X1ubgKBPRoiDIu1mL08Cfw4k7q71+Duyaw7DXDN+VTAp4Vh3oCOw==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "hastscript": "^7.0.0", + "property-information": "^6.0.0", + "vfile": "^5.0.0", + "vfile-location": "^4.0.0", + "web-namespaces": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-has-property": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-has-property/-/hast-util-has-property-2.0.1.tgz", + "integrity": "sha512-X2+RwZIMTMKpXUzlotatPzWj8bspCymtXH3cfG3iQKV+wPF53Vgaqxi/eLqGck0wKq1kS9nvoB1wchbCPEL8sg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-is-element": { + "version": "2.1.3", + "resolved": "https://registry.npmjs.org/hast-util-is-element/-/hast-util-is-element-2.1.3.tgz", + "integrity": "sha512-O1bKah6mhgEq2WtVMk+Ta5K7pPMqsBBlmzysLdcwKVrqzZQ0CHqUPiIVspNhAG1rvxpvJjtGee17XfauZYKqVA==", "dependencies": { - "@types/parse5": "^5.0.0", - "hastscript": "^6.0.0", - "property-information": "^5.0.0", - "vfile": "^4.0.0", - "vfile-location": "^3.2.0", - "web-namespaces": "^1.0.0" + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0" }, "funding": { "type": "opencollective", @@ -16521,29 +15787,90 @@ } }, "node_modules/hast-util-parse-selector": { - "version": "2.2.5", - "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-2.2.5.tgz", - "integrity": "sha512-7j6mrk/qqkSehsM92wQjdIgWM2/BW61u/53G6xmC8i1OmEdKLHbk419QKQUjz6LglWsfqoiHmyMRkP1BGjecNQ==", + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/hast-util-parse-selector/-/hast-util-parse-selector-3.1.1.tgz", + "integrity": "sha512-jdlwBjEexy1oGz0aJ2f4GKMaVKkA9jwjr4MjAAI22E5fM/TXVZHuS5OpONtdeIkRKqAaryQ2E9xNQxijoThSZA==", + "dependencies": { + "@types/hast": "^2.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/hast-util-raw": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-6.0.1.tgz", - "integrity": "sha512-ZMuiYA+UF7BXBtsTBNcLBF5HzXzkyE6MLzJnL605LKE8GJylNjGc4jjxazAHUtcwT5/CEt6afRKViYB4X66dig==", + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/hast-util-raw/-/hast-util-raw-7.2.3.tgz", + "integrity": "sha512-RujVQfVsOrxzPOPSzZFiwofMArbQke6DJjnFfceiEbFh7S05CbPt0cYN+A5YeD3pso0JQk6O1aHBnx9+Pm2uqg==", "dependencies": { "@types/hast": "^2.0.0", - "hast-util-from-parse5": "^6.0.0", - "hast-util-to-parse5": "^6.0.0", - "html-void-elements": "^1.0.0", + "@types/parse5": "^6.0.0", + "hast-util-from-parse5": "^7.0.0", + "hast-util-to-parse5": "^7.0.0", + "html-void-elements": "^2.0.0", "parse5": "^6.0.0", - "unist-util-position": "^3.0.0", - "vfile": "^4.0.0", - "web-namespaces": "^1.0.0", - "xtend": "^4.0.0", - "zwitch": "^1.0.0" + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0", + "vfile": "^5.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-raw/node_modules/parse5": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", + "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + }, + "node_modules/hast-util-select": { + "version": "5.0.5", + "resolved": "https://registry.npmjs.org/hast-util-select/-/hast-util-select-5.0.5.tgz", + "integrity": "sha512-QQhWMhgTFRhCaQdgTKzZ5g31GLQ9qRb1hZtDPMqQaOhpLBziWcshUS0uCR5IJ0U1jrK/mxg35fmcq+Dp/Cy2Aw==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "bcp-47-match": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "css-selector-parser": "^1.0.0", + "direction": "^2.0.0", + "hast-util-has-property": "^2.0.0", + "hast-util-to-string": "^2.0.0", + "hast-util-whitespace": "^2.0.0", + "not": "^0.1.0", + "nth-check": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "unist-util-visit": "^4.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-estree": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/hast-util-to-estree/-/hast-util-to-estree-2.3.3.tgz", + "integrity": "sha512-ihhPIUPxN0v0w6M5+IiAZZrn0LH2uZomeWwhn7uP7avZC6TE7lIiEh2yBMPr5+zi1aUCXq6VoYRgs2Bw9xmycQ==", + "dependencies": { + "@types/estree": "^1.0.0", + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "estree-util-attach-comments": "^2.0.0", + "estree-util-is-identifier-name": "^2.0.0", + "hast-util-whitespace": "^2.0.0", + "mdast-util-mdx-expression": "^1.0.0", + "mdast-util-mdxjs-esm": "^1.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.4.1", + "unist-util-position": "^4.0.0", + "zwitch": "^2.0.0" }, "funding": { "type": "opencollective", @@ -16551,31 +15878,81 @@ } }, "node_modules/hast-util-to-parse5": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-6.0.0.tgz", - "integrity": "sha512-Lu5m6Lgm/fWuz8eWnrKezHtVY83JeRGaNQ2kn9aJgqaxvVkFCZQBEhgodZUDUvoodgyROHDb3r5IxAEdl6suJQ==", + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/hast-util-to-parse5/-/hast-util-to-parse5-7.1.0.tgz", + "integrity": "sha512-YNRgAJkH2Jky5ySkIqFXTQiaqcAtJyVE+D5lkN6CdtOqrnkLfGYYrEcKuHOJZlp+MwjSwuD3fZuawI+sic/RBw==", "dependencies": { - "hast-to-hyperscript": "^9.0.0", - "property-information": "^5.0.0", - "web-namespaces": "^1.0.0", - "xtend": "^4.0.0", - "zwitch": "^1.0.0" + "@types/hast": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0", + "web-namespaces": "^2.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hast-util-to-string/-/hast-util-to-string-2.0.0.tgz", + "integrity": "sha512-02AQ3vLhuH3FisaMM+i/9sm4OXGSq1UhOOCpTLLQtHdL3tZt7qil69r8M8iDkZYyC0HCFylcYoP+8IO7ddta1A==", + "dependencies": { + "@types/hast": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-to-text": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/hast-util-to-text/-/hast-util-to-text-3.1.2.tgz", + "integrity": "sha512-tcllLfp23dJJ+ju5wCCZHVpzsQQ43+moJbqVX3jNWPB7z/KFC4FyZD6R7y94cHL6MQ33YtMZL8Z0aIXXI4XFTw==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/unist": "^2.0.0", + "hast-util-is-element": "^2.0.0", + "unist-util-find-after": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/hast-util-truncate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/hast-util-truncate/-/hast-util-truncate-1.0.2.tgz", + "integrity": "sha512-IWLuKZGZ9YaA4mmxlYyQgxbYARRRjomRaPnwvgwhC6VfUD9uAhdDa6+B0ad23rOoC4RyLVMB8fIE40x/O6qK1Q==", + "dependencies": { + "@types/hast": "^2.0.0", + "micromark-util-character": "^1.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, + "node_modules/hast-util-whitespace": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/hast-util-whitespace/-/hast-util-whitespace-2.0.1.tgz", + "integrity": "sha512-nAxA0v8+vXSBDt3AnRUNjyRIQ0rD+ntpbAp4LnPkumc5M9yUbSMa4XDU9Q6etY4f1Wp4bNgvc1yjiZtsTTrSng==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/hastscript": { - "version": "6.0.0", - "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-6.0.0.tgz", - "integrity": "sha512-nDM6bvd7lIqDUiYEiu5Sl/+6ReP0BMk/2f4U/Rooccxkj0P5nm+acM5PrGJ/t5I8qPGiqZSE6hVAwZEdZIvP4w==", + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/hastscript/-/hastscript-7.2.0.tgz", + "integrity": "sha512-TtYPq24IldU8iKoJQqvZOuhi5CyCQRAbvDOX0x1eW6rsHSxa/1i2CCiptNTotGHJ3VoHRGmqiv6/D3q113ikkw==", "dependencies": { "@types/hast": "^2.0.0", - "comma-separated-tokens": "^1.0.0", - "hast-util-parse-selector": "^2.0.0", - "property-information": "^5.0.0", - "space-separated-tokens": "^1.0.0" + "comma-separated-tokens": "^2.0.0", + "hast-util-parse-selector": "^3.0.0", + "property-information": "^6.0.0", + "space-separated-tokens": "^2.0.0" }, "funding": { "type": "opencollective", @@ -16670,9 +16047,9 @@ "dev": true }, "node_modules/html-void-elements": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-1.0.5.tgz", - "integrity": "sha512-uE/TxKuyNIcx44cIWnjr/rfIATDH7ZaOMmstu0CwhFG1Dunhlp4OC6/NMbhiwoq5BpW0ubi303qnEk/PZj614w==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/html-void-elements/-/html-void-elements-2.0.1.tgz", + "integrity": "sha512-0quDb7s97CfemeJAnW9wC0hw78MtW7NU3hqtCD75g2vFlDLt36llsYD7uB7SUzojLMP24N5IatXf7ylGXiGG9A==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -16895,6 +16272,16 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/import-meta-resolve": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/import-meta-resolve/-/import-meta-resolve-2.2.2.tgz", + "integrity": "sha512-f8KcQ1D80V7RnqVm+/lirO9zkOxjGxhaTC1IPrBGd3MEfNgmNG67tSUO9gTi2F3Blr2Az6g1vocaxzkVnWl9MA==", + "dev": true, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/imurmurhash": { "version": "0.1.4", "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", @@ -17118,14 +16505,6 @@ "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/is-alphanumeric": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/is-alphanumeric/-/is-alphanumeric-1.0.0.tgz", - "integrity": "sha512-ZmRL7++ZkcMOfDuWZuMJyIVLr2keE1o/DeNWh1EmgqGhUcV+9BIVsx0BcSBOHTZqzjs4+dISzr2KAeBEWGgXeA==", - "engines": { - "node": ">=0.10.0" - } - }, "node_modules/is-alphanumerical": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-1.0.4.tgz", @@ -17375,6 +16754,12 @@ "node": ">=0.10.0" } }, + "node_modules/is-empty": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/is-empty/-/is-empty-1.2.0.tgz", + "integrity": "sha512-F2FnH/otLNJv0J6wc73A5Xo7oHLNnqplYqZhUu01tD54DIPvxIRSTSLkrUB/M0nHO4vo1O9PDfN4KoTxCzLh/w==", + "dev": true + }, "node_modules/is-equal-shallow": { "version": "0.1.3", "resolved": "https://registry.npmjs.org/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz", @@ -17574,6 +16959,7 @@ "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", "integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==", + "dev": true, "engines": { "node": ">=8" } @@ -17620,6 +17006,14 @@ "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==" }, + "node_modules/is-reference": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-3.0.3.tgz", + "integrity": "sha512-ixkJoqQvAP88E6wLydLGGqCJsrFUnqoH6HnaczB8XmDH1oaWU+xxdptvikTgaEhtZ53Ky6YXiBuUI2WXLMCwjw==", + "dependencies": { + "@types/estree": "^1.0.6" + } + }, "node_modules/is-regex": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.2.1.tgz", @@ -17839,15 +17233,6 @@ "url": "https://github.com/sponsors/ljharb" } }, - "node_modules/is-whitespace-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-whitespace-character/-/is-whitespace-character-1.0.4.tgz", - "integrity": "sha512-SDweEzfIZM0SJV0EUga669UTKlmL0Pq8Lno0QDQsPnvECB3IM2aP0gdx5TrU0A01MAPfViaZiI2V1QMZLaKK5w==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/is-windows": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", @@ -17856,15 +17241,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-word-character": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/is-word-character/-/is-word-character-1.0.4.tgz", - "integrity": "sha512-5SMO8RVennx3nZrqtKwCGyyetPE9VDba5ugvKLaD4KopPG5kR4mQ7tNt/r7feL5yt5h3lpuBbIUmCOG2eSzXHA==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/is-wsl": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/is-wsl/-/is-wsl-3.1.0.tgz", @@ -17991,12 +17367,6 @@ "@sideway/pinpoint": "^2.0.0" } }, - "node_modules/jquery": { - "version": "3.7.1", - "resolved": "https://registry.npmjs.org/jquery/-/jquery-3.7.1.tgz", - "integrity": "sha512-m4avr8yL8kmFN8psrbFFFmB/If14iN5o9nw/NgnnM+kybDJpRsAynV2BsfpTYrTRysYUdADVD7CkUUizgkpLfg==", - "peer": true - }, "node_modules/js-cookie": { "version": "2.2.1", "resolved": "https://registry.npmjs.org/js-cookie/-/js-cookie-2.2.1.tgz", @@ -18256,12 +17626,26 @@ "resolved": "https://registry.npmjs.org/node-addon-api/-/node-addon-api-4.3.0.tgz", "integrity": "sha512-73sE9+3UaLYYFmDsFZnqCInzPyh3MqIwZO9cw58yIqAZhONrrabrYyYe3TuIqtIiOuTXVhsGau8hcrhhwSsDIQ==" }, - "node_modules/load-script": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz", - "integrity": "sha512-kPEjMFtZvwL9TaZo0uZ2ml+Ye9HUMmPwbYRJ324qF9tqMejwykJ5ggTyvzmrbBeapCAbk98BSbTeovHEEP1uCA==" - }, - "node_modules/loader-runner": { + "node_modules/load-plugin": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/load-plugin/-/load-plugin-5.1.0.tgz", + "integrity": "sha512-Lg1CZa1CFj2CbNaxijTL6PCbzd4qGTlZov+iH2p5Xwy/ApcZJh+i6jMN2cYePouTfjJfrNu3nXFdEw8LvbjPFQ==", + "dev": true, + "dependencies": { + "@npmcli/config": "^6.0.0", + "import-meta-resolve": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/load-script": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/load-script/-/load-script-1.0.0.tgz", + "integrity": "sha512-kPEjMFtZvwL9TaZo0uZ2ml+Ye9HUMmPwbYRJ324qF9tqMejwykJ5ggTyvzmrbBeapCAbk98BSbTeovHEEP1uCA==" + }, + "node_modules/loader-runner": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.0.tgz", "integrity": "sha512-3R/1M+yS3j5ou80Me59j7F9IMs4PXs3VqRrm0TU3AbKPxlmpoY1TNscJV/oGJXo8qCatFGTfDbY6W6ipGOYXfg==", @@ -18311,21 +17695,11 @@ "resolved": "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz", "integrity": "sha512-mKnC+QJ9pWVzv+C4/U3rRsHapFfHvQFoFB92e52xeyGMcX6/OlIl78je1u8vePzYZSkkogMPJ2yjxxsb89cxyw==" }, - "node_modules/lodash.assignin": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.assignin/-/lodash.assignin-4.2.0.tgz", - "integrity": "sha512-yX/rx6d/UTVh7sSVWVSIMjfnz95evAgDFdb1ZozC35I9mSFCkmzptOzevxjgbQUsc78NR44LVHWjsoMQXy9FDg==" - }, "node_modules/lodash.assignwith": { "version": "4.2.0", "resolved": "https://registry.npmjs.org/lodash.assignwith/-/lodash.assignwith-4.2.0.tgz", "integrity": "sha512-ZznplvbvtjK2gMvnQ1BR/zqPFZmS6jbK4p+6Up4xcRYA7yMIwxHCfbTcrYxXKzzqLsQ05eJPVznEW3tuwV7k1g==" }, - "node_modules/lodash.bind": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/lodash.bind/-/lodash.bind-4.2.1.tgz", - "integrity": "sha512-lxdsn7xxlCymgLYo1gGvVrfHmkjDiyqVv62FAeF2i5ta72BipE1SLxw8hPEPLhD4/247Ijw07UQH7Hq/chT5LA==" - }, "node_modules/lodash.clonedeep": { "version": "4.5.0", "resolved": "https://registry.npmjs.org/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz", @@ -18341,31 +17715,16 @@ "resolved": "https://registry.npmjs.org/lodash.deburr/-/lodash.deburr-4.1.0.tgz", "integrity": "sha512-m/M1U1f3ddMCs6Hq2tAsYThTBDaAKFDX3dwDo97GEYzamXi9SqUpjWi/Rrj/gf3X2n8ktwgZrlP1z6E3v/IExQ==" }, - "node_modules/lodash.defaults": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/lodash.defaults/-/lodash.defaults-4.2.0.tgz", - "integrity": "sha512-qjxPLHd3r5DnsdGacqOMU6pb/avJzdh9tFX2ymgoZE27BmjXrNy/y4LoaiTeAb+O3gL8AfpJGtqfX/ae2leYYQ==" - }, "node_modules/lodash.every": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.every/-/lodash.every-4.6.0.tgz", "integrity": "sha512-isF82d+65/sNvQ3aaQAW7LLHnnTxSN/2fm4rhYyuufLzA4VtHz6y6S5vFwe6PQVr2xdqUOyxBbTNKDpnmeu50w==" }, - "node_modules/lodash.filter": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.filter/-/lodash.filter-4.6.0.tgz", - "integrity": "sha512-pXYUy7PR8BCLwX5mgJ/aNtyOvuJTdZAo9EQFUvMIYugqmJxnrYaANvTbgndOzHSCSR0wnlBBfRXJL5SbWxo3FQ==" - }, "node_modules/lodash.find": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/lodash.find/-/lodash.find-4.6.0.tgz", "integrity": "sha512-yaRZoAV3Xq28F1iafWN1+a0rflOej93l1DQUejs3SZ41h2O9UJBoS9aueGjPDgAl4B6tPC0NuuchLKaDQQ3Isg==" }, - "node_modules/lodash.flatten": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.flatten/-/lodash.flatten-4.4.0.tgz", - "integrity": "sha512-C5N2Z3DgnnKr0LOpv/hKCgKdb7ZZwafIrsesve6lmzvZIRZRGaZ/l6Q8+2W7NaT+ZwO3fFlSCzCzrDCFdJfZ4g==" - }, "node_modules/lodash.flattendeep": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz", @@ -18411,26 +17770,6 @@ "resolved": "https://registry.npmjs.org/lodash.merge/-/lodash.merge-4.6.2.tgz", "integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==" }, - "node_modules/lodash.pick": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/lodash.pick/-/lodash.pick-4.4.0.tgz", - "integrity": "sha512-hXt6Ul/5yWjfklSGvLQl8vM//l3FtyHZeuelpzK6mm99pNvN9yTDruNZPEJZD1oWrqo+izBmB7oUfWgcCX7s4Q==" - }, - "node_modules/lodash.reduce": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.reduce/-/lodash.reduce-4.6.0.tgz", - "integrity": "sha512-6raRe2vxCYBhpBu+B+TtNGUzah+hQjVdu3E17wfusjyrXBka2nBS8OH/gjVZ5PvHOhWmIZTYri09Z6n/QfnNMw==" - }, - "node_modules/lodash.reject": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.reject/-/lodash.reject-4.6.0.tgz", - "integrity": "sha512-qkTuvgEzYdyhiJBx42YPzPo71R1aEr0z79kAv7Ixg8wPFEjgRgJdUsGMG3Hf3OYSF/kHI79XhNlt+5Ar6OzwxQ==" - }, - "node_modules/lodash.some": { - "version": "4.6.0", - "resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz", - "integrity": "sha512-j7MJE+TuT51q9ggt4fSgVqro163BEFjAt3u97IqU+JA2DkWl80nFTrowzLpZ/BnpN7rrl0JA/593NAdd8p/scQ==" - }, "node_modules/lodash.throttle": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/lodash.throttle/-/lodash.throttle-4.1.1.tgz", @@ -18447,9 +17786,9 @@ "integrity": "sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ==" }, "node_modules/longest-streak": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", - "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-3.1.0.tgz", + "integrity": "sha512-9Ri+o0JYgehTaVBBDoMqIl8GXtbWg711O3srftcHhZ0dqnETqLaoIK0x17fUw9rFSlK/0NlsKe0Ahhyl5pXE2g==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -18586,20 +17925,26 @@ "node": ">=0.10.0" } }, - "node_modules/markdown-escapes": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/markdown-escapes/-/markdown-escapes-1.0.4.tgz", - "integrity": "sha512-8z4efJYk43E0upd0NbVXwgSTQs6cT3T06etieCMEg7dRbzCbxUCK/GHlX8mhHRDcp+OLlHkPKsvqQTCvsRl2cg==", + "node_modules/markdown-extensions": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/markdown-extensions/-/markdown-extensions-1.1.1.tgz", + "integrity": "sha512-WWC0ZuMzCyDHYCasEGs4IPvLyTGftYwh6wIEOULOF0HXcqZlhwRzrK0w2VUlxWA98xnvb/jszw4ZSkJ6ADpM6Q==", + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/markdown-table": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-2.0.0.tgz", + "integrity": "sha512-Ezda85ToJUBhM6WGaG6veasyym+Tbs3cMAw/ZhOPqXiYsr0jgocBV3j3nx+4lk47plLlIqjwuTm/ywVI+zjJ/A==", + "dependencies": { + "repeat-string": "^1.0.0" + }, "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" } }, - "node_modules/markdown-table": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/markdown-table/-/markdown-table-1.1.3.tgz", - "integrity": "sha512-1RUZVgQlpJSPWYbFSpmudq5nHY1doEIv89gBtF0s4gW1GF2XorxcA/70M5vq7rLv0a6mhOUccRsqkwhwLCIQ2Q==" - }, "node_modules/math-intrinsics": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/math-intrinsics/-/math-intrinsics-1.1.0.tgz", @@ -18614,303 +17959,1669 @@ "integrity": "sha512-rUxjysqif/BZQH2yhd5Aaq7vXMSx9NdEsQcyA07uEzIvxgI7zIr33gGsh+RU0/XjmQpCW7RsVof1vlkvQVCK5A==", "dev": true }, - "node_modules/mdast-squeeze-paragraphs": { + "node_modules/mdast-util-definitions": { "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-squeeze-paragraphs/-/mdast-squeeze-paragraphs-4.0.0.tgz", - "integrity": "sha512-zxdPn69hkQ1rm4J+2Cs2j6wDEv7O17TfXTJ33tl/+JPIoEmtV9t2ZzBM5LPHE8QlHsmVD8t3vPKCyY3oH+H8MQ==", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz", + "integrity": "sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==", "dependencies": { - "unist-util-remove": "^2.0.0" + "unist-util-visit": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-squeeze-paragraphs/node_modules/unist-util-remove": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/unist-util-remove/-/unist-util-remove-2.1.0.tgz", - "integrity": "sha512-J8NYPyBm4baYLdCbjmf1bhPu45Cr1MWTm77qd9istEkzWpnN6O9tMsEbB2JhNnBCqGENRqEWomQ+He6au0B27Q==", + "node_modules/mdast-util-definitions/node_modules/unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-definitions/node_modules/unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", "dependencies": { - "unist-util-is": "^4.0.0" + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-compact": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/mdast-util-compact/-/mdast-util-compact-1.0.4.tgz", - "integrity": "sha512-3YDMQHI5vRiS2uygEFYaqckibpJtKq5Sj2c8JioeOQBU6INpKbdWzfyLqFFnDwEcEnRFIdMsguzs5pC1Jp4Isg==", + "node_modules/mdast-util-find-and-replace": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/mdast-util-find-and-replace/-/mdast-util-find-and-replace-1.1.1.tgz", + "integrity": "sha512-9cKl33Y21lyckGzpSmEQnIDjEfeeWelN5s1kUW1LwdB0Fkuq2u+4GdqcGEygYxJE8GVqCl0741bYXHgamfWAZA==", "dependencies": { - "unist-util-visit": "^1.1.0" + "escape-string-regexp": "^4.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-compact/node_modules/unist-util-is": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", - "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==" + "node_modules/mdast-util-find-and-replace/node_modules/unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } }, - "node_modules/mdast-util-compact/node_modules/unist-util-visit": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", - "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "node_modules/mdast-util-from-markdown": { + "version": "0.8.5", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-0.8.5.tgz", + "integrity": "sha512-2hkTXtYYnr+NubD/g6KGBS/0mFmBcifAsI0yIWRiRo0PjVs6SSOSOdtzbp6kSGnShDN6G5aWZpKQ2lWRy27mWQ==", + "dev": true, "dependencies": { - "unist-util-visit-parents": "^2.0.0" + "@types/mdast": "^3.0.0", + "mdast-util-to-string": "^2.0.0", + "micromark": "~2.11.0", + "parse-entities": "^2.0.0", + "unist-util-stringify-position": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-compact/node_modules/unist-util-visit-parents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", - "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "node_modules/mdast-util-from-markdown/node_modules/unist-util-stringify-position": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", + "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "dev": true, "dependencies": { - "unist-util-is": "^3.0.0" + "@types/unist": "^2.0.2" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-definitions": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-4.0.0.tgz", - "integrity": "sha512-k8AJ6aNnUkB7IE+5azR9h81O5EQ/cTDXtWdMq9Kk5KcEW/8ritU5CeLg/9HhOC++nALHBlaogJ5jz0Ybk3kPMQ==", + "node_modules/mdast-util-gfm": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-gfm/-/mdast-util-gfm-0.1.2.tgz", + "integrity": "sha512-NNkhDx/qYcuOWB7xHUGWZYVXvjPFFd6afg6/e2g+SV4r9q5XUcCbV4Wfa3DLYIiD+xAEZc6K4MGaE/m0KDcPwQ==", "dependencies": { - "unist-util-visit": "^2.0.0" + "mdast-util-gfm-autolink-literal": "^0.1.0", + "mdast-util-gfm-strikethrough": "^0.2.0", + "mdast-util-gfm-table": "^0.1.0", + "mdast-util-gfm-task-list-item": "^0.1.0", + "mdast-util-to-markdown": "^0.6.1" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-to-hast": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.0.1.tgz", - "integrity": "sha512-BW3LM9SEMnjf4HXXVApZMt8gLQWVNXc3jryK0nJu/rOXPOnlkUjmdkDlmxMirpbU9ILncGFIwLH/ubnWBbcdgA==", + "node_modules/mdast-util-gfm-autolink-literal": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-autolink-literal/-/mdast-util-gfm-autolink-literal-0.1.3.tgz", + "integrity": "sha512-GjmLjWrXg1wqMIO9+ZsRik/s7PLwTaeCHVB7vRxUwLntZc8mzmTsLVr6HW1yLokcnhfURsn5zmSVdi3/xWWu1A==", + "dependencies": { + "ccount": "^1.0.0", + "mdast-util-find-and-replace": "^1.1.0", + "micromark": "^2.11.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-autolink-literal/node_modules/ccount": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/ccount/-/ccount-1.1.0.tgz", + "integrity": "sha512-vlNK021QdI7PNeiUh/lKkC/mNHHfV0m/Ad5JoI0TYtlBnJAslM/JIkm/tGC88bkLIwO6OQ5uV6ztS6kVAtCDlg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-gfm-strikethrough": { + "version": "0.2.3", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-strikethrough/-/mdast-util-gfm-strikethrough-0.2.3.tgz", + "integrity": "sha512-5OQLXpt6qdbttcDG/UxYY7Yjj3e8P7X16LzvpX8pIQPYJ/C2Z1qFGMmcw+1PZMUM3Z8wt8NRfYTvCni93mgsgA==", + "dependencies": { + "mdast-util-to-markdown": "^0.6.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-strikethrough/node_modules/longest-streak": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-gfm-strikethrough/node_modules/mdast-util-to-markdown": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", + "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", "dependencies": { - "@types/mdast": "^3.0.0", "@types/unist": "^2.0.0", - "mdast-util-definitions": "^4.0.0", - "mdurl": "^1.0.0", - "unist-builder": "^2.0.0", - "unist-util-generated": "^1.0.0", - "unist-util-position": "^3.0.0", - "unist-util-visit": "^2.0.0" + "longest-streak": "^2.0.0", + "mdast-util-to-string": "^2.0.0", + "parse-entities": "^2.0.0", + "repeat-string": "^1.0.0", + "zwitch": "^1.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-to-nlcst": { - "version": "3.2.3", - "resolved": "https://registry.npmjs.org/mdast-util-to-nlcst/-/mdast-util-to-nlcst-3.2.3.tgz", - "integrity": "sha512-hPIsgEg7zCvdU6/qvjcR6lCmJeRuIEpZGY5xBV+pqzuMOvQajyyF8b6f24f8k3Rw8u40GwkI3aAxUXr3bB2xag==", + "node_modules/mdast-util-gfm-strikethrough/node_modules/zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-gfm-table": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-table/-/mdast-util-gfm-table-0.1.6.tgz", + "integrity": "sha512-j4yDxQ66AJSBwGkbpFEp9uG/LS1tZV3P33fN1gkyRB2LoRL+RR3f76m0HPHaby6F4Z5xr9Fv1URmATlRRUIpRQ==", "dependencies": { - "nlcst-to-string": "^2.0.0", - "repeat-string": "^1.5.2", - "unist-util-position": "^3.0.0", - "vfile-location": "^2.0.0" + "markdown-table": "^2.0.0", + "mdast-util-to-markdown": "~0.6.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-to-nlcst/node_modules/vfile-location": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", - "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==", + "node_modules/mdast-util-gfm-table/node_modules/longest-streak": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-gfm-table/node_modules/mdast-util-to-markdown": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", + "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "longest-streak": "^2.0.0", + "mdast-util-to-string": "^2.0.0", + "parse-entities": "^2.0.0", + "repeat-string": "^1.0.0", + "zwitch": "^1.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-to-string": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-1.1.0.tgz", - "integrity": "sha512-jVU0Nr2B9X3MU4tSK7JP1CMkSvOj7X5l/GboG1tKRw52lLF1x2Ju92Ms9tNetCcbfX3hzlM73zYo2NKkWSfF/A==", + "node_modules/mdast-util-gfm-table/node_modules/zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-gfm-task-list-item": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/mdast-util-gfm-task-list-item/-/mdast-util-gfm-task-list-item-0.1.6.tgz", + "integrity": "sha512-/d51FFIfPsSmCIRNp7E6pozM9z1GYPIkSy1urQ8s/o4TC22BZ7DqfHFWiqBD23bc7J3vV1Fc9O4QIHBlfuit8A==", + "dependencies": { + "mdast-util-to-markdown": "~0.6.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/mdast-util-toc": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mdast-util-toc/-/mdast-util-toc-3.1.0.tgz", - "integrity": "sha512-Za0hqL1PqWrvxGtA/3NH9D5nhGAUS9grMM4obEAz5+zsk1RIw/vWUchkaoDLNdrwk05A0CSC5eEXng36/1qE5w==", + "node_modules/mdast-util-gfm-task-list-item/node_modules/longest-streak": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-gfm-task-list-item/node_modules/mdast-util-to-markdown": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", + "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "longest-streak": "^2.0.0", + "mdast-util-to-string": "^2.0.0", + "parse-entities": "^2.0.0", + "repeat-string": "^1.0.0", + "zwitch": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm-task-list-item/node_modules/zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-gfm/node_modules/longest-streak": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/longest-streak/-/longest-streak-2.0.4.tgz", + "integrity": "sha512-vM6rUVCVUJJt33bnmHiZEvr7wPT78ztX7rojL+LW51bHtLh6HTjx84LA5W4+oa6aKEJA7jJu5LR6vQRBpA5DVg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-gfm/node_modules/mdast-util-to-markdown": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-0.6.5.tgz", + "integrity": "sha512-XeV9sDE7ZlOQvs45C9UKMtfTcctcaj/pGwH8YLbMHoMOXNNCn2LsqVQOqrF1+/NU8lKDAqozme9SCXWyo9oAcQ==", + "dependencies": { + "@types/unist": "^2.0.0", + "longest-streak": "^2.0.0", + "mdast-util-to-string": "^2.0.0", + "parse-entities": "^2.0.0", + "repeat-string": "^1.0.0", + "zwitch": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-gfm/node_modules/zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-mdx": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdx/-/mdast-util-mdx-2.0.1.tgz", + "integrity": "sha512-38w5y+r8nyKlGvNjSEqWrhG0w5PmnRA+wnBvm+ulYCct7nsGYhFVb0lljS9bQav4psDAS1eGkP2LMVcZBi/aqw==", + "dependencies": { + "mdast-util-from-markdown": "^1.0.0", + "mdast-util-mdx-expression": "^1.0.0", + "mdast-util-mdx-jsx": "^2.0.0", + "mdast-util-mdxjs-esm": "^1.0.0", + "mdast-util-to-markdown": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-expression/-/mdast-util-mdx-expression-1.3.2.tgz", + "integrity": "sha512-xIPmR5ReJDu/DHH1OoIT1HkuybIfRGYRywC+gJtI7qHjCJp/M9jrmBEJW22O8lskDWm562BX2W8TiAwRTb0rKA==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "mdast-util-from-markdown": "^1.0.0", + "mdast-util-to-markdown": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression/node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/mdast-util-mdx-expression/node_modules/mdast-util-from-markdown": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "mdast-util-to-string": "^3.1.0", + "micromark": "^3.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression/node_modules/mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "dependencies": { + "@types/mdast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-expression/node_modules/micromark": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "micromark-core-commonmark": "^1.0.1", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/mdast-util-mdx-jsx": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/mdast-util-mdx-jsx/-/mdast-util-mdx-jsx-2.1.4.tgz", + "integrity": "sha512-DtMn9CmVhVzZx3f+optVDF8yFgQVt7FghCRNdlIaS3X5Bnym3hZwPbg/XW86vdpKjlc1PVj26SpnLGeJBXD3JA==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "ccount": "^2.0.0", + "mdast-util-from-markdown": "^1.1.0", + "mdast-util-to-markdown": "^1.3.0", + "parse-entities": "^4.0.0", + "stringify-entities": "^4.0.0", + "unist-util-remove-position": "^4.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx/node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/mdast-util-mdx-jsx/node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-mdx-jsx/node_modules/character-reference-invalid": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/character-reference-invalid/-/character-reference-invalid-2.0.1.tgz", + "integrity": "sha512-iBZ4F4wRbyORVsu0jPV7gXkOsGYjGHPmAyv+HiHG8gi5PtC9KI2j1+v8/tlibRvjoWX027ypmG/n0HtO5t7unw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-mdx-jsx/node_modules/is-alphabetical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphabetical/-/is-alphabetical-2.0.1.tgz", + "integrity": "sha512-FWyyY60MeTNyeSRpkM2Iry0G9hpr7/9kD40mD/cGQEuilcZYS4okz8SN2Q6rLCJ8gbCt6fN+rC+6tMGS99LaxQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-mdx-jsx/node_modules/is-alphanumerical": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-alphanumerical/-/is-alphanumerical-2.0.1.tgz", + "integrity": "sha512-hmbYhX/9MUMF5uh7tOXyK/n0ZvWpad5caBA17GsC6vyuCqaWliRG5K1qS9inmUhEMaOBIW7/whAnSwveW/LtZw==", + "dependencies": { + "is-alphabetical": "^2.0.0", + "is-decimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-mdx-jsx/node_modules/is-decimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-decimal/-/is-decimal-2.0.1.tgz", + "integrity": "sha512-AAB9hiomQs5DXWcRB1rqsxGUstbRroFOPPVAomNk/3XHR5JyEZChOyTWe2oayKnsSsr/kcGqF+z6yuH6HHpN0A==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-mdx-jsx/node_modules/is-hexadecimal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-hexadecimal/-/is-hexadecimal-2.0.1.tgz", + "integrity": "sha512-DgZQp241c8oO6cA1SbTEWiXeoxV42vlcJxgH+B3hi1AiqqKruZR3ZGF8In3fj4+/y/7rHvlOZLZtgJ/4ttYGZg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-mdx-jsx/node_modules/mdast-util-from-markdown": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "mdast-util-to-string": "^3.1.0", + "micromark": "^3.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx/node_modules/mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "dependencies": { + "@types/mdast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx-jsx/node_modules/micromark": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "micromark-core-commonmark": "^1.0.1", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/mdast-util-mdx-jsx/node_modules/parse-entities": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-4.0.2.tgz", + "integrity": "sha512-GG2AQYWoLgL877gQIKeRPGO1xF9+eG1ujIb5soS5gPvLQ1y2o8FL90w2QWNdf9I361Mpp7726c+lj3U0qK1uGw==", + "dependencies": { + "@types/unist": "^2.0.0", + "character-entities-legacy": "^3.0.0", + "character-reference-invalid": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "is-alphanumerical": "^2.0.0", + "is-decimal": "^2.0.0", + "is-hexadecimal": "^2.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/mdast-util-mdx/node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/mdast-util-mdx/node_modules/mdast-util-from-markdown": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "mdast-util-to-string": "^3.1.0", + "micromark": "^3.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx/node_modules/mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "dependencies": { + "@types/mdast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdx/node_modules/micromark": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "micromark-core-commonmark": "^1.0.1", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/mdast-util-mdxjs-esm": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-mdxjs-esm/-/mdast-util-mdxjs-esm-1.3.1.tgz", + "integrity": "sha512-SXqglS0HrEvSdUEfoXFtcg7DRl7S2cwOXc7jkuusG472Mmjag34DUDeOJUZtl+BVnyeO1frIgVpHlNRWc2gk/w==", + "dependencies": { + "@types/estree-jsx": "^1.0.0", + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "mdast-util-from-markdown": "^1.0.0", + "mdast-util-to-markdown": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm/node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/mdast-util-mdxjs-esm/node_modules/mdast-util-from-markdown": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "mdast-util-to-string": "^3.1.0", + "micromark": "^3.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "uvu": "^0.5.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm/node_modules/mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "dependencies": { + "@types/mdast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-mdxjs-esm/node_modules/micromark": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "micromark-core-commonmark": "^1.0.1", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/mdast-util-phrasing": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/mdast-util-phrasing/-/mdast-util-phrasing-3.0.1.tgz", + "integrity": "sha512-WmI1gTXUBJo4/ZmSk79Wcb2HcjPJBzM1nlI/OUWA8yk2X9ik3ffNbBGsU+09BFmXaL1IBb9fiuvq6/KMiNycSg==", + "dependencies": { + "@types/mdast": "^3.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-10.2.0.tgz", + "integrity": "sha512-JoPBfJ3gBnHZ18icCwHR50orC9kNH81tiR1gs01D8Q5YpV6adHNO9nKNuFBCJQ941/32PT1a63UF/DitmS3amQ==", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "mdast-util-definitions": "^4.0.0", + "mdurl": "^1.0.0", + "unist-builder": "^2.0.0", + "unist-util-generated": "^1.0.0", + "unist-util-position": "^3.0.0", + "unist-util-visit": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast/node_modules/unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast/node_modules/unist-util-position": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", + "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-hast/node_modules/unist-util-visit": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", + "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^4.0.0", + "unist-util-visit-parents": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-markdown/-/mdast-util-to-markdown-1.5.0.tgz", + "integrity": "sha512-bbv7TPv/WC49thZPg3jXuqzuvI45IL2EVAr/KxF0BSdHsU0ceFHOmwQn6evxAh1GaoK/6GQ1wp4R4oW2+LFL/A==", + "dependencies": { + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "longest-streak": "^3.0.0", + "mdast-util-phrasing": "^3.0.0", + "mdast-util-to-string": "^3.0.0", + "micromark-util-decode-string": "^1.0.0", + "unist-util-visit": "^4.0.0", + "zwitch": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-markdown/node_modules/mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "dependencies": { + "@types/mdast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-to-string": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-2.0.0.tgz", + "integrity": "sha512-AW4DRS3QbBayY/jJmD8437V1Gombjf8RSOUCMFBuo5iHi58AGEgVCKQ+ezHkZZDpAQS75hcBMpLqjpJTjtUL7w==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-toc": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/mdast-util-toc/-/mdast-util-toc-6.1.1.tgz", + "integrity": "sha512-Er21728Kow8hehecK2GZtb7Ny3omcoPUVrmObiSUwmoRYVZaXLR751QROEFjR8W/vAQdHMLj49Lz20J55XaNpw==", + "dependencies": { + "@types/extend": "^3.0.0", + "@types/mdast": "^3.0.0", + "extend": "^3.0.0", + "github-slugger": "^2.0.0", + "mdast-util-to-string": "^3.1.0", + "unist-util-is": "^5.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdast-util-toc/node_modules/mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", + "dependencies": { + "@types/mdast": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/mdn-data": { + "version": "2.0.14", + "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", + "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" + }, + "node_modules/mdurl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", + "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" + }, + "node_modules/meant": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/meant/-/meant-1.0.3.tgz", + "integrity": "sha512-88ZRGcNxAq4EH38cQ4D85PM57pikCwS8Z99EWHODxN7KBY+UuPiqzRTtZzS8KTXO/ywSWbdjjJST2Hly/EQxLw==" + }, + "node_modules/media-typer": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", + "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/mem": { + "version": "8.1.1", + "resolved": "https://registry.npmjs.org/mem/-/mem-8.1.1.tgz", + "integrity": "sha512-qFCFUDs7U3b8mBDPyz5EToEKoAkgCzqquIgi9nkkR9bixxOVOre+09lbuH7+9Kn2NFpm56M3GUWVbU2hQgdACA==", + "dependencies": { + "map-age-cleaner": "^0.1.3", + "mimic-fn": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/mem?sponsor=1" + } + }, + "node_modules/mem/node_modules/mimic-fn": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", + "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", + "engines": { + "node": ">=8" + } + }, + "node_modules/memfs": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", + "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "dependencies": { + "fs-monkey": "^1.0.4" + }, + "engines": { + "node": ">= 4.0.0" + } + }, + "node_modules/memoize-one": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", + "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" + }, + "node_modules/memoizee": { + "version": "0.4.17", + "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz", + "integrity": "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==", + "dependencies": { + "d": "^1.0.2", + "es5-ext": "^0.10.64", + "es6-weak-map": "^2.0.3", + "event-emitter": "^0.3.5", + "is-promise": "^2.2.2", + "lru-queue": "^0.1.0", + "next-tick": "^1.1.0", + "timers-ext": "^0.1.7" + }, + "engines": { + "node": ">=0.12" + } + }, + "node_modules/meow": { + "version": "7.1.1", + "resolved": "https://registry.npmjs.org/meow/-/meow-7.1.1.tgz", + "integrity": "sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA==", + "dependencies": { + "@types/minimist": "^1.2.0", + "camelcase-keys": "^6.2.2", + "decamelize-keys": "^1.1.0", + "hard-rejection": "^2.1.0", + "minimist-options": "4.1.0", + "normalize-package-data": "^2.5.0", + "read-pkg-up": "^7.0.1", + "redent": "^3.0.0", + "trim-newlines": "^3.0.0", + "type-fest": "^0.13.1", + "yargs-parser": "^18.1.3" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/meow/node_modules/type-fest": { + "version": "0.13.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", + "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-descriptors": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", + "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/merge-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", + "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" + }, + "node_modules/merge2": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", + "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", + "engines": { + "node": ">= 8" + } + }, + "node_modules/methods": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", + "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/micromark": { + "version": "2.11.4", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-2.11.4.tgz", + "integrity": "sha512-+WoovN/ppKolQOFIAajxi7Lu9kInbPxFuTBVEavFcL8eAfVstoc5MocPmqBeAdBOJV00uaVjegzH4+MA0DN/uA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "debug": "^4.0.0", + "parse-entities": "^2.0.0" + } + }, + "node_modules/micromark-core-commonmark": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-core-commonmark/-/micromark-core-commonmark-1.1.0.tgz", + "integrity": "sha512-BgHO1aRbolh2hcrzL2d1La37V0Aoz73ymF8rAcKnohLy93titmv62E0gP8Hrx9PKcKrqCZ1BbLGbP3bEhoXYlw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "decode-named-character-reference": "^1.0.0", + "micromark-factory-destination": "^1.0.0", + "micromark-factory-label": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-factory-title": "^1.0.0", + "micromark-factory-whitespace": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-classify-character": "^1.0.0", + "micromark-util-html-tag-name": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-extension-gfm": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm/-/micromark-extension-gfm-0.3.3.tgz", + "integrity": "sha512-oVN4zv5/tAIA+l3GbMi7lWeYpJ14oQyJ3uEim20ktYFAcfX1x3LNlFGGlmrZHt7u9YlKExmyJdDGaTt6cMSR/A==", + "dependencies": { + "micromark": "~2.11.0", + "micromark-extension-gfm-autolink-literal": "~0.5.0", + "micromark-extension-gfm-strikethrough": "~0.6.5", + "micromark-extension-gfm-table": "~0.4.0", + "micromark-extension-gfm-tagfilter": "~0.3.0", + "micromark-extension-gfm-task-list-item": "~0.3.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-autolink-literal": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-autolink-literal/-/micromark-extension-gfm-autolink-literal-0.5.7.tgz", + "integrity": "sha512-ePiDGH0/lhcngCe8FtH4ARFoxKTUelMp4L7Gg2pujYD5CSMb9PbblnyL+AAMud/SNMyusbS2XDSiPIRcQoNFAw==", + "dependencies": { + "micromark": "~2.11.3" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-strikethrough": { + "version": "0.6.5", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-strikethrough/-/micromark-extension-gfm-strikethrough-0.6.5.tgz", + "integrity": "sha512-PpOKlgokpQRwUesRwWEp+fHjGGkZEejj83k9gU5iXCbDG+XBA92BqnRKYJdfqfkrRcZRgGuPuXb7DaK/DmxOhw==", + "dependencies": { + "micromark": "~2.11.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-table": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-table/-/micromark-extension-gfm-table-0.4.3.tgz", + "integrity": "sha512-hVGvESPq0fk6ALWtomcwmgLvH8ZSVpcPjzi0AjPclB9FsVRgMtGZkUcpE0zgjOCFAznKepF4z3hX8z6e3HODdA==", + "dependencies": { + "micromark": "~2.11.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-tagfilter": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-tagfilter/-/micromark-extension-gfm-tagfilter-0.3.0.tgz", + "integrity": "sha512-9GU0xBatryXifL//FJH+tAZ6i240xQuFrSL7mYi8f4oZSbc+NvXjkrHemeYP0+L4ZUT+Ptz3b95zhUZnMtoi/Q==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-gfm-task-list-item": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/micromark-extension-gfm-task-list-item/-/micromark-extension-gfm-task-list-item-0.3.3.tgz", + "integrity": "sha512-0zvM5iSLKrc/NQl84pZSjGo66aTGd57C1idmlWmE87lkMcXrTxg1uXa/nXomxJytoje9trP0NDLvw4bZ/Z/XCQ==", + "dependencies": { + "micromark": "~2.11.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-expression": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-expression/-/micromark-extension-mdx-expression-1.0.8.tgz", + "integrity": "sha512-zZpeQtc5wfWKdzDsHRBY003H2Smg+PUi2REhqgIhdzAa5xonhP03FcXxqFSerFiNUr5AWmHpaNPQTBVOS4lrXw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "micromark-factory-mdx-expression": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-events-to-acorn": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-extension-mdx-jsx": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-jsx/-/micromark-extension-mdx-jsx-1.0.5.tgz", + "integrity": "sha512-gPH+9ZdmDflbu19Xkb8+gheqEDqkSpdCEubQyxuz/Hn8DOXiXvrXeikOoBA71+e8Pfi0/UYmU3wW3H58kr7akA==", + "dependencies": { + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "estree-util-is-identifier-name": "^2.0.0", + "micromark-factory-mdx-expression": "^1.0.0", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdx-md": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdx-md/-/micromark-extension-mdx-md-1.0.1.tgz", + "integrity": "sha512-7MSuj2S7xjOQXAjjkbjBsHkMtb+mDGVW6uI2dBL9snOBCbZmoNgDAeZ0nSn9j3T42UE/g2xVNMn18PJxZvkBEA==", + "dependencies": { + "micromark-util-types": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs/-/micromark-extension-mdxjs-1.0.1.tgz", + "integrity": "sha512-7YA7hF6i5eKOfFUzZ+0z6avRG52GpWR8DL+kN47y3f2KhxbBZMhmxe7auOeaTBrW2DenbbZTf1ea9tA2hDpC2Q==", + "dependencies": { + "acorn": "^8.0.0", + "acorn-jsx": "^5.0.0", + "micromark-extension-mdx-expression": "^1.0.0", + "micromark-extension-mdx-jsx": "^1.0.0", + "micromark-extension-mdx-md": "^1.0.0", + "micromark-extension-mdxjs-esm": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-types": "^1.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-extension-mdxjs-esm": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/micromark-extension-mdxjs-esm/-/micromark-extension-mdxjs-esm-1.0.5.tgz", + "integrity": "sha512-xNRBw4aoURcyz/S69B19WnZAkWJMxHMT5hE36GtDAyhoyn/8TuAeqjFJQlwk+MKQsUD7b3l7kFX+vlfVWgcX1w==", + "dependencies": { + "@types/estree": "^1.0.0", + "micromark-core-commonmark": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-events-to-acorn": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-position-from-estree": "^1.1.0", + "uvu": "^0.5.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/micromark-factory-destination": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-destination/-/micromark-factory-destination-1.1.0.tgz", + "integrity": "sha512-XaNDROBgx9SgSChd69pjiGKbV+nfHGDPVYFs5dOoDd7ZnMAE+Cuu91BCpsY8RT2NP9vo/B8pds2VQNCLiu0zhg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-label": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-label/-/micromark-factory-label-1.1.0.tgz", + "integrity": "sha512-OLtyez4vZo/1NjxGhcpDSbHQ+m0IIGnT8BoPamh+7jVlzLJBH98zzuCoUeMxvM6WsNeh8wx8cKvqLiPHEACn0w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" + } + }, + "node_modules/micromark-factory-mdx-expression": { + "version": "1.0.9", + "resolved": "https://registry.npmjs.org/micromark-factory-mdx-expression/-/micromark-factory-mdx-expression-1.0.9.tgz", + "integrity": "sha512-jGIWzSmNfdnkJq05c7b0+Wv0Kfz3NJ3N4cBjnbO4zjXIlxJr+f8lk+5ZmwFvqdAbUy2q6B5rCY//g0QAAaXDWA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "@types/estree": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-events-to-acorn": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-position-from-estree": "^1.0.0", + "uvu": "^0.5.0", + "vfile-message": "^3.0.0" + } + }, + "node_modules/micromark-factory-space": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-space/-/micromark-factory-space-1.1.0.tgz", + "integrity": "sha512-cRzEj7c0OL4Mw2v6nwzttyOZe8XY/Z8G0rzmWQZTBi/jjwyw/U4uqKtUORXQrR5bAZZnbTI/feRV/R7hc4jQYQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-title": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-title/-/micromark-factory-title-1.1.0.tgz", + "integrity": "sha512-J7n9R3vMmgjDOCY8NPw55jiyaQnH5kBdV2/UXCtZIpnHH3P6nHUKaH7XXEYuWwx/xUJcawa8plLBEjMPU24HzQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-factory-whitespace": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-factory-whitespace/-/micromark-factory-whitespace-1.1.0.tgz", + "integrity": "sha512-v2WlmiymVSp5oMg+1Q0N1Lxmt6pMhIHD457whWM7/GUlEks1hI9xj5w3zbc4uuMKXGisksZk8DzP2UyGbGqNsQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-character": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-character/-/micromark-util-character-1.2.0.tgz", + "integrity": "sha512-lXraTwcX3yH/vMDaFWCQJP1uIszLVebzUa3ZHdrgxr7KEU/9mL4mVgCpGbyhvNLNlauROiNUq7WN5u7ndbY6xg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" + } + }, + "node_modules/micromark-util-chunked": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-chunked/-/micromark-util-chunked-1.1.0.tgz", + "integrity": "sha512-Ye01HXpkZPNcV6FiyoW2fGZDUw4Yc7vT0E9Sad83+bEDiCJ1uXu0S3mr8WLpsz3HaG3x2q0HM6CTuPdcZcluFQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "dependencies": { - "github-slugger": "^1.2.1", - "mdast-util-to-string": "^1.0.5", - "unist-util-is": "^2.1.2", - "unist-util-visit": "^1.1.0" + "micromark-util-symbol": "^1.0.0" } }, - "node_modules/mdast-util-toc/node_modules/unist-util-is": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-2.1.3.tgz", - "integrity": "sha512-4WbQX2iwfr/+PfM4U3zd2VNXY+dWtZsN1fLnWEi2QQXA4qyDYAZcDMfXUX0Cu6XZUHHAO9q4nyxxLT4Awk1qUA==" - }, - "node_modules/mdast-util-toc/node_modules/unist-util-visit": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", - "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "node_modules/micromark-util-classify-character": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-classify-character/-/micromark-util-classify-character-1.1.0.tgz", + "integrity": "sha512-SL0wLxtKSnklKSUplok1WQFoGhUdWYKggKUiqhX+Swala+BtptGCu5iPRc+xvzJ4PXE/hwM3FNXsfEVgoZsWbw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "dependencies": { - "unist-util-visit-parents": "^2.0.0" + "micromark-util-character": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0" } }, - "node_modules/mdast-util-toc/node_modules/unist-util-visit-parents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", - "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", + "node_modules/micromark-util-combine-extensions": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-combine-extensions/-/micromark-util-combine-extensions-1.1.0.tgz", + "integrity": "sha512-Q20sp4mfNf9yEqDL50WwuWZHUrCO4fEyeDCnMGmG5Pr0Cz15Uo7KBs6jq+dq0EgX4DPwwrh9m0X+zPV1ypFvUA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "dependencies": { - "unist-util-is": "^3.0.0" + "micromark-util-chunked": "^1.0.0", + "micromark-util-types": "^1.0.0" } }, - "node_modules/mdast-util-toc/node_modules/unist-util-visit-parents/node_modules/unist-util-is": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", - "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==" - }, - "node_modules/mdn-data": { - "version": "2.0.14", - "resolved": "https://registry.npmjs.org/mdn-data/-/mdn-data-2.0.14.tgz", - "integrity": "sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==" - }, - "node_modules/mdurl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/mdurl/-/mdurl-1.0.1.tgz", - "integrity": "sha512-/sKlQJCBYVY9Ers9hqzKou4H6V5UWc/M59TH2dvkt+84itfnq7uFOMLpOiOS4ujvHP4etln18fmIxA5R5fll0g==" - }, - "node_modules/meant": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/meant/-/meant-1.0.3.tgz", - "integrity": "sha512-88ZRGcNxAq4EH38cQ4D85PM57pikCwS8Z99EWHODxN7KBY+UuPiqzRTtZzS8KTXO/ywSWbdjjJST2Hly/EQxLw==" - }, - "node_modules/media-typer": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/media-typer/-/media-typer-0.3.0.tgz", - "integrity": "sha512-dq+qelQ9akHpcOl/gUVRTxVIOkAJ1wR3QAvb4RsVjS8oVoFjDGTc679wJYmUmknUF5HwMLOgb5O+a3KxfWapPQ==", - "engines": { - "node": ">= 0.6" + "node_modules/micromark-util-decode-numeric-character-reference": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-numeric-character-reference/-/micromark-util-decode-numeric-character-reference-1.1.0.tgz", + "integrity": "sha512-m9V0ExGv0jB1OT21mrWcuf4QhP46pH1KkfWy9ZEezqHKAxkj4mPCy3nIH1rkbdMlChLHX531eOrymlwyZIf2iw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-symbol": "^1.0.0" } }, - "node_modules/mem": { - "version": "8.1.1", - "resolved": "https://registry.npmjs.org/mem/-/mem-8.1.1.tgz", - "integrity": "sha512-qFCFUDs7U3b8mBDPyz5EToEKoAkgCzqquIgi9nkkR9bixxOVOre+09lbuH7+9Kn2NFpm56M3GUWVbU2hQgdACA==", + "node_modules/micromark-util-decode-string": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-decode-string/-/micromark-util-decode-string-1.1.0.tgz", + "integrity": "sha512-YphLGCK8gM1tG1bd54azwyrQRjCFcmgj2S2GoJDNnh4vYtnL38JS8M4gpxzOPNyHdNEpheyWXCTnnTDY3N+NVQ==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "dependencies": { - "map-age-cleaner": "^0.1.3", - "mimic-fn": "^3.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sindresorhus/mem?sponsor=1" + "decode-named-character-reference": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-symbol": "^1.0.0" } }, - "node_modules/mem/node_modules/mimic-fn": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-3.1.0.tgz", - "integrity": "sha512-Ysbi9uYW9hFyfrThdDEQuykN4Ey6BuwPD2kpI5ES/nFTDn/98yxYNLZJcgUAKPT/mcrLLKaGzJR9YVxJrIdASQ==", - "engines": { - "node": ">=8" - } + "node_modules/micromark-util-encode": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-encode/-/micromark-util-encode-1.1.0.tgz", + "integrity": "sha512-EuEzTWSTAj9PA5GOAs992GzNh2dGQO52UvAbtSOMvXTxv3Criqb6IOzJUBCmEqrrXSblJIJBbFFv6zPxpreiJw==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] }, - "node_modules/memfs": { - "version": "3.5.3", - "resolved": "https://registry.npmjs.org/memfs/-/memfs-3.5.3.tgz", - "integrity": "sha512-UERzLsxzllchadvbPs5aolHh65ISpKpM+ccLbOJ8/vvpBKmAWf+la7dXFy7Mr0ySHbdHrFv5kGFCUHHe6GFEmw==", + "node_modules/micromark-util-events-to-acorn": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/micromark-util-events-to-acorn/-/micromark-util-events-to-acorn-1.2.3.tgz", + "integrity": "sha512-ij4X7Wuc4fED6UoLWkmo0xJQhsktfNh1J0m8g4PbIMPlx+ek/4YdW5mvbye8z/aZvAPUoxgXHrwVlXAPKMRp1w==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "dependencies": { - "fs-monkey": "^1.0.4" - }, - "engines": { - "node": ">= 4.0.0" + "@types/acorn": "^4.0.0", + "@types/estree": "^1.0.0", + "@types/unist": "^2.0.0", + "estree-util-visit": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0", + "vfile-message": "^3.0.0" } }, - "node_modules/memoize-one": { - "version": "5.2.1", - "resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-5.2.1.tgz", - "integrity": "sha512-zYiwtZUcYyXKo/np96AGZAckk+FWWsUdJ3cHGGmld7+AhvcWmQyGCYUh1hc4Q/pkOhb65dQR/pqCyK0cOaHz4Q==" + "node_modules/micromark-util-html-tag-name": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-html-tag-name/-/micromark-util-html-tag-name-1.2.0.tgz", + "integrity": "sha512-VTQzcuQgFUD7yYztuQFKXT49KghjtETQ+Wv/zUjGSGBioZnkA4P1XXZPT1FHeJA6RwRXSF47yvJ1tsJdoxwO+Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] }, - "node_modules/memoizee": { - "version": "0.4.17", - "resolved": "https://registry.npmjs.org/memoizee/-/memoizee-0.4.17.tgz", - "integrity": "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA==", + "node_modules/micromark-util-normalize-identifier": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-normalize-identifier/-/micromark-util-normalize-identifier-1.1.0.tgz", + "integrity": "sha512-N+w5vhqrBihhjdpM8+5Xsxy71QWqGn7HYNUvch71iV2PM7+E3uWGox1Qp90loa1ephtCxG2ftRV/Conitc6P2Q==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "dependencies": { - "d": "^1.0.2", - "es5-ext": "^0.10.64", - "es6-weak-map": "^2.0.3", - "event-emitter": "^0.3.5", - "is-promise": "^2.2.2", - "lru-queue": "^0.1.0", - "next-tick": "^1.1.0", - "timers-ext": "^0.1.7" - }, - "engines": { - "node": ">=0.12" + "micromark-util-symbol": "^1.0.0" } }, - "node_modules/meow": { - "version": "7.1.1", - "resolved": "https://registry.npmjs.org/meow/-/meow-7.1.1.tgz", - "integrity": "sha512-GWHvA5QOcS412WCo8vwKDlTelGLsCGBVevQB5Kva961rmNfun0PCbv5+xta2kUMFJyR8/oWnn7ddeKdosbAPbA==", + "node_modules/micromark-util-resolve-all": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-resolve-all/-/micromark-util-resolve-all-1.1.0.tgz", + "integrity": "sha512-b/G6BTMSg+bX+xVCshPTPyAu2tmA0E4X98NSR7eIbeC6ycCqCeE7wjfDIgzEbkzdEVJXRtOG4FbEm/uGbCRouA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "dependencies": { - "@types/minimist": "^1.2.0", - "camelcase-keys": "^6.2.2", - "decamelize-keys": "^1.1.0", - "hard-rejection": "^2.1.0", - "minimist-options": "4.1.0", - "normalize-package-data": "^2.5.0", - "read-pkg-up": "^7.0.1", - "redent": "^3.0.0", - "trim-newlines": "^3.0.0", - "type-fest": "^0.13.1", - "yargs-parser": "^18.1.3" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "micromark-util-types": "^1.0.0" } }, - "node_modules/meow/node_modules/type-fest": { - "version": "0.13.1", - "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.13.1.tgz", - "integrity": "sha512-34R7HTnG0XIJcBSn5XhDd7nNFPRcXYRZrBB2O2jdKqYODldSzBAqzsWoZYYvduky73toYS/ESqxPvkDf/F0XMg==", - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node_modules/micromark-util-sanitize-uri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/micromark-util-sanitize-uri/-/micromark-util-sanitize-uri-1.2.0.tgz", + "integrity": "sha512-QO4GXv0XZfWey4pYFndLUKEAktKkG5kZTdUNaTAkzbuJxn2tNBOr+QtxR2XpWaMhbImT2dPzyLrPXLlPhph34A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-character": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-symbol": "^1.0.0" } }, - "node_modules/merge-descriptors": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/merge-descriptors/-/merge-descriptors-1.0.3.tgz", - "integrity": "sha512-gaNvAS7TZ897/rVaZ0nMtAyxNyi/pdbjbAwUpFQpN70GqnVfOiXpeUUMKRBmzXaSQ8DdTX4/0ms62r2K+hE6mQ==", - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node_modules/micromark-util-subtokenize": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-subtokenize/-/micromark-util-subtokenize-1.1.0.tgz", + "integrity": "sha512-kUQHyzRoxvZO2PuLzMt2P/dwVsTiivCK8icYTeR+3WgbuPqfHgPPy7nFKbeqRivBvn/3N3GBiNC+JRTMSxEC7A==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], + "dependencies": { + "micromark-util-chunked": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "uvu": "^0.5.0" } }, - "node_modules/merge-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz", - "integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==" - }, - "node_modules/merge2": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz", - "integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==", - "engines": { - "node": ">= 8" - } + "node_modules/micromark-util-symbol": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-symbol/-/micromark-util-symbol-1.1.0.tgz", + "integrity": "sha512-uEjpEYY6KMs1g7QfJ2eX1SQEV+ZT4rUD3UcF6l57acZvLNK7PBZL+ty82Z1qhK1/yXIY4bdx04FKMgR0g4IAag==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] }, - "node_modules/methods": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/methods/-/methods-1.1.2.tgz", - "integrity": "sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==", - "engines": { - "node": ">= 0.6" - } + "node_modules/micromark-util-types": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/micromark-util-types/-/micromark-util-types-1.1.0.tgz", + "integrity": "sha512-ukRBgie8TIAcacscVHSiddHjO4k/q3pnedmzMQ4iwDcK0FtFCohKOlFbaOL/mPgfnPsL3C1ZyxJa4sbWrBl3jg==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ] }, "node_modules/micromatch": { "version": "4.0.8", @@ -19117,6 +19828,14 @@ "node": "*" } }, + "node_modules/mri": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", + "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", + "engines": { + "node": ">=4" + } + }, "node_modules/mrmime": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/mrmime/-/mrmime-2.0.0.tgz", @@ -19245,13 +19964,6 @@ "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz", "integrity": "sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA==" }, - "node_modules/nan": { - "version": "2.20.0", - "resolved": "https://registry.npmjs.org/nan/-/nan-2.20.0.tgz", - "integrity": "sha512-bk3gXBZDGILuuo/6sKtr0DQmSThYHLtNCdSdXk9YkxD/jK6X2vmCyyXBBxyqZ4XcnzTyYEAThfX3DCEnLf6igw==", - "dev": true, - "optional": true - }, "node_modules/nano-css": { "version": "5.6.2", "resolved": "https://registry.npmjs.org/nano-css/-/nano-css-5.6.2.tgz", @@ -19415,15 +20127,6 @@ "resolved": "https://registry.npmjs.org/next-tick/-/next-tick-1.1.0.tgz", "integrity": "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ==" }, - "node_modules/nlcst-to-string": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/nlcst-to-string/-/nlcst-to-string-2.0.4.tgz", - "integrity": "sha512-3x3jwTd6UPG7vi5k4GEzvxJ5rDA7hVUIRNHPblKuMVP9Z3xmlsd9cgLcpAMkc5uPOBna82EeshROFhsPkbnTZg==", - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/no-case": { "version": "3.0.4", "resolved": "https://registry.npmjs.org/no-case/-/no-case-3.0.4.tgz", @@ -19516,6 +20219,21 @@ "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-2.0.18.tgz", "integrity": "sha512-d9VeXT4SJ7ZeOqGX6R5EM022wpL+eWPooLI+5UpWn2jCT1aosUQEhQP214x33Wkwx3JQMvIm+tIoVOdodFS40g==" }, + "node_modules/nopt": { + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/nopt/-/nopt-7.2.1.tgz", + "integrity": "sha512-taM24ViiimT/XntxbPyJQzCG+p4EKOpgD3mxFwW38mGjVUrfERQOeY4EDHjdnptttfHuHQXFx+lTP08Q+mLa/w==", + "dev": true, + "dependencies": { + "abbrev": "^2.0.0" + }, + "bin": { + "nopt": "bin/nopt.js" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/normalize-package-data": { "version": "2.5.0", "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", @@ -19561,10 +20279,24 @@ "resolved": "https://registry.npmjs.org/normalize-url/-/normalize-url-6.1.0.tgz", "integrity": "sha512-DlL+XwOy3NxAQ8xuC0okPgK46iuVNAK01YN7RueYBqqFeGsBjV9XmCAzAdgt+667bCl5kPh9EqKKDwnaPG1I7A==", "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/not": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/not/-/not-0.1.0.tgz", + "integrity": "sha512-5PDmaAsVfnWUgTUbJ3ERwn7u79Z0dYxN9ErxCpVJJqe2RK0PJ3z+iFUxuqjwtlDDegXvtWoxD/3Fzxox7tFGWA==" + }, + "node_modules/npm-normalize-package-bin": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/npm-normalize-package-bin/-/npm-normalize-package-bin-3.0.1.tgz", + "integrity": "sha512-dMxCf+zZ+3zeQZXKxmyuCKlIDPGuv8EF940xbkC4kQVDTtqoh6rJFO+JTKSA6/Rwi0getWmtuy4Itup0AMcaDQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, "node_modules/npm-run-path": { @@ -20023,14 +20755,6 @@ "node": ">=8" } }, - "node_modules/p-finally": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", - "integrity": "sha512-LICb2p9CB7FS+0eR1oqWnHhp0FljGLZCWBE9aix0Uye9W8LTQPwMTYVGWQWIw9RdQiDg4+epXQODwIYJtSJaow==", - "engines": { - "node": ">=4" - } - }, "node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -20059,32 +20783,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/p-queue": { - "version": "6.6.2", - "resolved": "https://registry.npmjs.org/p-queue/-/p-queue-6.6.2.tgz", - "integrity": "sha512-RwFpb72c/BhQLEXIZ5K2e+AhgNVmIejGlTgiB9MzZ0e93GRvqZ7uSi0dvRF7/XIXDeNkra2fNHBxTyPDGySpjQ==", - "dependencies": { - "eventemitter3": "^4.0.4", - "p-timeout": "^3.2.0" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/sponsors/sindresorhus" - } - }, - "node_modules/p-timeout": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/p-timeout/-/p-timeout-3.2.0.tgz", - "integrity": "sha512-rhIwUycgwwKcP9yTOOFK/AKsAopjjCakVqLHePO3CC6Mir1Z99xT+R63jZxAT5lFZLa2inS5h+ZS2GvR99/FBg==", - "dependencies": { - "p-finally": "^1.0.0" - }, - "engines": { - "node": ">=8" - } - }, "node_modules/p-try": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", @@ -20285,21 +20983,6 @@ "node": ">=6" } }, - "node_modules/parse-english": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/parse-english/-/parse-english-4.2.0.tgz", - "integrity": "sha512-jw5N6wZUZViIw3VLG/FUSeL3vDhfw5Q2g4E3nYC69Mm5ANbh9ZWd+eligQbeUoyObZM8neynTn3l14e09pjEWg==", - "dependencies": { - "nlcst-to-string": "^2.0.0", - "parse-latin": "^4.0.0", - "unist-util-modify-children": "^2.0.0", - "unist-util-visit-children": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/parse-entities": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-2.0.0.tgz", @@ -20317,6 +21000,15 @@ "url": "https://github.com/sponsors/wooorm" } }, + "node_modules/parse-entities/node_modules/character-entities": { + "version": "1.2.4", + "resolved": "https://registry.npmjs.org/character-entities/-/character-entities-1.2.4.tgz", + "integrity": "sha512-iBMyeEHxfVnIakwOuDXpVkc54HijNgCyQB2w0VfGQThle6NXn50zU6V/u+LDhxHcDUPojn6Kpga3PTAD8W1bQw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, "node_modules/parse-filepath": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/parse-filepath/-/parse-filepath-1.0.2.tgz", @@ -20383,20 +21075,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/parse-latin": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/parse-latin/-/parse-latin-4.3.0.tgz", - "integrity": "sha512-TYKL+K98dcAWoCw/Ac1yrPviU8Trk+/gmjQVaoWEFDZmVD4KRg6c/80xKqNNFQObo2mTONgF8trzAf2UTwKafw==", - "dependencies": { - "nlcst-to-string": "^2.0.0", - "unist-util-modify-children": "^2.0.0", - "unist-util-visit-children": "^1.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/parse-path": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/parse-path/-/parse-path-7.0.0.tgz", @@ -20414,9 +21092,52 @@ } }, "node_modules/parse5": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/parse5/-/parse5-6.0.1.tgz", - "integrity": "sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==" + "version": "7.2.1", + "resolved": "https://registry.npmjs.org/parse5/-/parse5-7.2.1.tgz", + "integrity": "sha512-BuBYQYlv1ckiPdQi/ohiivi9Sagc9JG+Ozs0r7b/0iK3sKmrb0b9FdWdBbOdx6hBCM/F9Ir82ofnBhtZOjCRPQ==", + "dependencies": { + "entities": "^4.5.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/parse5-htmlparser2-tree-adapter/-/parse5-htmlparser2-tree-adapter-7.1.0.tgz", + "integrity": "sha512-ruw5xyKs6lrpo9x9rCZqZZnIUntICjQAd0Wsmp396Ul9lN/h+ifgVV1x1gZHi8euej6wTfpqX8j+BFQxF0NS/g==", + "dependencies": { + "domhandler": "^5.0.3", + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } + }, + "node_modules/parse5-htmlparser2-tree-adapter/node_modules/domhandler": { + "version": "5.0.3", + "resolved": "https://registry.npmjs.org/domhandler/-/domhandler-5.0.3.tgz", + "integrity": "sha512-cgwlv/1iFQiFnU96XXgROh8xTeetsnJiDsTc7TYCLFd9+/WNkIqPTxiM/8pSd8VIrhXGTf1Ny1q1hquVqDJB5w==", + "dependencies": { + "domelementtype": "^2.3.0" + }, + "engines": { + "node": ">= 4" + }, + "funding": { + "url": "https://github.com/fb55/domhandler?sponsor=1" + } + }, + "node_modules/parse5-parser-stream": { + "version": "7.1.2", + "resolved": "https://registry.npmjs.org/parse5-parser-stream/-/parse5-parser-stream-7.1.2.tgz", + "integrity": "sha512-JyeQc9iwFLn5TbvvqACIF/VXG6abODeB3Fwmv/TGdLk2LfbWkaySGY72at4+Ty7EkPZj854u4CrICqNk2qIbow==", + "dependencies": { + "parse5": "^7.0.0" + }, + "funding": { + "url": "https://github.com/inikulin/parse5?sponsor=1" + } }, "node_modules/parseurl": { "version": "1.3.3", @@ -20581,6 +21302,24 @@ "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz", "integrity": "sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==" }, + "node_modules/periscopic": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/periscopic/-/periscopic-3.1.0.tgz", + "integrity": "sha512-vKiQ8RRtkl9P+r/+oefh25C3fhybptkHKCZSPlcXiJux2tJF55GnEj3BVn4A5gKfq9NWWXXrxkHBwVPUfH0opw==", + "dependencies": { + "@types/estree": "^1.0.0", + "estree-walker": "^3.0.0", + "is-reference": "^3.0.0" + } + }, + "node_modules/periscopic/node_modules/estree-walker": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz", + "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==", + "dependencies": { + "@types/estree": "^1.0.0" + } + }, "node_modules/physical-cpu-count": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/physical-cpu-count/-/physical-cpu-count-2.0.0.tgz", @@ -21421,6 +22160,11 @@ "node": ">=0.10.0" } }, + "node_modules/prettier-bytes": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/prettier-bytes/-/prettier-bytes-1.0.4.tgz", + "integrity": "sha512-dLbWOa4xBn+qeWeIF60qRoB6Pk2jX5P3DIVgOQyMyvBpu931Q+8dXz8X0snJiFkQdohDDLnZQECjzsAj75hgZQ==" + }, "node_modules/pretty-bytes": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/pretty-bytes/-/pretty-bytes-5.6.0.tgz", @@ -21463,6 +22207,15 @@ "stream-parser": "~0.3.1" } }, + "node_modules/proc-log": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/proc-log/-/proc-log-3.0.0.tgz", + "integrity": "sha512-++Vn7NS4Xf9NacaU9Xq3URUuqZETPsf8L4j5/ckhaRYsfPeRyzGw+iDjFhV/Jr3uNmTvvddEJFWh5R1gRgUH8A==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/process": { "version": "0.11.10", "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", @@ -21476,6 +22229,28 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, + "node_modules/process-top": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/process-top/-/process-top-1.3.0.tgz", + "integrity": "sha512-WZ08E4so0R7nL/twE4N0VkZLVWOFbMhfJ8B3vzB21YZK12B7wzTsaQxJxZ0YQJZ+uatXkepYV5lWrNjW30PN+w==", + "dependencies": { + "bare-hrtime": "^2.0.10", + "bare-os": "^3.1.0", + "event-loop-delay": "^1.1.0", + "prettier-bytes": "^1.0.4" + }, + "bin": { + "process-top": "bin.js" + } + }, + "node_modules/process-top/node_modules/bare-os": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/bare-os/-/bare-os-3.3.0.tgz", + "integrity": "sha512-FHpgZfomMYliB1mDls35vFDpSQGFKS+yZYTCNdkK891t5dl9+sNUvplKxIPJvnhPHl+ZYTOz0gIJHeFpjltcDg==", + "engines": { + "bare": ">=1.6.0" + } + }, "node_modules/progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -21525,12 +22300,9 @@ } }, "node_modules/property-information": { - "version": "5.6.0", - "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", - "integrity": "sha512-YUHSPk+A30YPv+0Qf8i9Mbfe/C0hdPXk1s1jPVToV8pk8BQtpw10ct89Eo7OWkutrwqvT0eicAxlOg3dOAu8JA==", - "dependencies": { - "xtend": "^4.0.0" - }, + "version": "6.5.0", + "resolved": "https://registry.npmjs.org/property-information/-/property-information-6.5.0.tgz", + "integrity": "sha512-PgTgs/BlvHxOu8QuEN7wi5A0OmXaBcHpmCSTehcs6Uuu9IkDIEo13Hy7n898RHfrQ49vKCoGeWZSaAK01nwVig==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -22160,6 +22932,41 @@ "react": "*" } }, + "node_modules/react-markdown": { + "version": "8.0.7", + "resolved": "https://registry.npmjs.org/react-markdown/-/react-markdown-8.0.7.tgz", + "integrity": "sha512-bvWbzG4MtOU62XqBx3Xx+zB2raaFFsq4mYiAzfjXJMEz2sixgeAfraA3tvzULF02ZdOMUOKTBFFaZJDDrq+BJQ==", + "dependencies": { + "@types/hast": "^2.0.0", + "@types/prop-types": "^15.0.0", + "@types/unist": "^2.0.0", + "comma-separated-tokens": "^2.0.0", + "hast-util-whitespace": "^2.0.0", + "prop-types": "^15.0.0", + "property-information": "^6.0.0", + "react-is": "^18.0.0", + "remark-parse": "^10.0.0", + "remark-rehype": "^10.0.0", + "space-separated-tokens": "^2.0.0", + "style-to-object": "^0.4.0", + "unified": "^10.0.0", + "unist-util-visit": "^4.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + }, + "peerDependencies": { + "@types/react": ">=16", + "react": ">=16" + } + }, + "node_modules/react-markdown/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, "node_modules/react-modal": { "version": "3.16.1", "resolved": "https://registry.npmjs.org/react-modal/-/react-modal-3.16.1.tgz", @@ -22569,6 +23376,28 @@ "node": ">=0.8" } }, + "node_modules/read-package-json-fast": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/read-package-json-fast/-/read-package-json-fast-3.0.2.tgz", + "integrity": "sha512-0J+Msgym3vrLOUB3hzQCuZHII0xkNGCtz/HJH9xZshwv9DbDwkw1KaE3gx/e2J5rpEY5rtOy6cyhKOPrkP7FZw==", + "dev": true, + "dependencies": { + "json-parse-even-better-errors": "^3.0.0", + "npm-normalize-package-bin": "^3.0.0" + }, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, + "node_modules/read-package-json-fast/node_modules/json-parse-even-better-errors": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-3.0.2.tgz", + "integrity": "sha512-fi0NG4bPjCHunUJffmLd0gxssIgkNmArMvis4iNah6Owg1MCJjWhEcDLmsK6iGkJq3tHwbDkTlce70/tmXN4cQ==", + "dev": true, + "engines": { + "node": "^14.17.0 || ^16.13.0 || >=18.0.0" + } + }, "node_modules/read-pkg": { "version": "5.2.0", "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-5.2.0.tgz", @@ -22965,6 +23794,38 @@ "jsesc": "bin/jsesc" } }, + "node_modules/rehype-infer-description-meta": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/rehype-infer-description-meta/-/rehype-infer-description-meta-1.1.0.tgz", + "integrity": "sha512-TGGIYo5YpkQuUxTp9niX7/G1+9VCeC1d3O625jTRDZLUybpjfvekTw70M7dg3viUwdAmXXxqe2A8K0eUz1tTCg==", + "dependencies": { + "@types/hast": "^2.0.0", + "hast-util-excerpt": "^1.0.0", + "hast-util-select": "^5.0.0", + "hast-util-to-text": "^3.0.0", + "hast-util-truncate": "^1.0.0", + "unified": "^10.0.0", + "unist-util-remove-position": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/rehype-raw": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/rehype-raw/-/rehype-raw-6.1.1.tgz", + "integrity": "sha512-d6AKtisSRtDRX4aSPsJGTfnzrX2ZkHQLE5kiUuGOeEoLpbEulFF4hj0mLPbsa+7vmguDKOVVEQdHKDSwoaIDsQ==", + "dependencies": { + "@types/hast": "^2.0.0", + "hast-util-raw": "^7.2.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/relay-runtime": { "version": "12.0.0", "resolved": "https://registry.npmjs.org/relay-runtime/-/relay-runtime-12.0.0.tgz", @@ -22975,301 +23836,208 @@ "invariant": "^2.2.4" } }, - "node_modules/remark": { - "version": "10.0.1", - "resolved": "https://registry.npmjs.org/remark/-/remark-10.0.1.tgz", - "integrity": "sha512-E6lMuoLIy2TyiokHprMjcWNJ5UxfGQjaMSMhV+f4idM625UjjK4j798+gPs5mfjzDE6vL0oFKVeZM6gZVSVrzQ==", + "node_modules/remark-gfm": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/remark-gfm/-/remark-gfm-1.0.0.tgz", + "integrity": "sha512-KfexHJCiqvrdBZVbQ6RopMZGwaXz6wFJEfByIuEwGf0arvITHjiKKZ1dpXujjH9KZdm1//XJQwgfnJ3lmXaDPA==", "dependencies": { - "remark-parse": "^6.0.0", - "remark-stringify": "^6.0.0", - "unified": "^7.0.0" - } - }, - "node_modules/remark-footnotes": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/remark-footnotes/-/remark-footnotes-2.0.0.tgz", - "integrity": "sha512-3Clt8ZMH75Ayjp9q4CorNeyjwIxHFcTkaektplKGl2A1jNGEUey8cKL0ZC5vJwfcD5GFGsNLImLG/NGzWIzoMQ==", + "mdast-util-gfm": "^0.1.0", + "micromark-extension-gfm": "^0.3.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/remark-mdx": { - "version": "1.6.22", - "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-1.6.22.tgz", - "integrity": "sha512-phMHBJgeV76uyFkH4rvzCftLfKCr2RZuF+/gmVcaKrpsihyzmhXjA0BEMDaPTXG5y8qZOKPVo83NAOX01LPnOQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/remark-mdx/-/remark-mdx-2.3.0.tgz", + "integrity": "sha512-g53hMkpM0I98MU266IzDFMrTD980gNF3BJnkyFcmN+dD873mQeD5rdMO3Y2X+x8umQfbSE0PcoEDl7ledSA+2g==", "dependencies": { - "@babel/core": "7.12.9", - "@babel/helper-plugin-utils": "7.10.4", - "@babel/plugin-proposal-object-rest-spread": "7.12.1", - "@babel/plugin-syntax-jsx": "7.12.1", - "@mdx-js/util": "1.6.22", - "is-alphabetical": "1.0.4", - "remark-parse": "8.0.3", - "unified": "9.2.0" + "mdast-util-mdx": "^2.0.0", + "micromark-extension-mdxjs": "^1.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-mdx/node_modules/@babel/core": { - "version": "7.12.9", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.12.9.tgz", - "integrity": "sha512-gTXYh3M5wb7FRXQy+FErKFAv90BnlOuNn1QkCK2lREoPAjrQCO49+HVSrFoe5uakFAF5eenS75KbO2vQiLrTMQ==", - "dependencies": { - "@babel/code-frame": "^7.10.4", - "@babel/generator": "^7.12.5", - "@babel/helper-module-transforms": "^7.12.1", - "@babel/helpers": "^7.12.5", - "@babel/parser": "^7.12.7", - "@babel/template": "^7.12.7", - "@babel/traverse": "^7.12.9", - "@babel/types": "^7.12.7", - "convert-source-map": "^1.7.0", - "debug": "^4.1.0", - "gensync": "^1.0.0-beta.1", - "json5": "^2.1.2", - "lodash": "^4.17.19", - "resolve": "^1.3.2", - "semver": "^5.4.1", - "source-map": "^0.5.0" - }, - "engines": { - "node": ">=6.9.0" + "node_modules/remark-parse": { + "version": "10.0.2", + "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-10.0.2.tgz", + "integrity": "sha512-3ydxgHa/ZQzG8LvC7jTXccARYDcRld3VfcgIIFs7bI6vbRSxJJmzgLEIIoYKyrfhaY+ujuWaf/PJiMZXoiCXgw==", + "dependencies": { + "@types/mdast": "^3.0.0", + "mdast-util-from-markdown": "^1.0.0", + "unified": "^10.0.0" }, "funding": { "type": "opencollective", - "url": "https://opencollective.com/babel" + "url": "https://opencollective.com/unified" } }, - "node_modules/remark-mdx/node_modules/@babel/helper-plugin-utils": { - "version": "7.10.4", - "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz", - "integrity": "sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg==" - }, - "node_modules/remark-mdx/node_modules/@babel/plugin-proposal-object-rest-spread": { - "version": "7.12.1", - "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.12.1.tgz", - "integrity": "sha512-s6SowJIjzlhx8o7lsFx5zmY4At6CTtDvgNQDdPzkBQucle58A6b/TTeEBYtyDgmcXjUTM+vE8YOGHZzzbc/ioA==", - "deprecated": "This proposal has been merged to the ECMAScript standard and thus this plugin is no longer maintained. Please use @babel/plugin-transform-object-rest-spread instead.", + "node_modules/remark-parse/node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", "dependencies": { - "@babel/helper-plugin-utils": "^7.10.4", - "@babel/plugin-syntax-object-rest-spread": "^7.8.0", - "@babel/plugin-transform-parameters": "^7.12.1" - }, - "peerDependencies": { - "@babel/core": "^7.0.0-0" - } - }, - "node_modules/remark-mdx/node_modules/convert-source-map": { - "version": "1.9.0", - "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz", - "integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==" - }, - "node_modules/remark-mdx/node_modules/semver": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.2.tgz", - "integrity": "sha512-cBznnQ9KjJqU67B52RMC65CMarK2600WFnbkcaiwWq3xy/5haFJlshgnpjovMVJ+Hff49d8GEn0b87C5pDQ10g==", - "bin": { - "semver": "bin/semver" + "@types/ms": "*" } }, - "node_modules/remark-parse": { - "version": "8.0.3", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-8.0.3.tgz", - "integrity": "sha512-E1K9+QLGgggHxCQtLt++uXltxEprmWzNfg+MxpfHsZlrddKzZ/hZyWHDbK3/Ap8HJQqYJRXP+jHczdL6q6i85Q==", + "node_modules/remark-parse/node_modules/mdast-util-from-markdown": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mdast-util-from-markdown/-/mdast-util-from-markdown-1.3.1.tgz", + "integrity": "sha512-4xTO/M8c82qBcnQc1tgpNtubGUW/Y1tBQ1B0i5CtSoelOLKFYlElIr3bvgREYYO5iRqbMY1YuqZng0GVOI8Qww==", "dependencies": { - "ccount": "^1.0.0", - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^2.0.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^2.0.0", - "vfile-location": "^3.0.0", - "xtend": "^4.0.1" + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "decode-named-character-reference": "^1.0.0", + "mdast-util-to-string": "^3.1.0", + "micromark": "^3.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-decode-string": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.0", + "unist-util-stringify-position": "^3.0.0", + "uvu": "^0.5.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-retext": { - "version": "3.1.3", - "resolved": "https://registry.npmjs.org/remark-retext/-/remark-retext-3.1.3.tgz", - "integrity": "sha512-UujXAm28u4lnUvtOZQFYfRIhxX+auKI9PuA2QpQVTT7gYk1OgX6o0OUrSo1KOa6GNrFX+OODOtS5PWIHPxM7qw==", - "dependencies": { - "mdast-util-to-nlcst": "^3.2.0" - } - }, - "node_modules/remark-squeeze-paragraphs": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/remark-squeeze-paragraphs/-/remark-squeeze-paragraphs-4.0.0.tgz", - "integrity": "sha512-8qRqmL9F4nuLPIgl92XUuxI3pFxize+F1H0e/W3llTk0UsjJaj01+RrirkMw7P21RKe4X6goQhYRSvNWX+70Rw==", + "node_modules/remark-parse/node_modules/mdast-util-to-string": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-string/-/mdast-util-to-string-3.2.0.tgz", + "integrity": "sha512-V4Zn/ncyN1QNSqSBxTrMOLpjr+IKdHl2v3KVLoWmDPscP4r9GcCi71gjgvUV1SFSKh92AjAG4peFuBl2/YgCJg==", "dependencies": { - "mdast-squeeze-paragraphs": "^4.0.0" + "@types/mdast": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark-stringify": { - "version": "6.0.4", - "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-6.0.4.tgz", - "integrity": "sha512-eRWGdEPMVudijE/psbIDNcnJLRVx3xhfuEsTDGgH4GsFF91dVhw5nhmnBppafJ7+NWINW6C7ZwWbi30ImJzqWg==", - "dependencies": { - "ccount": "^1.0.0", - "is-alphanumeric": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "longest-streak": "^2.0.1", - "markdown-escapes": "^1.0.0", - "markdown-table": "^1.1.0", - "mdast-util-compact": "^1.0.0", - "parse-entities": "^1.0.2", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "stringify-entities": "^1.0.1", - "unherit": "^1.0.4", - "xtend": "^4.0.1" - } - }, - "node_modules/remark-stringify/node_modules/parse-entities": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", - "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", - "dependencies": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - } - }, - "node_modules/remark/node_modules/parse-entities": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/parse-entities/-/parse-entities-1.2.2.tgz", - "integrity": "sha512-NzfpbxW/NPrzZ/yYSoQxyqUZMZXIdCfE0OIN4ESsnptHJECoUk3FZktxNuzQf4tjt5UEopnxpYJbvYuxIFDdsg==", - "dependencies": { - "character-entities": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "character-reference-invalid": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-hexadecimal": "^1.0.0" - } - }, - "node_modules/remark/node_modules/remark-parse": { - "version": "6.0.3", - "resolved": "https://registry.npmjs.org/remark-parse/-/remark-parse-6.0.3.tgz", - "integrity": "sha512-QbDXWN4HfKTUC0hHa4teU463KclLAnwpn/FBn87j9cKYJWWawbiLgMfP2Q4XwhxxuuuOxHlw+pSN0OKuJwyVvg==", + "node_modules/remark-parse/node_modules/micromark": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/micromark/-/micromark-3.2.0.tgz", + "integrity": "sha512-uD66tJj54JLYq0De10AhWycZWGQNUvDI55xPgk2sQM5kn1JYlhbCMTtEeT27+vAhW2FBQxLlOmS3pmA7/2z4aA==", + "funding": [ + { + "type": "GitHub Sponsors", + "url": "https://github.com/sponsors/unifiedjs" + }, + { + "type": "OpenCollective", + "url": "https://opencollective.com/unified" + } + ], "dependencies": { - "collapse-white-space": "^1.0.2", - "is-alphabetical": "^1.0.0", - "is-decimal": "^1.0.0", - "is-whitespace-character": "^1.0.0", - "is-word-character": "^1.0.0", - "markdown-escapes": "^1.0.0", - "parse-entities": "^1.1.0", - "repeat-string": "^1.5.4", - "state-toggle": "^1.0.0", - "trim": "0.0.1", - "trim-trailing-lines": "^1.0.0", - "unherit": "^1.0.4", - "unist-util-remove-position": "^1.0.0", - "vfile-location": "^2.0.0", - "xtend": "^4.0.1" - } - }, - "node_modules/remark/node_modules/unified": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-7.1.0.tgz", - "integrity": "sha512-lbk82UOIGuCEsZhPj8rNAkXSDXd6p0QLzIuSsCdxrqnqU56St4eyOB+AlXsVgVeRmetPTYydIuvFfpDIed8mqw==", + "@types/debug": "^4.0.0", + "debug": "^4.0.0", + "decode-named-character-reference": "^1.0.0", + "micromark-core-commonmark": "^1.0.1", + "micromark-factory-space": "^1.0.0", + "micromark-util-character": "^1.0.0", + "micromark-util-chunked": "^1.0.0", + "micromark-util-combine-extensions": "^1.0.0", + "micromark-util-decode-numeric-character-reference": "^1.0.0", + "micromark-util-encode": "^1.0.0", + "micromark-util-normalize-identifier": "^1.0.0", + "micromark-util-resolve-all": "^1.0.0", + "micromark-util-sanitize-uri": "^1.0.0", + "micromark-util-subtokenize": "^1.0.0", + "micromark-util-symbol": "^1.0.0", + "micromark-util-types": "^1.0.1", + "uvu": "^0.5.0" + } + }, + "node_modules/remark-rehype": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/remark-rehype/-/remark-rehype-10.1.0.tgz", + "integrity": "sha512-EFmR5zppdBp0WQeDVZ/b66CWJipB2q2VLNFMabzDSGR66Z2fQii83G5gTBbgGEnEEA0QRussvrFHxk1HWGJskw==", "dependencies": { - "@types/unist": "^2.0.0", - "@types/vfile": "^3.0.0", - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-plain-obj": "^1.1.0", - "trough": "^1.0.0", - "vfile": "^3.0.0", - "x-is-string": "^0.1.0" + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "mdast-util-to-hast": "^12.1.0", + "unified": "^10.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/remark/node_modules/unist-util-is": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", - "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==" - }, - "node_modules/remark/node_modules/unist-util-remove-position": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-1.1.4.tgz", - "integrity": "sha512-tLqd653ArxJIPnKII6LMZwH+mb5q+n/GtXQZo6S6csPRs5zB0u79Yw8ouR3wTw8wxvdJFhpP6Y7jorWdCgLO0A==", + "node_modules/remark-rehype/node_modules/mdast-util-definitions": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/mdast-util-definitions/-/mdast-util-definitions-5.1.2.tgz", + "integrity": "sha512-8SVPMuHqlPME/z3gqVwWY4zVXn8lqKv/pAhC57FuJ40ImXyBpmO5ukh98zB2v7Blql2FiHjHv9LVztSIqjY+MA==", "dependencies": { - "unist-util-visit": "^1.1.0" + "@types/mdast": "^3.0.0", + "@types/unist": "^2.0.0", + "unist-util-visit": "^4.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark/node_modules/unist-util-stringify-position": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-1.1.2.tgz", - "integrity": "sha512-pNCVrk64LZv1kElr0N1wPiHEUoXNVFERp+mlTg/s9R5Lwg87f9bM/3sQB99w+N9D/qnM9ar3+AKDBwo/gm/iQQ==" - }, - "node_modules/remark/node_modules/unist-util-visit": { - "version": "1.4.1", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-1.4.1.tgz", - "integrity": "sha512-AvGNk7Bb//EmJZyhtRUnNMEpId/AZ5Ph/KUpTI09WHQuDZHKovQ1oEv3mfmKpWKtoMzyMC4GLBm1Zy5k12fjIw==", + "node_modules/remark-rehype/node_modules/mdast-util-to-hast": { + "version": "12.3.0", + "resolved": "https://registry.npmjs.org/mdast-util-to-hast/-/mdast-util-to-hast-12.3.0.tgz", + "integrity": "sha512-pits93r8PhnIoU4Vy9bjW39M2jJ6/tdHyja9rrot9uujkN7UTU9SDnE6WNJz/IGyQk3XHX6yNNtrBH6cQzm8Hw==", "dependencies": { - "unist-util-visit-parents": "^2.0.0" + "@types/hast": "^2.0.0", + "@types/mdast": "^3.0.0", + "mdast-util-definitions": "^5.0.0", + "micromark-util-sanitize-uri": "^1.1.0", + "trim-lines": "^3.0.0", + "unist-util-generated": "^2.0.0", + "unist-util-position": "^4.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/remark/node_modules/unist-util-visit-parents": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-2.1.2.tgz", - "integrity": "sha512-DyN5vD4NE3aSeB+PXYNKxzGsfocxp6asDc2XXE3b0ekO2BaRUpBicbbUygfSvYfUz1IkmjFR1YF7dPklraMZ2g==", - "dependencies": { - "unist-util-is": "^3.0.0" + "node_modules/remark-rehype/node_modules/unist-util-generated": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-2.0.1.tgz", + "integrity": "sha512-qF72kLmPxAw0oN2fwpWIqbXAVyEqUzDHMsbtPvOudIlUzXYFIeQIuxXQCRCFh22B7cixvU0MG7m3MW8FTq/S+A==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, - "node_modules/remark/node_modules/vfile": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-3.0.1.tgz", - "integrity": "sha512-y7Y3gH9BsUSdD4KzHsuMaCzRjglXN0W2EcMf0gpvu6+SbsGhMje7xDc8AEoeXy6mIwCKMI6BkjMsRjzQbhMEjQ==", + "node_modules/remark-stringify": { + "version": "10.0.3", + "resolved": "https://registry.npmjs.org/remark-stringify/-/remark-stringify-10.0.3.tgz", + "integrity": "sha512-koyOzCMYoUHudypbj4XpnAKFbkddRMYZHwghnxd7ue5210WzGw6kOBwauJTRUMq16jsovXx8dYNvSSWP89kZ3A==", + "dev": true, "dependencies": { - "is-buffer": "^2.0.0", - "replace-ext": "1.0.0", - "unist-util-stringify-position": "^1.0.0", - "vfile-message": "^1.0.0" - } - }, - "node_modules/remark/node_modules/vfile-location": { - "version": "2.0.6", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-2.0.6.tgz", - "integrity": "sha512-sSFdyCP3G6Ka0CEmN83A2YCMKIieHx0EDaj5IDP4g1pa5ZJ4FJDvpO0WODLxo4LUX4oe52gmSCK7Jw4SBghqxA==", + "@types/mdast": "^3.0.0", + "mdast-util-to-markdown": "^1.0.0", + "unified": "^10.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/remark/node_modules/vfile-message": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-1.1.1.tgz", - "integrity": "sha512-1WmsopSGhWt5laNir+633LszXvZ+Z/lxveBf6yhGsqnQIhlhzooZae7zV6YVM1Sdkw68dtAW3ow0pOdPANugvA==", + "node_modules/remark-unwrap-images": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/remark-unwrap-images/-/remark-unwrap-images-3.0.1.tgz", + "integrity": "sha512-5VUY0n+J9lPTPfkct5S3/SbutryBjp8J/4mbgtlkDrOk3h8jde0hyqdYUJOoJKherZezS08tjd6i4+nnQ+wl5w==", "dependencies": { - "unist-util-stringify-position": "^1.1.1" + "@types/mdast": "^3.0.0", + "hast-util-whitespace": "^2.0.0", + "unified": "^10.0.0", + "unist-util-visit": "^4.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, "node_modules/remove-trailing-separator": { @@ -23325,14 +24093,6 @@ "node": ">=0.10" } }, - "node_modules/replace-ext": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/replace-ext/-/replace-ext-1.0.0.tgz", - "integrity": "sha512-vuNYXC7gG7IeVNBC1xUllqCcZKRbJoSPOBhnTEcAIiKCsbuef6zO3F0Rve3isPMMoNoQRWjQwbAgAjHUHniyEA==", - "engines": { - "node": ">= 0.10" - } - }, "node_modules/require-directory": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz", @@ -23349,14 +24109,6 @@ "node": ">=0.10.0" } }, - "node_modules/require-like": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/require-like/-/require-like-0.1.2.tgz", - "integrity": "sha512-oyrU88skkMtDdauHDuKVrgR+zuItqr6/c//FXzvmxRGMexSDc6hNvJInGW3LL46n+8b50RykrvwSUIIQH2LQ5A==", - "engines": { - "node": "*" - } - }, "node_modules/require-main-filename": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz", @@ -23457,19 +24209,6 @@ "node": ">=0.12" } }, - "node_modules/retext-english": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/retext-english/-/retext-english-3.0.4.tgz", - "integrity": "sha512-yr1PgaBDde+25aJXrnt3p1jvT8FVLVat2Bx8XeAWX13KXo8OT+3nWGU3HWxM4YFJvmfqvJYJZG2d7xxaO774gw==", - "dependencies": { - "parse-english": "^4.0.0", - "unherit": "^1.0.4" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" - } - }, "node_modules/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", @@ -23664,6 +24403,17 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" }, + "node_modules/sade": { + "version": "1.8.1", + "resolved": "https://registry.npmjs.org/sade/-/sade-1.8.1.tgz", + "integrity": "sha512-xal3CZX1Xlo/k4ApwCFrHVACi9fBqJ7V+mwhBsuf/1IOKbBy098Fex+Wa/5QMubw09pSZ/u8EY8PWgevJsXp1A==", + "dependencies": { + "mri": "^1.1.0" + }, + "engines": { + "node": ">=6" + } + }, "node_modules/safe-array-concat": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.3.tgz", @@ -24638,9 +25388,9 @@ "deprecated": "Please use @jridgewell/sourcemap-codec instead" }, "node_modules/space-separated-tokens": { - "version": "1.1.5", - "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-1.1.5.tgz", - "integrity": "sha512-q/JSVd1Lptzhf5bkYm4ob4iWPjx0KiRe3sRFBNrVqbJkFaBm5vbbowy1mymoPNLRa52+oadOhJ+K49wsSeSjTA==", + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/space-separated-tokens/-/space-separated-tokens-2.0.2.tgz", + "integrity": "sha512-PEGlAwrG8yXGXRjW32fGbg66JAlOAwbObuqVoJpv/mRgoWDQfgH1wDPvtzWyUSNAXBGSk8h755YDbbcEy3SH2Q==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -24727,11 +25477,6 @@ "tslib": "^2.0.3" } }, - "node_modules/sprintf-js": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.1.3.tgz", - "integrity": "sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==" - }, "node_modules/stable": { "version": "0.1.8", "resolved": "https://registry.npmjs.org/stable/-/stable-0.1.8.tgz", @@ -24786,15 +25531,6 @@ "stacktrace-gps": "^3.0.4" } }, - "node_modules/state-toggle": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/state-toggle/-/state-toggle-1.0.3.tgz", - "integrity": "sha512-d/5Z4/2iiCnHw6Xzghyhb+GcmF89bxwgXG60wjIiZaxnymbyOmI8Hk4VqHXiVVp6u2ysaskFfXg3ekCj4WNftQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/static-extend": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", @@ -24833,32 +25569,6 @@ "node": ">= 0.4" } }, - "node_modules/static-site-generator-webpack-plugin": { - "version": "3.4.2", - "resolved": "https://registry.npmjs.org/static-site-generator-webpack-plugin/-/static-site-generator-webpack-plugin-3.4.2.tgz", - "integrity": "sha512-39Kn+fZDVjolLYuX5y1rDvksJIW0QEUaEC/AVO/UewNXxGzoSQI1UYnRsL+ocAcN5Yti6d6rJgEL0qZ5tNXfdw==", - "dependencies": { - "bluebird": "^3.0.5", - "cheerio": "^0.22.0", - "eval": "^0.1.0", - "url": "^0.11.0", - "webpack-sources": "^0.2.0" - } - }, - "node_modules/static-site-generator-webpack-plugin/node_modules/source-list-map": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/source-list-map/-/source-list-map-1.1.2.tgz", - "integrity": "sha512-FqR2O+cX+toUD3ULVIgTtiqYIqPnA62ehJD47mf4LG1PZCB+xmIa3gcTEhegGbP22aRPh88dJSdgDIolrvSxBQ==" - }, - "node_modules/static-site-generator-webpack-plugin/node_modules/webpack-sources": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-0.2.3.tgz", - "integrity": "sha512-iqanNZjOHLdPn/R0e/nKVn90dm4IsUMxKam0MZD1btWhFub/Cdo1nWdMio6yEqBc0F8mEieOjc+jfBSXwna94Q==", - "dependencies": { - "source-list-map": "^1.1.1", - "source-map": "~0.5.3" - } - }, "node_modules/statuses": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz", @@ -25101,14 +25811,25 @@ } }, "node_modules/stringify-entities": { - "version": "1.3.2", - "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-1.3.2.tgz", - "integrity": "sha512-nrBAQClJAPN2p+uGCVJRPIPakKeKWZ9GtBCmormE7pWOSlHat7+x5A8gx85M7HM5Dt0BP3pP5RhVW77WdbJJ3A==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/stringify-entities/-/stringify-entities-4.0.4.tgz", + "integrity": "sha512-IwfBptatlO+QCJUo19AqvrPNqlVMpW9YEL2LIVY+Rpv2qsjCGxaDLNRgeGsQWJhfItebuJhsGSLjaBbNSQ+ieg==", "dependencies": { - "character-entities-html4": "^1.0.0", - "character-entities-legacy": "^1.0.0", - "is-alphanumerical": "^1.0.0", - "is-hexadecimal": "^1.0.0" + "character-entities-html4": "^2.0.0", + "character-entities-legacy": "^3.0.0" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/stringify-entities/node_modules/character-entities-legacy": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/character-entities-legacy/-/character-entities-legacy-3.0.0.tgz", + "integrity": "sha512-RpPp0asT/6ufRm//AJVwpViZbGM/MkjQFxJccQRHmISF/22NBtsHqAWmL+/pmkPWoIUJdWyeVleTl1wydHATVQ==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" } }, "node_modules/strip-ansi": { @@ -25281,9 +26002,9 @@ } }, "node_modules/style-to-object": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.3.0.tgz", - "integrity": "sha512-CzFnRRXhzWIdItT3OmF8SQfWyahHhjq3HwcMNCNLn+N7klOOqPjMeG/4JSu77D7ypZdGvSzvkrbyeTMizz2VrA==", + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/style-to-object/-/style-to-object-0.4.4.tgz", + "integrity": "sha512-HYNoHZa2GorYNyqiCaBgsxvcJIn7OHq6inEga+E6Ke3m5JkoqpQbnFssk4jwe+K7AhGa2fcha4wSOf1Kn01dMg==", "dependencies": { "inline-style-parser": "0.1.1" } @@ -25575,6 +26296,22 @@ "node": ">= 4.7.0" } }, + "node_modules/synckit": { + "version": "0.9.2", + "resolved": "https://registry.npmjs.org/synckit/-/synckit-0.9.2.tgz", + "integrity": "sha512-vrozgXDQwYO72vHjUb/HnFbQx1exDjoKzqx23aXEg2a9VIg2TSFZ8FmeZpTjUCFMYw7mpX4BE2SFu8wI7asYsw==", + "dev": true, + "dependencies": { + "@pkgr/core": "^0.1.0", + "tslib": "^2.6.2" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts" + } + }, "node_modules/system-architecture": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/system-architecture/-/system-architecture-0.1.0.tgz", @@ -25939,6 +26676,20 @@ "node": ">=0.10.0" } }, + "node_modules/to-vfile": { + "version": "7.2.4", + "resolved": "https://registry.npmjs.org/to-vfile/-/to-vfile-7.2.4.tgz", + "integrity": "sha512-2eQ+rJ2qGbyw3senPI0qjuM7aut8IYXK6AEoOWb+fJx/mQYzviTckm1wDjq91QYHAPBTYzmdJXxMFA6Mk14mdw==", + "dev": true, + "dependencies": { + "is-buffer": "^2.0.0", + "vfile": "^5.1.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/toggle-selection": { "version": "1.0.6", "resolved": "https://registry.npmjs.org/toggle-selection/-/toggle-selection-1.0.6.tgz", @@ -25982,11 +26733,14 @@ "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" }, - "node_modules/trim": { - "version": "0.0.1", - "resolved": "https://registry.npmjs.org/trim/-/trim-0.0.1.tgz", - "integrity": "sha512-YzQV+TZg4AxpKxaTHK3c3D+kRDCGVEE7LemdlQZoQXn0iennk10RsIoY6ikzAqJTc9Xjl9C1/waHom/J86ziAQ==", - "deprecated": "Use String.prototype.trim() instead" + "node_modules/trim-lines": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/trim-lines/-/trim-lines-3.0.1.tgz", + "integrity": "sha512-kRj8B+YHZCc9kQYdWfJB2/oUl9rA99qbowYYBtr4ui4mZyAQ2JpvVBd/6U2YloATfqBhBTSMhTpgBHtU0Mf3Rg==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } }, "node_modules/trim-newlines": { "version": "3.0.1", @@ -26015,19 +26769,10 @@ "node": ">=0.8.0" } }, - "node_modules/trim-trailing-lines": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/trim-trailing-lines/-/trim-trailing-lines-1.1.4.tgz", - "integrity": "sha512-rjUWSqnfTNrjbB9NQWfPMH/xRK1deHeGsHoVfpxJ++XeYXE0d6B1En37AHfw3jtfTU7dzMzZL2jjpe8Qb5gLIQ==", - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/trough": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/trough/-/trough-1.0.5.tgz", - "integrity": "sha512-rvuRbTarPXmMb79SmzEp8aqXNKcK+y0XaB298IXueQ8I2PsrATcPBCSPyK/dDNa2iWOhKlfNnOjdAOTBU/nkFA==", + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/trough/-/trough-2.2.0.tgz", + "integrity": "sha512-tmMpK00BjZiUyVyvrBK7knerNgmgvcV/KLVyuma/SC+TQN167GrMRciANTz09+k3zW8L8t60jWO1GpfkZdjTaw==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -26268,19 +27013,6 @@ "is-typedarray": "^1.0.0" } }, - "node_modules/typescript": { - "version": "5.7.2", - "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.7.2.tgz", - "integrity": "sha512-i5t66RHxDvVN40HfDd1PsEThGNnlMCMT3jMUuoh9/0TaqWevNontacunWyN02LA9/fIbEWlcHZcgTKb9QoaLfg==", - "peer": true, - "bin": { - "tsc": "bin/tsc", - "tsserver": "bin/tsserver" - }, - "engines": { - "node": ">=14.17" - } - }, "node_modules/ua-parser-js": { "version": "1.0.39", "resolved": "https://registry.npmjs.org/ua-parser-js/-/ua-parser-js-1.0.39.tgz", @@ -26340,16 +27072,12 @@ "node": ">=0.10.0" } }, - "node_modules/underscore.string": { - "version": "3.3.6", - "resolved": "https://registry.npmjs.org/underscore.string/-/underscore.string-3.3.6.tgz", - "integrity": "sha512-VoC83HWXmCrF6rgkyxS9GHv8W9Q5nhMKho+OadDJGzL2oDYbYEppBaCMH6pFlwLeqj2QS+hhkw2kpXkSdD1JxQ==", - "dependencies": { - "sprintf-js": "^1.1.1", - "util-deprecate": "^1.0.2" - }, + "node_modules/undici": { + "version": "6.21.0", + "resolved": "https://registry.npmjs.org/undici/-/undici-6.21.0.tgz", + "integrity": "sha512-BUgJXc752Kou3oOIuU1i+yZZypyZRqNPW0vqoMPl8VaoalSfeR0D8/t4iAS3yirs79SSMTxTag+ZC86uswv+Cw==", "engines": { - "node": "*" + "node": ">=18.17" } }, "node_modules/undici-types": { @@ -26357,19 +27085,6 @@ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.19.8.tgz", "integrity": "sha512-ve2KP6f/JnbPBFyobGHuerC9g1FYGn/F8n1LWTwNxCEzd6IfqTwUQcNXgEtmmQ6DlRrC1hrSrBnCZPokRrDHjw==" }, - "node_modules/unherit": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/unherit/-/unherit-1.1.3.tgz", - "integrity": "sha512-Ft16BJcnapDKp0+J/rqFC3Rrk6Y/Ng4nzsC028k2jdDII/rdZ7Wd3pPT/6+vIIxRagwRc9K0IUX0Ra4fKvw+WQ==", - "dependencies": { - "inherits": "^2.0.0", - "xtend": "^4.0.0" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/wooorm" - } - }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.1.tgz", @@ -26403,32 +27118,215 @@ "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-2.1.0.tgz", "integrity": "sha512-6t3foTQI9qne+OZoVQB/8x8rk2k1eVy1gRXhV3oFQ5T6R1dqQ1xtin3XqSlx3+ATBkliTaR/hHyJBm+LVPNM8w==", "engines": { - "node": ">=4" + "node": ">=4" + } + }, + "node_modules/unified": { + "version": "10.1.2", + "resolved": "https://registry.npmjs.org/unified/-/unified-10.1.2.tgz", + "integrity": "sha512-pUSWAi/RAnVy1Pif2kAoeWNBa3JVrx0MId2LASj8G+7AiHWoKZNTomq6LG326T68U7/e263X6fTdcXIy7XnF7Q==", + "dependencies": { + "@types/unist": "^2.0.0", + "bail": "^2.0.0", + "extend": "^3.0.0", + "is-buffer": "^2.0.0", + "is-plain-obj": "^4.0.0", + "trough": "^2.0.0", + "vfile": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified-engine": { + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/unified-engine/-/unified-engine-10.1.0.tgz", + "integrity": "sha512-5+JDIs4hqKfHnJcVCxTid1yBoI/++FfF/1PFdSMpaftZZZY+qg2JFruRbf7PaIwa9KgLotXQV3gSjtY0IdcFGQ==", + "dev": true, + "dependencies": { + "@types/concat-stream": "^2.0.0", + "@types/debug": "^4.0.0", + "@types/is-empty": "^1.0.0", + "@types/node": "^18.0.0", + "@types/unist": "^2.0.0", + "concat-stream": "^2.0.0", + "debug": "^4.0.0", + "fault": "^2.0.0", + "glob": "^8.0.0", + "ignore": "^5.0.0", + "is-buffer": "^2.0.0", + "is-empty": "^1.0.0", + "is-plain-obj": "^4.0.0", + "load-plugin": "^5.0.0", + "parse-json": "^6.0.0", + "to-vfile": "^7.0.0", + "trough": "^2.0.0", + "unist-util-inspect": "^7.0.0", + "vfile-message": "^3.0.0", + "vfile-reporter": "^7.0.0", + "vfile-statistics": "^2.0.0", + "yaml": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unified-engine/node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "dev": true, + "dependencies": { + "@types/ms": "*" + } + }, + "node_modules/unified-engine/node_modules/@types/node": { + "version": "18.19.69", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.19.69.tgz", + "integrity": "sha512-ECPdY1nlaiO/Y6GUnwgtAAhLNaQ53AyIVz+eILxpEo5OvuqE6yWkqWBIb5dU0DqhKQtMeny+FBD3PK6lm7L5xQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, + "node_modules/unified-engine/node_modules/brace-expansion": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-2.0.1.tgz", + "integrity": "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0" + } + }, + "node_modules/unified-engine/node_modules/concat-stream": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/concat-stream/-/concat-stream-2.0.0.tgz", + "integrity": "sha512-MWufYdFw53ccGjCA+Ol7XJYpAlW6/prSMzuPOTRnJGcGzuhLn4Scrz7qf6o8bROZ514ltazcIFJZevcfbo0x7A==", + "dev": true, + "engines": [ + "node >= 6.0" + ], + "dependencies": { + "buffer-from": "^1.0.0", + "inherits": "^2.0.3", + "readable-stream": "^3.0.2", + "typedarray": "^0.0.6" + } + }, + "node_modules/unified-engine/node_modules/glob": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/glob/-/glob-8.1.0.tgz", + "integrity": "sha512-r8hpEjiQEYlF2QU0df3dS+nxxSIreXQS1qRhMJM0Q5NDdR386C7jb7Hwwod8Fgiuex+k0GFjgft18yvxm5XoCQ==", + "deprecated": "Glob versions prior to v9 are no longer supported", + "dev": true, + "dependencies": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^5.0.1", + "once": "^1.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/unified-engine/node_modules/is-plain-obj": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unified-engine/node_modules/lines-and-columns": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-2.0.4.tgz", + "integrity": "sha512-wM1+Z03eypVAVUCE7QdSqpVIvelbOakn1M0bPDoA4SGWPx3sNDVUiMo3L6To6WWGClB7VyXnhQ4Sn7gxiJbE6A==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, + "node_modules/unified-engine/node_modules/minimatch": { + "version": "5.1.6", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-5.1.6.tgz", + "integrity": "sha512-lKwV/1brpG6mBUFHtb7NUmtABCb2WZZmm2wNiOA5hAb8VdCS4B3dtMWyvcoViccwAW/COERjXLt0zP1zXUN26g==", + "dev": true, + "dependencies": { + "brace-expansion": "^2.0.1" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/unified-engine/node_modules/parse-json": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-6.0.2.tgz", + "integrity": "sha512-SA5aMiaIjXkAiBrW/yPgLgQAQg42f7K3ACO+2l/zOvtQBwX58DMUsFJXelW2fx3yMBmWOVkR6j1MGsdSbCA4UA==", + "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.0", + "error-ex": "^1.3.2", + "json-parse-even-better-errors": "^2.3.1", + "lines-and-columns": "^2.0.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/unified-engine/node_modules/readable-stream": { + "version": "3.6.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-3.6.2.tgz", + "integrity": "sha512-9u/sniCrY3D5WdsERHzHE4G2YCXqoG5FTHUiCC4SIbr6XcLZBY05ya9EKjYek9O5xOAwjGq+1JdGBAS7Q9ScoA==", + "dev": true, + "dependencies": { + "inherits": "^2.0.3", + "string_decoder": "^1.1.1", + "util-deprecate": "^1.0.1" + }, + "engines": { + "node": ">= 6" } }, - "node_modules/unified": { - "version": "9.2.0", - "resolved": "https://registry.npmjs.org/unified/-/unified-9.2.0.tgz", - "integrity": "sha512-vx2Z0vY+a3YoTj8+pttM3tiJHCwY5UFbYdiWrwBEbHmK8pvsPj2rtAX2BFfgXen8T39CJWblWRDT4L5WGXtDdg==", - "dependencies": { - "bail": "^1.0.0", - "extend": "^3.0.0", - "is-buffer": "^2.0.0", - "is-plain-obj": "^2.0.0", - "trough": "^1.0.0", - "vfile": "^4.0.0" + "node_modules/unified-engine/node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==", + "dev": true + }, + "node_modules/unified-engine/node_modules/yaml": { + "version": "2.7.0", + "resolved": "https://registry.npmjs.org/yaml/-/yaml-2.7.0.tgz", + "integrity": "sha512-+hSoy/QHluxmC9kCIJyL/uyFmLmc+e5CFR5Wa+bpIhIj85LVb9ZH2nVnqrHoSvKogwODv0ClqZkmiSSaIH5LTA==", + "dev": true, + "bin": { + "yaml": "bin.mjs" }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/unified" + "engines": { + "node": ">= 14" } }, "node_modules/unified/node_modules/is-plain-obj": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-2.1.0.tgz", - "integrity": "sha512-YWnfyRwxL/+SsrWYfOpUtz5b3YD+nyfkHvjbcanzk8zgyO4ASD67uVMRt8k5bM4lLMDnXfriRhOpemw+NfT1eA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz", + "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==", "engines": { - "node": ">=8" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/union-value": { @@ -26466,6 +27364,19 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-find-after": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/unist-util-find-after/-/unist-util-find-after-4.0.1.tgz", + "integrity": "sha512-QO/PuPMm2ERxC6vFXEPtmAutOopy5PknD+Oq64gGwxKtk4xwo9Z97t9Av1obPmGU0IyTa6EKYUfTrK2QJS3Ozw==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/unist-util-generated": { "version": "1.1.6", "resolved": "https://registry.npmjs.org/unist-util-generated/-/unist-util-generated-1.1.6.tgz", @@ -26475,29 +27386,25 @@ "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-is": { - "version": "4.1.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", - "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "node_modules/unist-util-inspect": { + "version": "7.0.2", + "resolved": "https://registry.npmjs.org/unist-util-inspect/-/unist-util-inspect-7.0.2.tgz", + "integrity": "sha512-Op0XnmHUl6C2zo/yJCwhXQSm/SmW22eDZdWP2qdf4WpGrgO1ZxFodq+5zFyeRGasFjJotAnLgfuD1jkcKqiH1Q==", + "dev": true, + "dependencies": { + "@types/unist": "^2.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-map": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/unist-util-map/-/unist-util-map-1.0.5.tgz", - "integrity": "sha512-dFil/AN6vqhnQWNCZk0GF/G3+Q5YwsB+PqjnzvpO2wzdRtUJ1E8PN+XRE/PRr/G3FzKjRTJU0haqE0Ekl+O3Ag==", - "dependencies": { - "object-assign": "^4.0.1" - } - }, - "node_modules/unist-util-modify-children": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/unist-util-modify-children/-/unist-util-modify-children-2.0.0.tgz", - "integrity": "sha512-HGrj7JQo9DwZt8XFsX8UD4gGqOsIlCih9opG6Y+N11XqkBGKzHo8cvDi+MfQQgiZ7zXRUiQREYHhjOBHERTMdg==", + "node_modules/unist-util-is": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-5.2.1.tgz", + "integrity": "sha512-u9njyyfEh43npf1M+yGKDGVPbY/JWEemg5nH05ncKPfi+kBbKBJoTdsogMu33uhytuLlv9y0O7GH7fEdwLdLQw==", "dependencies": { - "array-iterate": "^1.0.0" + "@types/unist": "^2.0.0" }, "funding": { "type": "opencollective", @@ -26505,69 +27412,97 @@ } }, "node_modules/unist-util-position": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-3.1.0.tgz", - "integrity": "sha512-w+PkwCbYSFw8vpgWD0v7zRCl1FpY3fjDSQ3/N/wNd9Ffa4gPi8+4keqt99N3XW6F99t/mUzp2xAhNmfKWp95QA==", + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/unist-util-position/-/unist-util-position-4.0.4.tgz", + "integrity": "sha512-kUBE91efOWfIVBo8xzh/uZQ7p9ffYRtUbMRZBNFYwf0RK8koUMx6dGUfwylLOKmaT2cs4wSW96QoYUSXAyEtpg==", + "dependencies": { + "@types/unist": "^2.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-remove": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/unist-util-remove/-/unist-util-remove-1.0.3.tgz", - "integrity": "sha512-mB6nCHCQK0pQffUAcCVmKgIWzG/AXs/V8qpS8K72tMPtOSCMSjDeMc5yN+Ye8rB0FhcE+JvW++o1xRNc0R+++g==", + "node_modules/unist-util-position-from-estree": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/unist-util-position-from-estree/-/unist-util-position-from-estree-1.1.2.tgz", + "integrity": "sha512-poZa0eXpS+/XpoQwGwl79UUdea4ol2ZuCYguVaJS4qzIOMDzbqz8a3erUCOmubSZkaOuGamb3tX790iwOIROww==", "dependencies": { - "unist-util-is": "^3.0.0" + "@types/unist": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" } }, "node_modules/unist-util-remove-position": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-2.0.1.tgz", - "integrity": "sha512-fDZsLYIe2uT+oGFnuZmy73K6ZxOPG/Qcm+w7jbEjaFcJgbQ6cqjs/eSPzXhsmGpAsWPkqZM9pYjww5QTn3LHMA==", + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/unist-util-remove-position/-/unist-util-remove-position-4.0.2.tgz", + "integrity": "sha512-TkBb0HABNmxzAcfLf4qsIbFbaPDvMO6wa3b3j4VcEzFVaw1LBKwnW4/sRJ/atSLSzoIg41JWEdnE7N6DIhGDGQ==", "dependencies": { - "unist-util-visit": "^2.0.0" + "@types/unist": "^2.0.0", + "unist-util-visit": "^4.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-remove/node_modules/unist-util-is": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-3.0.0.tgz", - "integrity": "sha512-sVZZX3+kspVNmLWBPAB6r+7D9ZgAFPNWm66f7YNb420RlQSbn+n8rG8dGZSkrER7ZIXGQYNm5pqC3v3HopH24A==" - }, - "node_modules/unist-util-stringify-position": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-2.0.3.tgz", - "integrity": "sha512-3faScn5I+hy9VleOq/qNbAd6pAx7iH5jYBMS9I1HgQVijz/4mv5Bvw5iw1sC/90CODiKo81G/ps8AJrISn687g==", + "node_modules/unist-util-select": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/unist-util-select/-/unist-util-select-3.0.4.tgz", + "integrity": "sha512-xf1zCu4okgPqGLdhCDpRnjwBNyv3EqjiXRUbz2SdK1+qnLMB7uXXajfzuBvvbHoQ+JLyp4AEbFCGndmc6S72sw==", "dependencies": { - "@types/unist": "^2.0.2" + "css-selector-parser": "^1.0.0", + "not": "^0.1.0", + "nth-check": "^2.0.0", + "unist-util-is": "^4.0.0", + "zwitch": "^1.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-visit": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-2.0.3.tgz", - "integrity": "sha512-iJ4/RczbJMkD0712mGktuGpm/U4By4FfDonL7N/9tATGIF4imikjOuagyMY53tnZq3NP6BcmlrHhEKAfGWjh7Q==", + "node_modules/unist-util-select/node_modules/unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-select/node_modules/zwitch": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", + "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "funding": { + "type": "github", + "url": "https://github.com/sponsors/wooorm" + } + }, + "node_modules/unist-util-stringify-position": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/unist-util-stringify-position/-/unist-util-stringify-position-3.0.3.tgz", + "integrity": "sha512-k5GzIBZ/QatR8N5X2y+drfpWG8IDBzdnVj6OInRNWm1oXrzydiaAT2OQiA8DPRRZyAKb9b6I2a6PxYklZD0gKg==", "dependencies": { - "@types/unist": "^2.0.0", - "unist-util-is": "^4.0.0", - "unist-util-visit-parents": "^3.0.0" + "@types/unist": "^2.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, - "node_modules/unist-util-visit-children": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/unist-util-visit-children/-/unist-util-visit-children-1.1.4.tgz", - "integrity": "sha512-sA/nXwYRCQVRwZU2/tQWUqJ9JSFM1X3x7JIOsIgSzrFHcfVt6NkzDtKzyxg2cZWkCwGF9CO8x4QNZRJRMK8FeQ==", + "node_modules/unist-util-visit": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/unist-util-visit/-/unist-util-visit-4.1.2.tgz", + "integrity": "sha512-MSd8OUGISqHdVvfY9TPhyK2VdUrPgxkUtWSuMHF6XAAFuL4LokseigBnZtPnJMu+FbynTkFNnFlyjxpVKujMRg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0", + "unist-util-visit-parents": "^5.1.1" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" @@ -26586,6 +27521,28 @@ "url": "https://opencollective.com/unified" } }, + "node_modules/unist-util-visit-parents/node_modules/unist-util-is": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/unist-util-is/-/unist-util-is-4.1.0.tgz", + "integrity": "sha512-ZOQSsnce92GrxSqlnEEseX0gi7GH9zTJZ0p9dtu87WRb/37mMPO2Ilx1s/t9vBHrFhbgweUwb+t7cIn5dxPhZg==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/unist-util-visit/node_modules/unist-util-visit-parents": { + "version": "5.1.3", + "resolved": "https://registry.npmjs.org/unist-util-visit-parents/-/unist-util-visit-parents-5.1.3.tgz", + "integrity": "sha512-x6+y8g7wWMyQhL1iZfhIPhDAs7Xwbn9nRosDXl7qoPTSCy0yNxnKc+hWokFifWQIDGi154rdUqKvbCa4+1kLhg==", + "dependencies": { + "@types/unist": "^2.0.0", + "unist-util-is": "^5.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, "node_modules/universalify": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/universalify/-/universalify-2.0.1.tgz", @@ -26873,15 +27830,6 @@ } } }, - "node_modules/use-sync-external-store": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.4.0.tgz", - "integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==", - "peer": true, - "peerDependencies": { - "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" - } - }, "node_modules/util-deprecate": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", @@ -26916,6 +27864,31 @@ "uuid": "dist/bin/uuid" } }, + "node_modules/uvu": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/uvu/-/uvu-0.5.6.tgz", + "integrity": "sha512-+g8ENReyr8YsOc6fv/NVJs2vFdHBnBNdfE49rshrTzDWOlUx4Gq7KOS2GD8eqhy2j+Ejq29+SbKH8yjkAqXqoA==", + "dependencies": { + "dequal": "^2.0.0", + "diff": "^5.0.0", + "kleur": "^4.0.3", + "sade": "^1.7.3" + }, + "bin": { + "uvu": "bin.js" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/uvu/node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "engines": { + "node": ">=6" + } + }, "node_modules/v8-compile-cache": { "version": "2.4.0", "resolved": "https://registry.npmjs.org/v8-compile-cache/-/v8-compile-cache-2.4.0.tgz", @@ -26952,14 +27925,14 @@ } }, "node_modules/vfile": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/vfile/-/vfile-4.2.1.tgz", - "integrity": "sha512-O6AE4OskCG5S1emQ/4gl8zK586RqA3srz3nfK/Viy0UPToBc5Trp9BVFb1u0CjsKrAWwnpr4ifM/KBXPWwJbCA==", + "version": "5.3.7", + "resolved": "https://registry.npmjs.org/vfile/-/vfile-5.3.7.tgz", + "integrity": "sha512-r7qlzkgErKjobAmyNIkkSpizsFPYiUPuJb5pNW1RB4JcYVZhs4lIbVqk8XPk033CV/1z8ss5pkax8SuhGpcG8g==", "dependencies": { "@types/unist": "^2.0.0", "is-buffer": "^2.0.0", - "unist-util-stringify-position": "^2.0.0", - "vfile-message": "^2.0.0" + "unist-util-stringify-position": "^3.0.0", + "vfile-message": "^3.0.0" }, "funding": { "type": "opencollective", @@ -26967,27 +27940,141 @@ } }, "node_modules/vfile-location": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-3.2.0.tgz", - "integrity": "sha512-aLEIZKv/oxuCDZ8lkJGhuhztf/BW4M+iHdCwglA/eWc+vtuRFJj8EtgceYFX4LRjOhCAAiNHsKGssC6onJ+jbA==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/vfile-location/-/vfile-location-4.1.0.tgz", + "integrity": "sha512-YF23YMyASIIJXpktBa4vIGLJ5Gs88UB/XePgqPmTa7cDA+JeO3yclbpheQYCHjVHBn/yePzrXuygIL+xbvRYHw==", + "dependencies": { + "@types/unist": "^2.0.0", + "vfile": "^5.0.0" + }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, "node_modules/vfile-message": { - "version": "2.0.4", - "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-2.0.4.tgz", - "integrity": "sha512-DjssxRGkMvifUOJre00juHoP9DPWuzjxKuMDrhNbk2TdaYYBNMStsNhEOt3idrtI12VQYM/1+iM0KOzXi4pxwQ==", + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/vfile-message/-/vfile-message-3.1.4.tgz", + "integrity": "sha512-fa0Z6P8HUrQN4BZaX05SIVXic+7kE3b05PWAtPuYP9QLHsLKYR7/AlLW3NtOrpXRLeawpDLMsVkmk5DG0NXgWw==", "dependencies": { "@types/unist": "^2.0.0", - "unist-util-stringify-position": "^2.0.0" + "unist-util-stringify-position": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-reporter": { + "version": "7.0.5", + "resolved": "https://registry.npmjs.org/vfile-reporter/-/vfile-reporter-7.0.5.tgz", + "integrity": "sha512-NdWWXkv6gcd7AZMvDomlQbK3MqFWL1RlGzMn++/O2TI+68+nqxCPTvLugdOtfSzXmjh+xUyhp07HhlrbJjT+mw==", + "dev": true, + "dependencies": { + "@types/supports-color": "^8.0.0", + "string-width": "^5.0.0", + "supports-color": "^9.0.0", + "unist-util-stringify-position": "^3.0.0", + "vfile": "^5.0.0", + "vfile-message": "^3.0.0", + "vfile-sort": "^3.0.0", + "vfile-statistics": "^2.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-reporter/node_modules/ansi-regex": { + "version": "6.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.1.0.tgz", + "integrity": "sha512-7HSX4QQb4CspciLpVFwyRe79O3xsIZDDLER21kERQ71oaPodF8jL725AgJMFAYbooIqolJoRLuM81SpeUkpkvA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/vfile-reporter/node_modules/string-width": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", + "integrity": "sha512-HnLOCR3vjcY8beoNLtcjZ5/nxn2afmME6lhrDrebokqMap+XbeW8n9TXpPDOqdGK5qcI3oT0GKTW6wC7EMiVqA==", + "dev": true, + "dependencies": { + "eastasianwidth": "^0.2.0", + "emoji-regex": "^9.2.2", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/vfile-reporter/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/vfile-reporter/node_modules/supports-color": { + "version": "9.4.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-9.4.0.tgz", + "integrity": "sha512-VL+lNrEoIXww1coLPOmiEmK/0sGigko5COxI09KzHc2VJXJsQ37UaQ+8quuxjDeA7+KnLGTWRyOXSLLR2Wb4jw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/supports-color?sponsor=1" + } + }, + "node_modules/vfile-sort": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/vfile-sort/-/vfile-sort-3.0.1.tgz", + "integrity": "sha512-1os1733XY6y0D5x0ugqSeaVJm9lYgj0j5qdcZQFyxlZOSy1jYarL77lLyb5gK4Wqr1d5OxmuyflSO3zKyFnTFw==", + "dev": true, + "dependencies": { + "vfile": "^5.0.0", + "vfile-message": "^3.0.0" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/unified" + } + }, + "node_modules/vfile-statistics": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/vfile-statistics/-/vfile-statistics-2.0.1.tgz", + "integrity": "sha512-W6dkECZmP32EG/l+dp2jCLdYzmnDBIw6jwiLZSER81oR5AHRcVqL+k3Z+pfH1R73le6ayDkJRMk0sutj1bMVeg==", + "dev": true, + "dependencies": { + "vfile": "^5.0.0", + "vfile-message": "^3.0.0" }, "funding": { "type": "opencollective", "url": "https://opencollective.com/unified" } }, + "node_modules/walk-up-path": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/walk-up-path/-/walk-up-path-3.0.1.tgz", + "integrity": "sha512-9YlCL/ynK3CTlrSRrDxZvUauLzAswPCrsaCgilqFevUYpeEW0/3ScEjaa3kbW/T0ghhkEr7mv+fpjqn1Y1YuTA==", + "dev": true + }, "node_modules/warning": { "version": "4.0.3", "resolved": "https://registry.npmjs.org/warning/-/warning-4.0.3.tgz", @@ -27014,9 +28101,9 @@ "integrity": "sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==" }, "node_modules/web-namespaces": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-1.1.4.tgz", - "integrity": "sha512-wYxSGajtmoP4WxfejAPIr4l0fVh+jeMXZb08wNc0tMg6xsfZXj3cECqIK0G7ZAqUq0PP8WlMDtaOGVBTAWztNw==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/web-namespaces/-/web-namespaces-2.0.1.tgz", + "integrity": "sha512-bKr1DkiNa2krS7qxNtdrtHAmzuYGFQLiQ13TsorsdT6ULTkPLKuu5+GsFpDlg6JFjUTwX2DyhMPG2be8uPrqsQ==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" @@ -27341,11 +28428,41 @@ "node": ">=10.13.0" } }, + "node_modules/whatwg-encoding": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-3.1.1.tgz", + "integrity": "sha512-6qN4hJdMwfYBtE3YBTTHhoeuUrDBPZmbQaxWAqSALV/MeEnR5z1xd8UKud2RAkFoPkmB+hli1TZSnyi84xz1vQ==", + "dependencies": { + "iconv-lite": "0.6.3" + }, + "engines": { + "node": ">=18" + } + }, + "node_modules/whatwg-encoding/node_modules/iconv-lite": { + "version": "0.6.3", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", + "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", + "dependencies": { + "safer-buffer": ">= 2.1.2 < 3.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/whatwg-fetch": { "version": "2.0.4", "resolved": "https://registry.npmjs.org/whatwg-fetch/-/whatwg-fetch-2.0.4.tgz", "integrity": "sha512-dcQ1GWpOD/eEQ97k66aiEVpNnapVj90/+R+SXTPYGHpYBBypfKJEQjLrvMZ7YXbKm21gXd4NcuxUTjiv1YtLng==" }, + "node_modules/whatwg-mimetype": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/whatwg-mimetype/-/whatwg-mimetype-4.0.0.tgz", + "integrity": "sha512-QaKxh0eNIi2mE9p2vEdzfagOKHCcj1pJ56EEHGQOVxp8r9/iszLUUV7v89x9O1p/T+NlTM5W7jW6+cz4Fq1YVg==", + "engines": { + "node": ">=18" + } + }, "node_modules/whatwg-url": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", @@ -27611,11 +28728,6 @@ } } }, - "node_modules/x-is-string": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/x-is-string/-/x-is-string-0.1.0.tgz", - "integrity": "sha512-GojqklwG8gpzOVEVki5KudKNoq7MbbjYZCbyWzEz7tyPA7eleiE0+ePwOWQQRb5fm86rD3S8Tc0tSFf3AOv50w==" - }, "node_modules/xdg-basedir": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/xdg-basedir/-/xdg-basedir-4.0.0.tgz", @@ -27856,9 +28968,9 @@ } }, "node_modules/zwitch": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-1.0.5.tgz", - "integrity": "sha512-V50KMwwzqJV0NpZIZFwfOD5/lyny3WlSzRiXgA0G7VUnRlqttta1L6UQIHzd6EuBY/cHGfwTIck7w1yH6Q5zUw==", + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/zwitch/-/zwitch-2.0.4.tgz", + "integrity": "sha512-bXE4cR/kVZhKZX/RjPEflHaKVhUVl85noU3v6b8apfQEc1x4A+zBxjZ4lN8LqGd6WZ3dl98pY4o717VFmoPp+A==", "funding": { "type": "github", "url": "https://github.com/sponsors/wooorm" diff --git a/package.json b/package.json index 8e691fea64a2..430878fbdb2d 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "start": "npm run develop", "serve": "gatsby serve", "lint": "eslint --fix .", - "checklint": "eslint .", + "checklint": "eslint . --ext js,md,mdx", "pretest": "eslint --ignore-path .gitignore .", "preload-fonts": "gatsby-preload-fonts", "deploy": "gatsby build && gh-pages -d public -b master", @@ -29,17 +29,14 @@ "@emotion/react": "^11.11.4", "@emotion/styled": "^11.14.0", "@fullcalendar/core": "^6.1.8", - "@fullcalendar/daygrid": "^6.1.8", - "@fullcalendar/google-calendar": "^6.0.2", - "@fullcalendar/interaction": "^6.0.1", - "@fullcalendar/react": "^6.1.8", - "@layer5/meshery-design-embed": "^0.4.0", - "@layer5/sistent": "^0.14.109", - "@loadable/component": "^5.16.4", - "@mdx-js/mdx": "1.6.22", - "@mdx-js/react": "1.6.22", - "@mediacurrent/gatsby-plugin-silence-css-order-warning": "^1.0.0", - "@mui/icons-material": "^5.16.4", + "@fullcalendar/daygrid": "^5.11.3", + "@fullcalendar/google-calendar": "^6.1.9", + "@fullcalendar/interaction": "^6.1.13", + "@fullcalendar/react": "^5.11.2", + "@layer5/meshery-design-embed": "^0.2.0", + "@layer5/sistent": "^0.14.60", + "@loadable/component": "^5.15.3", + "@mdx-js/react": "^2.3.0", "@mui/material": "^5.15.11", "@react-icons/all-files": "^4.1.0", "@svgr/webpack": "^8.0.1", @@ -63,8 +60,9 @@ "gatsby-plugin-image": "^3.11.0", "gatsby-plugin-loadable-components-ssr": "^4.3.2", "gatsby-plugin-manifest": "^5.11.0", - "gatsby-plugin-mdx": "3.20.0", + "gatsby-plugin-mdx": "^5.0.0", "gatsby-plugin-meta-redirect": "github:layer5labs/gatsby-plugin-meta-redirect", + "gatsby-plugin-no-sourcemaps": "^4.25.0", "gatsby-plugin-preload-fonts": "^4.11.0", "gatsby-plugin-robots-txt": "^1.8.0", "gatsby-plugin-sharp": "^5.11.0", @@ -72,6 +70,7 @@ "gatsby-plugin-styled-components": "^6.11.0", "gatsby-plugin-svgr": "^3.0.0-beta.0", "gatsby-redirect-from": "1.0.4", + "gatsby-remark-images": "^6.25.0", "gatsby-source-filesystem": "^5.14.0", "gatsby-transformer-sharp": "^5.11.0", "gbimage-bridge": "^0.2.2", @@ -84,6 +83,7 @@ "path-browserify": "^1.0.1", "prism-react-renderer": "^2.0.6", "process": "^0.11.10", + "process-top": "^1.2.0", "prop-types": "^15.7.2", "react": "^18.2.0", "react-accessible-accordion": "^5.0.0", @@ -95,6 +95,7 @@ "react-honeycomb": "^0.1.3", "react-intersection-observer": "^9.5.2", "react-loadable": "^5.5.0", + "react-markdown": "^8.0.7", "react-modal": "^3.16.1", "react-player": "^2.12.0", "react-scroll": "^1.9.0", @@ -107,6 +108,8 @@ "react-tsparticles": "^2.11.0", "react-vertical-timeline-component": "^3.5.2", "react-visibility-sensor": "^5.1.1", + "rehype-raw": "^6.1.1", + "remark-gfm": "^1.0.0", "sharp": "^0.33.5", "simple-react-cytoscape": "^1.0.4", "simple-react-lightbox": "^3.6.9-0", @@ -124,8 +127,9 @@ "babel-plugin-module-resolver": "^5.0.0", "cpx": "^1.5.0", "env-cmd": "^10.1.0", - "eslint": "^8.46.0", - "eslint-plugin-react": "^7.37.3", + "eslint": "^8.57.0", + "eslint-plugin-mdx": "^2.1.0", + "eslint-plugin-react": "^7.34.2", "gatsby-plugin-webpack-bundle-analyser-v2": "^1.1.30", "gh-pages": "^6.0.0", "husky": "^8.0.3", diff --git a/root-wrapper.js b/root-wrapper.js index c22a84f4f4ff..d835a9308a8e 100644 --- a/root-wrapper.js +++ b/root-wrapper.js @@ -1,34 +1,8 @@ import React from "react"; -import { MDXProvider } from "@mdx-js/react"; -import Code from "./src/components/CodeBlock"; -import CTA_ImageOnly from "./src/components/Call-To-Actions/CTA_ImageOnly"; -import CTA_FullWidth from "./src/components/Call-To-Actions/CTA_FullWidth"; -import CTA_Bottom from "./src/components/Call-To-Actions/CTA_Bottom"; import { ContextWrapper } from "./context-wrapper"; -const components = { - pre: ({ children: { props } }) => { - if (props.mdxType === "code") { - return ( - - ); - } - }, - CTA_ImageOnly, - CTA_FullWidth, - CTA_Bottom -}; - export const wrapRootElement = ({ element }) => ( - - {element} - + {element} ); \ No newline at end of file diff --git a/src/assets/discuss/html/footer.html b/src/assets/discuss/html/footer.html index cd11cd1797b4..d19983746338 100644 --- a/src/assets/discuss/html/footer.html +++ b/src/assets/discuss/html/footer.html @@ -1,105 +1,105 @@ - + diff --git a/src/assets/images/Community-pictures/9 gsoc-shirt.webp b/src/assets/images/Community-pictures/9 gsoc-shirt.webp index c941383bbe66..bee12e4aac4c 100644 Binary files a/src/assets/images/Community-pictures/9 gsoc-shirt.webp and b/src/assets/images/Community-pictures/9 gsoc-shirt.webp differ diff --git a/src/assets/images/kanvas-snapshot/kanvas-snapshot.svg b/src/assets/images/kanvas-snapshot/kanvas-snapshot.svg index 694ca086fcd4..e5abf6b018fa 100644 --- a/src/assets/images/kanvas-snapshot/kanvas-snapshot.svg +++ b/src/assets/images/kanvas-snapshot/kanvas-snapshot.svg @@ -1,67 +1,67 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/kanvas/catalog-card-images/circuit-breaker.svg b/src/assets/images/kanvas/catalog-card-images/circuit-breaker.svg index 5e64363db7ba..b1288a2acfeb 100644 --- a/src/assets/images/kanvas/catalog-card-images/circuit-breaker.svg +++ b/src/assets/images/kanvas/catalog-card-images/circuit-breaker.svg @@ -1,59 +1,59 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/kanvas/catalog-card-images/correlate-event.svg b/src/assets/images/kanvas/catalog-card-images/correlate-event.svg index 17cd906b8996..3b18c550f8d4 100644 --- a/src/assets/images/kanvas/catalog-card-images/correlate-event.svg +++ b/src/assets/images/kanvas/catalog-card-images/correlate-event.svg @@ -1,25 +1,25 @@ - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/kanvas/catalog-card-images/denial.svg b/src/assets/images/kanvas/catalog-card-images/denial.svg index 975ab9221d80..cbab4f02d620 100644 --- a/src/assets/images/kanvas/catalog-card-images/denial.svg +++ b/src/assets/images/kanvas/catalog-card-images/denial.svg @@ -1,71 +1,71 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/kanvas/catalog-card-images/http.svg b/src/assets/images/kanvas/catalog-card-images/http.svg index efdc2d464f33..029fda02ca02 100644 --- a/src/assets/images/kanvas/catalog-card-images/http.svg +++ b/src/assets/images/kanvas/catalog-card-images/http.svg @@ -1,19 +1,19 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/kanvas/catalog-card-images/jwt.svg b/src/assets/images/kanvas/catalog-card-images/jwt.svg index a8138cd74a81..f8b7618b3784 100644 --- a/src/assets/images/kanvas/catalog-card-images/jwt.svg +++ b/src/assets/images/kanvas/catalog-card-images/jwt.svg @@ -1,18 +1,18 @@ - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/kanvas/catalog-card-images/multicluster.svg b/src/assets/images/kanvas/catalog-card-images/multicluster.svg index cfc819673ec7..9060b3a3ada7 100644 --- a/src/assets/images/kanvas/catalog-card-images/multicluster.svg +++ b/src/assets/images/kanvas/catalog-card-images/multicluster.svg @@ -1,78 +1,78 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/kanvas/catalog-card-images/mutual-tls.svg b/src/assets/images/kanvas/catalog-card-images/mutual-tls.svg index c3a87eaa21f6..e1b7194d4324 100644 --- a/src/assets/images/kanvas/catalog-card-images/mutual-tls.svg +++ b/src/assets/images/kanvas/catalog-card-images/mutual-tls.svg @@ -1,52 +1,52 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/kanvas/catalog-card-images/node-agent.svg b/src/assets/images/kanvas/catalog-card-images/node-agent.svg index cbc3a4e3727e..b12b5652b0d4 100644 --- a/src/assets/images/kanvas/catalog-card-images/node-agent.svg +++ b/src/assets/images/kanvas/catalog-card-images/node-agent.svg @@ -1,62 +1,62 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/kanvas/catalog-card-images/only-wagent.svg b/src/assets/images/kanvas/catalog-card-images/only-wagent.svg index ce5f03343d3d..0b6863aac3d1 100644 --- a/src/assets/images/kanvas/catalog-card-images/only-wagent.svg +++ b/src/assets/images/kanvas/catalog-card-images/only-wagent.svg @@ -1,15 +1,15 @@ - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + diff --git a/src/assets/images/kanvas/catalog-card-images/pre-provision.svg b/src/assets/images/kanvas/catalog-card-images/pre-provision.svg index 2a638a45a5b2..d82eb0fdeb11 100644 --- a/src/assets/images/kanvas/catalog-card-images/pre-provision.svg +++ b/src/assets/images/kanvas/catalog-card-images/pre-provision.svg @@ -1,44 +1,44 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/kanvas/catalog-card-images/retries.svg b/src/assets/images/kanvas/catalog-card-images/retries.svg index 54f6869acdbd..33a6d3fba875 100644 --- a/src/assets/images/kanvas/catalog-card-images/retries.svg +++ b/src/assets/images/kanvas/catalog-card-images/retries.svg @@ -1,52 +1,52 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/kanvas/catalog-card-images/retry-deadline.svg b/src/assets/images/kanvas/catalog-card-images/retry-deadline.svg index 1167f8a883d5..06b5d6db6ece 100644 --- a/src/assets/images/kanvas/catalog-card-images/retry-deadline.svg +++ b/src/assets/images/kanvas/catalog-card-images/retry-deadline.svg @@ -1,64 +1,64 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/kanvas/catalog-card-images/single-tenant.svg b/src/assets/images/kanvas/catalog-card-images/single-tenant.svg index 8207cc21b9cb..3ea9b9f27cb9 100644 --- a/src/assets/images/kanvas/catalog-card-images/single-tenant.svg +++ b/src/assets/images/kanvas/catalog-card-images/single-tenant.svg @@ -1,54 +1,54 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/kanvas/catalog-card-images/singleton.svg b/src/assets/images/kanvas/catalog-card-images/singleton.svg index 25996a86e9a3..54a0e729a315 100644 --- a/src/assets/images/kanvas/catalog-card-images/singleton.svg +++ b/src/assets/images/kanvas/catalog-card-images/singleton.svg @@ -1,19 +1,19 @@ - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/kanvas/catalog-card-images/traces.svg b/src/assets/images/kanvas/catalog-card-images/traces.svg index f8126b2c369c..7c65416dbb08 100644 --- a/src/assets/images/kanvas/catalog-card-images/traces.svg +++ b/src/assets/images/kanvas/catalog-card-images/traces.svg @@ -1,34 +1,34 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/assets/images/kanvas/ebpf.svg b/src/assets/images/kanvas/ebpf.svg index 53c7ce7df3f7..266cded0ce3e 100644 --- a/src/assets/images/kanvas/ebpf.svg +++ b/src/assets/images/kanvas/ebpf.svg @@ -1,12 +1,12 @@ - - - - - - - - - - - - + + + + + + + + + + + + diff --git a/src/assets/images/kanvas/opa.svg b/src/assets/images/kanvas/opa.svg index ef7dbca5d7be..18f992db511c 100644 --- a/src/assets/images/kanvas/opa.svg +++ b/src/assets/images/kanvas/opa.svg @@ -1,6 +1,6 @@ - - - - - - + + + + + + diff --git a/src/assets/images/learn-layer5/istio/Prometheus.webp b/src/assets/images/learn-layer5/istio/Prometheus.webp index 0aaa2deff88e..19a2c1072983 100644 Binary files a/src/assets/images/learn-layer5/istio/Prometheus.webp and b/src/assets/images/learn-layer5/istio/Prometheus.webp differ diff --git a/src/assets/integration-template/icon/color/integration-template-color.svg b/src/assets/integration-template/icon/color/integration-template-color.svg new file mode 100644 index 000000000000..f67472307973 --- /dev/null +++ b/src/assets/integration-template/icon/color/integration-template-color.svg @@ -0,0 +1,33 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/src/assets/integration-template/icon/white/integration-template-white.svg b/src/assets/integration-template/icon/white/integration-template-white.svg new file mode 100644 index 000000000000..aa9e84b87c10 --- /dev/null +++ b/src/assets/integration-template/icon/white/integration-template-white.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/src/assets/integration-template/index.mdx b/src/assets/integration-template/index.mdx new file mode 100644 index 000000000000..e69de29bb2d1 diff --git a/src/collections/blog/2019/2019-05-21-a-standard-interface-for-service-meshes/index.mdx b/src/collections/blog/2019/2019-05-21-a-standard-interface-for-service-meshes/index.mdx index 51704afda6bb..bababb93ce46 100644 --- a/src/collections/blog/2019/2019-05-21-a-standard-interface-for-service-meshes/index.mdx +++ b/src/collections/blog/2019/2019-05-21-a-standard-interface-for-service-meshes/index.mdx @@ -1,39 +1,39 @@ ---- -title: "A Standard Interface for Service Meshes" -subtitle: "" -date: 2019-05-21 12:15:05 +0000 -author: Lee Calcote -thumbnail: ./smi-logo.webp -darkthumbnail: ./smi-logo.webp -category: Announcements -tags: - - "Service Mesh Interface" -type: Blog -product: Service Mesh Landscape -resource: true -published: true -redirect_from: - - /blog/a-standard-interface-for-service-meshes/ ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import SmiLogo from "./smi-logo.webp"; - - - -SMI Logo - -Most began their cloud native journey with their first step being use of containers, and taking a second step, moved into container orchestration as their workloads grew. Now, waves and waves of organizations are considering service meshes as their third significant step in their cloud native journey. As they invest into service meshes as their next layer of key infrastructure, users will continue to look for the same assurances sought from other commonly accepted (standard) interfaces for container runtimes (e.g. CRI), container storage (e.g. CSI), container networking (e.g. CNI) and they will look for a commonly accepted service mesh interface. - -As a prominent supporter of management software for multiple service meshes, Layer5 is pleased to partner with Microsoft in support of the [Service Mesh Interface](https://smi-spec.io) (SMI). The Service Mesh Interface is a specification for service meshes that run on Kubernetes. As such, SMI defines a common standard that can be implemented by a variety of service mesh projects and vendors. - -Like standards before SMI, consistent APIs inspire confidence in infrastructure stability, community-managed APIs assuage technology and vendor lock-in concerns, and steward the resounding of core use cases, resulting in streamlining the smaller, but critical-to-users, subset of capabilities offered across the [service mesh landscape](https://layer5.io/landscape). - -Meshery and SMI are aligned on common goals of getting users started quickly, understanding that users want service mesh technology, but have questions as to which service mesh use, how, and when to get started through a common interface. Meshery’s playground capabilities quick provision a variety of service meshes and reduce time to value and time to understanding for those adopting a service mesh. - -As a multi-mesh manager, Meshery, understands that each service mesh has it own strengths. SMI intends to allow for differentiation by service mesh providers, at the same time providing interoperability between service meshes and their surrounding tooling. As a management plane, Meshery enhances networking intelligence in a multi-mesh way, encouraging users to expect more from their infrastructure. Meshery exposes each service mesh’s differentiated capabilities. - -SMI’s aim for consistent APIs facilitates Meshery’s same goals, allowing for users and tools to flourish. As SMI unveils today, so does Meshery’s compatibility. Try out [Meshery and SMI](https://layer5.io/meshery) today! - - - +--- +title: "A Standard Interface for Service Meshes" +subtitle: "" +date: 2019-05-21 12:15:05 +0000 +author: Lee Calcote +thumbnail: ./smi-logo.webp +darkthumbnail: ./smi-logo.webp +category: Announcements +tags: + - "Service Mesh Interface" +type: Blog +product: Service Mesh Landscape +resource: true +published: true +redirect_from: + - /blog/a-standard-interface-for-service-meshes/ +--- + + +import SmiLogo from "./smi-logo.webp"; + + + +SMI Logo + +Most began their cloud native journey with their first step being use of containers, and taking a second step, moved into container orchestration as their workloads grew. Now, waves and waves of organizations are considering service meshes as their third significant step in their cloud native journey. As they invest into service meshes as their next layer of key infrastructure, users will continue to look for the same assurances sought from other commonly accepted (standard) interfaces for container runtimes (e.g. CRI), container storage (e.g. CSI), container networking (e.g. CNI) and they will look for a commonly accepted service mesh interface. + +As a prominent supporter of management software for multiple service meshes, Layer5 is pleased to partner with Microsoft in support of the [Service Mesh Interface](https://smi-spec.io) (SMI). The Service Mesh Interface is a specification for service meshes that run on Kubernetes. As such, SMI defines a common standard that can be implemented by a variety of service mesh projects and vendors. + +Like standards before SMI, consistent APIs inspire confidence in infrastructure stability, community-managed APIs assuage technology and vendor lock-in concerns, and steward the resounding of core use cases, resulting in streamlining the smaller, but critical-to-users, subset of capabilities offered across the [service mesh landscape](https://layer5.io/landscape). + +Meshery and SMI are aligned on common goals of getting users started quickly, understanding that users want service mesh technology, but have questions as to which service mesh use, how, and when to get started through a common interface. Meshery’s playground capabilities quick provision a variety of service meshes and reduce time to value and time to understanding for those adopting a service mesh. + +As a multi-mesh manager, Meshery, understands that each service mesh has it own strengths. SMI intends to allow for differentiation by service mesh providers, at the same time providing interoperability between service meshes and their surrounding tooling. As a management plane, Meshery enhances networking intelligence in a multi-mesh way, encouraging users to expect more from their infrastructure. Meshery exposes each service mesh’s differentiated capabilities. + +SMI’s aim for consistent APIs facilitates Meshery’s same goals, allowing for users and tools to flourish. As SMI unveils today, so does Meshery’s compatibility. Try out [Meshery and SMI](https://layer5.io/meshery) today! + + + diff --git a/src/collections/blog/2019/2019-07-09-Meshery-start-feat-WSL2-K3d/index.mdx b/src/collections/blog/2019/2019-07-09-Meshery-start-feat-WSL2-K3d/index.mdx index 44e285808932..b58db8d08882 100644 --- a/src/collections/blog/2019/2019-07-09-Meshery-start-feat-WSL2-K3d/index.mdx +++ b/src/collections/blog/2019/2019-07-09-Meshery-start-feat-WSL2-K3d/index.mdx @@ -1,173 +1,173 @@ ---- -title: "Getting started with Meshery, WSL2 and k3d" -subtitle: "" -date: 2019-07-09 12:00:00 +0000 -author: Nuno do Carmo -thumbnail: ./cnab-logo.webp -darkthumbnail: ./cnab-logo.webp -category: Meshery -tags: - - Community - - Meshery - - mesheryctl -published: true -type: Blog -technology: Docker -product: Meshery -resource: true -redirect_from: - - /blog/2019-07-09-getting-started-with-Meshery-WSL2-k3d/ ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import wsldockerstart from "./wsl-docker-start.webp"; -import wslgrafanalogin from "./wsl-grafana-login.webp"; -import wslgrafanaloginsuccess from "./wsl-grafana-login-success.webp"; -import wslgrafanastart from "./wsl-grafana-start.webp"; -import wslk3dstart from "./wsl-k3d-start.webp"; -import wslmesherycomplete from "./wsl-meshery-complete.webp"; -import wslmesherylogin from "./wsl-meshery-login.webp"; -import wslmesheryloginsuccess from "./wsl-meshery-login-success.webp"; -import wslmesherystart from "./wsl-meshery-start.webp"; - - - -During KubeCon EU 2019, I had the chance to discover two new softwares that simply amazed me: -1. [Meshery](https://layer5.io/cloud-native-management/meshery), which is the multi-cluster Kubernetes management plane. -2. [k3d](https://github.com/rancher/k3d), which is used to create a dockerized [k3s](https://k3s.io) server. - -And, what really appealed to me about both of them is that everything from the installation to the usage was just *simple!* -And cream on the top, both softwares are used with or inside containers, making each ideal for a create/try/delete workflow. - -

Environment Setup

- -Before we start having *real* fun with Meshery, I will quickly list the different components I used for this blog post and ensure I define what could be optional for your own setup: -1. [Meshery](https://layer5.io/cloud-native-management/meshery) -2. [Docker](https://docs.docker.com/install/) - - Docker is of course mandatory and as Meshery is based on a Compose file, which means that [docker-compose](https://docs.docker.com/compose/install/) is also mandatory. -3. [k3d](https://github.com/rancher/k3d) - - k3d or any k3s/K8s cluster that you might have already configured. -4. [WSL2](https://devblogs.microsoft.com/commandline/wsl-2-is-now-available-in-windows-insiders/) - - For the (few) ones who know me, my "OS base" is WSL2, which means that without much/any change, it should run fine for any Linux/MacOS setup. -5. [Grafana](https://grafana.com/) *(optional)* - - Grafana is not mandatory however is strongly recommend. We will setup a dockerized instance, but feel free to plug Meshery with your existing instance. - -

Nothing is taken for granted

- -For the sake of making the blog post around Meshery, I won't explain how to install each component and will focus only on getting k3d and Meshery working. - -That said, I do not take anything for granted and as Scott Hanselman once taught me: there is no "just have to ..." or "by simply doing ...". - -If you face any issue with your setup (hopefully WSL2), just let me know on [Twitter](https://twitter.com/nunixtech) or on the [Layer5 Slack channel](http://slack.layer5.io). - -

Meshery Installation

- -For the following steps, I will use the Ubuntu 18.04 WSL2 distro: - -- Start docker and confirm it's running: - -```bash -sudo service docker start -docker version -``` - -- Using Docker, install Meshery on your local machine by running the following: - -```bash -curl -L https://meshery.io/install | PLATFORM=kubernetes bash - -``` - - wsl-docker-start - - -- Create a new k3d cluster with the WSL2 IP - -```bash -export mainIP=`hostname -I | awk '{ print $1 }'` -k3d list -k3d create --workers 3 --api-port ${mainIP}:6443 -export KUBECONFIG="$(k3d get-kubeconfig --name='k3s-default')" -kubectl cluster-info -``` - - - wslk3dstart - -
-- Start Meshery on the newly created cluster - -```bash -mesheryctl system start -``` - - - wslmesherystart - -- Once Meshery is fully started, login in your preferred browser using the WSL2 IP instead of localhost - -```bash -export BROWSER=/mnt/c/Firefox/firefox.exe -$BROWSER $mainIP:9081 & -``` - - - wslmesherylogin - - - wslmesheryloginsuccess - - - -#### [Optional] More analytics with Grafana -As stated above, Meshery can leverage the analytics provided by Grafana. For this blog post, as everything is built from scratch. Here is the setup for a new Grafana dockerized instance. - -Start a new Grafana on docker instance - -```bash -docker run \ --d \ --p 3000:3000 \ ---name=grafana \ --e "GF_SERVER_ROOT_URL=http://$mainIP" \ --e "GF_SECURITY_ADMIN_PASSWORD=MesheryInstance" \ -grafana/grafana -``` - - - wslgrafanastart - - -- Access the new instance with the admin password that you set in the docker environment variable -```bash -$BROWSER $mainIP:3000 & -``` - - - wslgrafanalogin - -
- - wslgrafanaloginsuccess - - -### An inside look -While everything should run fine, it's always good to have a look at what has been deployed. - -In this case, we are almost exclusively working with Docker and the "inside look" should look something like this: - - - wslmesherycomplete - - -#### Conclusion -As [Lee Calcote](https://twitter.com/lcalcote) put it, this is a lot of buzz words: Meshery > k3s (deployed via k3d) > Docker > WSL2 > Windows 10. And he's totally right, still the "beauty" here, is that it "simply works". - -Since the begin of the Docker era, new tooling has appeard for simplifying complex workflows. -Even Kubernetes (K8s) as a much lighter version with k3s by Rancher. - -And of course, Meshery which integrates and simplifies the installation and benchmarking of different Kubernetes configurations. Hope you had fun assembling all these pieces and stay tunned for the "Bonuses", more fun to come! - - > > > Nunix out - - -
+--- +title: "Getting started with Meshery, WSL2 and k3d" +subtitle: "" +date: 2019-07-09 12:00:00 +0000 +author: Nuno do Carmo +thumbnail: ./cnab-logo.webp +darkthumbnail: ./cnab-logo.webp +category: Meshery +tags: + - Community + - Meshery + - mesheryctl +published: true +type: Blog +technology: Docker +product: Meshery +resource: true +redirect_from: + - /blog/2019-07-09-getting-started-with-Meshery-WSL2-k3d/ +--- + + +import wsldockerstart from "./wsl-docker-start.webp"; +import wslgrafanalogin from "./wsl-grafana-login.webp"; +import wslgrafanaloginsuccess from "./wsl-grafana-login-success.webp"; +import wslgrafanastart from "./wsl-grafana-start.webp"; +import wslk3dstart from "./wsl-k3d-start.webp"; +import wslmesherycomplete from "./wsl-meshery-complete.webp"; +import wslmesherylogin from "./wsl-meshery-login.webp"; +import wslmesheryloginsuccess from "./wsl-meshery-login-success.webp"; +import wslmesherystart from "./wsl-meshery-start.webp"; + + + +During KubeCon EU 2019, I had the chance to discover two new softwares that simply amazed me: +1. [Meshery](https://layer5.io/cloud-native-management/meshery), which is the multi-cluster Kubernetes management plane. +2. [k3d](https://github.com/rancher/k3d), which is used to create a dockerized [k3s](https://k3s.io) server. + +And, what really appealed to me about both of them is that everything from the installation to the usage was just *simple!* +And cream on the top, both softwares are used with or inside containers, making each ideal for a create/try/delete workflow. + +

Environment Setup

+ +Before we start having *real* fun with Meshery, I will quickly list the different components I used for this blog post and ensure I define what could be optional for your own setup: +1. [Meshery](https://layer5.io/cloud-native-management/meshery) +2. [Docker](https://docs.docker.com/install/) + - Docker is of course mandatory and as Meshery is based on a Compose file, which means that [docker-compose](https://docs.docker.com/compose/install/) is also mandatory. +3. [k3d](https://github.com/rancher/k3d) + - k3d or any k3s/K8s cluster that you might have already configured. +4. [WSL2](https://devblogs.microsoft.com/commandline/wsl-2-is-now-available-in-windows-insiders/) + - For the (few) ones who know me, my "OS base" is WSL2, which means that without much/any change, it should run fine for any Linux/MacOS setup. +5. [Grafana](https://grafana.com/) *(optional)* + - Grafana is not mandatory however is strongly recommend. We will setup a dockerized instance, but feel free to plug Meshery with your existing instance. + +

Nothing is taken for granted

+ +For the sake of making the blog post around Meshery, I won't explain how to install each component and will focus only on getting k3d and Meshery working. + +That said, I do not take anything for granted and as Scott Hanselman once taught me: there is no "just have to ..." or "by simply doing ...". + +If you face any issue with your setup (hopefully WSL2), just let me know on [Twitter](https://twitter.com/nunixtech) or on the [Layer5 Slack channel](http://slack.layer5.io). + +

Meshery Installation

+ +For the following steps, I will use the Ubuntu 18.04 WSL2 distro: + +- Start docker and confirm it's running: + +```bash +sudo service docker start +docker version +``` + +- Using Docker, install Meshery on your local machine by running the following: + +```bash +curl -L https://meshery.io/install | PLATFORM=kubernetes bash - +``` + + wsl-docker-start + + +- Create a new k3d cluster with the WSL2 IP + +```bash +export mainIP=`hostname -I | awk '{ print $1 }'` +k3d list +k3d create --workers 3 --api-port ${mainIP}:6443 +export KUBECONFIG="$(k3d get-kubeconfig --name='k3s-default')" +kubectl cluster-info +``` + + + wslk3dstart + +
+- Start Meshery on the newly created cluster + +```bash +mesheryctl system start +``` + + + wslmesherystart + +- Once Meshery is fully started, login in your preferred browser using the WSL2 IP instead of localhost + +```bash +export BROWSER=/mnt/c/Firefox/firefox.exe +$BROWSER $mainIP:9081 & +``` + + + wslmesherylogin + + + wslmesheryloginsuccess + + + +#### [Optional] More analytics with Grafana +As stated above, Meshery can leverage the analytics provided by Grafana. For this blog post, as everything is built from scratch. Here is the setup for a new Grafana dockerized instance. + +Start a new Grafana on docker instance + +```bash +docker run \ +-d \ +-p 3000:3000 \ +--name=grafana \ +-e "GF_SERVER_ROOT_URL=http://$mainIP" \ +-e "GF_SECURITY_ADMIN_PASSWORD=MesheryInstance" \ +grafana/grafana +``` + + + wslgrafanastart + + +- Access the new instance with the admin password that you set in the docker environment variable +```bash +$BROWSER $mainIP:3000 & +``` + + + wslgrafanalogin + +
+ + wslgrafanaloginsuccess + + +### An inside look +While everything should run fine, it's always good to have a look at what has been deployed. + +In this case, we are almost exclusively working with Docker and the "inside look" should look something like this: + + + wslmesherycomplete + + +#### Conclusion +As [Lee Calcote](https://twitter.com/lcalcote) put it, this is a lot of buzz words: Meshery > k3s (deployed via k3d) > Docker > WSL2 > Windows 10. And he's totally right, still the "beauty" here, is that it "simply works". + +Since the begin of the Docker era, new tooling has appeard for simplifying complex workflows. +Even Kubernetes (K8s) as a much lighter version with k3s by Rancher. + +And of course, Meshery which integrates and simplifies the installation and benchmarking of different Kubernetes configurations. Hope you had fun assembling all these pieces and stay tunned for the "Bonuses", more fun to come! + + > > > Nunix out + + +
diff --git a/src/collections/blog/2019/2019-10-02-hacktoberfest-2019-documenting-my-first-ever-hacktoberfest-contribution/index.mdx b/src/collections/blog/2019/2019-10-02-hacktoberfest-2019-documenting-my-first-ever-hacktoberfest-contribution/index.mdx index d2e1daede8b8..8c05659fd44e 100644 --- a/src/collections/blog/2019/2019-10-02-hacktoberfest-2019-documenting-my-first-ever-hacktoberfest-contribution/index.mdx +++ b/src/collections/blog/2019/2019-10-02-hacktoberfest-2019-documenting-my-first-ever-hacktoberfest-contribution/index.mdx @@ -1,141 +1,141 @@ ---- -title: "Hacktoberfest 2019: documenting my first-ever Hacktoberfest contribution" -date: 2019-10-02 18:19:00 +0000 -author: Rafi Ungar -thumbnail: ./hacktoberfest.webp -darkthumbnail: ./hacktoberfest.webp -category: Internship Programs -tags: - - Landscape - - Community -published: true -redirect_from: - - /blog/hacktoberfest-2019-documenting-my-first-ever-hacktoberfest-contribution/ - - /blog/landscape/hacktoberfest-2019-documenting-my-first-ever-hacktoberfest-contribution/ - - /blog/landscape/hacktoberfest-2019-documenting-my-first-ever-hacktoberfest-contribution ---- - -import { BlogWrapper } from "../../Blog.style.js"; - - - - -In [my last post](https://raungar.wordpress.com/2019/09/27/planning-for-hacktoberfest-2019/), I identified three GitHub issues to kick off my participation in Hacktoberfest 2019. Today, I am happy to showcase my resolution of one of those issues, marking my first-ever Hacktoberfest contribution! - -* * * - -#### [Layer5.io](https://github.com/layer5io/layer5) - -Before I continue on, I want to acknowledge the project that I have contributed to. In [an article](/programs/gsod) discussing their participating in the Google Summer of Code 2019 program, [**Layer5**](https://github.com/layer5io/layer5)'s open source community is described cloud native tools for devops engineers. My project was on [service mesh](/resources/service-mesh/service-mesh-fundamentals) helpfully defines a service mesh as "a dedicated infrastructure layer" of an application that controls how different parts of that application ("services") share data with one another (i.e. 'mesh together'). - -* * * - -### Selecting my first Hacktoberfest issue - -As I mentioned my last post, I came into contact with Layer5 after discovering (through the [Hacktoberfest Issue Finder](https://hacktoberfest-finder.netlify.com/)) its [issue regarding table filtering](https://github.com/layer5io/layer5/issues/65)—and subsequently discovered an unreported styling issue. [![A styling issue with a collection of lists hosted on Layer5's Landscape page.](https://user-images.githubusercontent.com/13500769/66007380-2d643700-e480-11e9-8bda-e81dd0e166d9.webp)](https://user-images.githubusercontent.com/13500769/66007380-2d643700-e480-11e9-8bda-e81dd0e166d9.webp) - -A styling issue affected a collection of lists hosted on Layer5's [Landscape page](https://layer5.io/landscape). - -Of the three GitHub issues I've scoped out, the resolution of this styling issue (i.e. tweaking CSS) represents the simplest of tasks that I have lined up—and an ideal candidate for a first-time Hacktoberfest contribution! - -As far as I could tell, no open issues concerned the styling problem that I discovered. So, as instructed both Layer5's website (and encouraged its extremely-welcoming development team), I opened _my own issue_ - [Enhance landscape categories section wrapping (#191)](https://github.com/layer5io/layer5/issues/191). - -[![https://github.com/layer5io/layer5/issues/191](https://raungar.files.wordpress.com/2019/10/image-1.webp?w=1024)](https://raungar.files.wordpress.com/2019/10/image-1.webp?w=1024) - -### Identifying a solution - -To address this issue, I came up with the idea of realigning the category list items horizontally, transforming the poorly-behaving columns of category 'cards' into rows in a responsive and easily-scalable vertical stack. - -Implementating this idea proved quite simple, requiring only [a few added CSS rules](https://github.com/layer5io/layer5/issues/191#issuecomment-537304508), which I first accomplished by tinkering with the live webpage's styling (with the help of the [Stylish](https://addons.mozilla.org/en-US/firefox/addon/stylish/) browser extension): - - -```css -.card .card-content li { - float: right; - width: 200px; -} -.card .card-content { - border-right: unset; - padding: 0 0 5px 0; -} -.card .card-content:not(:last-child) { - border-bottom-width: 1px; - border-bottom-style: dashed; - border-bottom-color: var(--main-dark-grey); -} -``` - -The vertical stack is implemented by the rules in the first selector: list items are floated right and assigned a fixed width, which aligns them neatly. The dashed borders and padding used to separate category lists was also adjusted to accomodate the new design (pictured below): - -[![https://github.com/layer5io/layer5/issues/191#issuecomment-537304508](https://user-images.githubusercontent.com/13500769/66013483-5e049a80-e499-11e9-8920-52c3da81ece7.webp)](https://user-images.githubusercontent.com/13500769/66013483-5e049a80-e499-11e9-8920-52c3da81ece7.webp) - -The above image is one of the [two mockups of the redesign](https://github.com/layer5io/layer5/issues/191#issuecomment-537304508) that I produced for the consideration of the project's developers. As luck would have it, Layer5 project lead [Lee Calcote](https://github.com/leecalcote) provided [a lightning-quick response](https://github.com/layer5io/layer5/issues/191#issuecomment-537310179), welcoming a pull request to it! - -[![https://github.com/layer5io/layer5/issues/191#issuecomment-537310179](https://raungar.files.wordpress.com/2019/10/image-2.webp?w=1024)](https://raungar.files.wordpress.com/2019/10/image-2.webp?w=1024) - -#### Future research area: Materialize CSS - -I discovered that the 'cards' comprising the category section are styled using [Materialize CSS](https://materializecss.com/). I considered using this framework in my solution, but ultimately decided to opt for a simple, intuitive solution. This framework appears interesting, and would definitely merits research were this a more-involved styling task. - -## Implementing the solution - -While using my browser's developer tools to tinker with styling, I discovered an inline `style` tag that serviced the categories section. I determined that this tag would present the best place to add the styling rules that I wrote (following the coding style of a prior contributor). - -Finding the location of this `style` tag (i.e. of the "Service Mesh Landscape" page) in the source code was a lot more trouble than I thought it would be. After paging through too many HTML documents, I gave in and used Visual Studio's global search functionality to locate it. - -## Testing the solution - -Although I knew that my styling worked well when loaded from a browser extension, before I could contribute code, I needed to ensure that the styling worked equally-well when loaded inline from an HTML document. Little did I know, at that time, what I would be getting myself into... - -#### Ruby, Gems and Jekyll? `rvm`, `bundle` and `make`? - -Picking through my ~/.bash\_history file, here is the sequence of Bash shell commands that I issued (via WSL Ubuntu) in order to execute a local copy of the layer5 website (annotated for your convenience): -```sh -## Install dependency packages ## -sudo apt-get install build-essential -sudo apt-get install software-properties-common - -## Install specific version of Ruby via Ruby Version Manager ## -sudo apt-add-repository -y ppa:rael-gc/rvm -sudo apt-get update -sudo apt-get install rvm -rvm install "ruby-2.6.3" # install specific version of Ruby specified in Layer5's Gemfile - # (Yes, it must be that exact version.) - -## Configure RubyGems ## -echo 'export GEM\_HOME="$HOME/gems"' >> ~/.bashrc -echo 'export PATH="$HOME/gems/bin:$PATH"' >> ~/.bashrc -source ~/.bashrc - -## Install Jekyll and dependencies ## -gem install jekyll bundler -bundle install # install dependencies listed in Gemfile - -## Execute project! ## -make site # references Layer5's Makefile - # alias for "bundle exec jekyll serve --drafts --livereload" -``` -#### Stray thoughts on documentation - -Reflecting back on the process, a question has stuck with me: how much should projects hold the hands of novice contributors? Setting up the means to run `make site` is not included within Layer5's [CONTRIBUTING.md file](https://github.com/layer5io/layer5/blob/master/CONTRIBUTING.md). As such, for the most novice of contributors, like myself (who have never even heard of `make` before), setting up the prerequisite development environment presented a lengthy and piecemeal (albeit ultimately valuable) learning experience. - -How much documentation is too little? Too much? How high should the bar be set for contribution? I suppose it is up to the project's community to decide upon the answers to these questions themselves (and write documentation, accordingly). - -## Creating a pull request - -After successfully testing and fixing the styling on my local fork, I created [a pull request](https://github.com/layer5io/layer5/pull/192): - -[![https://github.com/layer5io/layer5/pull/192](https://raungar.files.wordpress.com/2019/10/image-3.webp?w=1024)](https://raungar.files.wordpress.com/2019/10/image-3.webp?w=1024) - -Pull request – [Restyle landscape categories (#192)](https://github.com/layer5io/layer5/pull/192) - -...and it got merged! First Hacktoberfest contribution, completed! - -## Up next! - -I ended [my last post](https://raungar.wordpress.com/2019/09/27/planning-for-hacktoberfest-2019/) by stating that I have yet to gain any experience with makefiles. Well, thanks to my work on Layer5, that is no longer true: I have since used a makefile (to launch a Jekyll executable)! This experience will undoubtedly save me some time with resolving [the Comcast issue I found](https://github.com/Comcast/RestfulHttpsProxy/issues/5)! However, the next Hacktoberfest issue I resolve will be [_the first one I blogged about_](https://github.com/layer5io/layer5/issues/65). - -Stay tuned! - - - +--- +title: "Hacktoberfest 2019: documenting my first-ever Hacktoberfest contribution" +date: 2019-10-02 18:19:00 +0000 +author: Rafi Ungar +thumbnail: ./hacktoberfest.webp +darkthumbnail: ./hacktoberfest.webp +category: Internship Programs +tags: + - Landscape + - Community +published: true +redirect_from: + - /blog/hacktoberfest-2019-documenting-my-first-ever-hacktoberfest-contribution/ + - /blog/landscape/hacktoberfest-2019-documenting-my-first-ever-hacktoberfest-contribution/ + - /blog/landscape/hacktoberfest-2019-documenting-my-first-ever-hacktoberfest-contribution +--- + + + + + + +In [my last post](https://raungar.wordpress.com/2019/09/27/planning-for-hacktoberfest-2019/), I identified three GitHub issues to kick off my participation in Hacktoberfest 2019. Today, I am happy to showcase my resolution of one of those issues, marking my first-ever Hacktoberfest contribution! + +* * * + +#### [Layer5.io](https://github.com/layer5io/layer5) + +Before I continue on, I want to acknowledge the project that I have contributed to. In [an article](/programs/gsod) discussing their participating in the Google Summer of Code 2019 program, [**Layer5**](https://github.com/layer5io/layer5)'s open source community is described cloud native tools for devops engineers. My project was on [service mesh](/resources/service-mesh/service-mesh-fundamentals) helpfully defines a service mesh as "a dedicated infrastructure layer" of an application that controls how different parts of that application ("services") share data with one another (i.e. 'mesh together'). + +* * * + +### Selecting my first Hacktoberfest issue + +As I mentioned my last post, I came into contact with Layer5 after discovering (through the [Hacktoberfest Issue Finder](https://hacktoberfest-finder.netlify.com/)) its [issue regarding table filtering](https://github.com/layer5io/layer5/issues/65)—and subsequently discovered an unreported styling issue. [![A styling issue with a collection of lists hosted on Layer5's Landscape page.](https://user-images.githubusercontent.com/13500769/66007380-2d643700-e480-11e9-8bda-e81dd0e166d9.webp)](https://user-images.githubusercontent.com/13500769/66007380-2d643700-e480-11e9-8bda-e81dd0e166d9.webp) + +A styling issue affected a collection of lists hosted on Layer5's [Landscape page](https://layer5.io/landscape). + +Of the three GitHub issues I've scoped out, the resolution of this styling issue (i.e. tweaking CSS) represents the simplest of tasks that I have lined up—and an ideal candidate for a first-time Hacktoberfest contribution! + +As far as I could tell, no open issues concerned the styling problem that I discovered. So, as instructed both Layer5's website (and encouraged its extremely-welcoming development team), I opened _my own issue_ - [Enhance landscape categories section wrapping (#191)](https://github.com/layer5io/layer5/issues/191). + +[![https://github.com/layer5io/layer5/issues/191](https://raungar.files.wordpress.com/2019/10/image-1.webp?w=1024)](https://raungar.files.wordpress.com/2019/10/image-1.webp?w=1024) + +### Identifying a solution + +To address this issue, I came up with the idea of realigning the category list items horizontally, transforming the poorly-behaving columns of category 'cards' into rows in a responsive and easily-scalable vertical stack. + +Implementating this idea proved quite simple, requiring only [a few added CSS rules](https://github.com/layer5io/layer5/issues/191#issuecomment-537304508), which I first accomplished by tinkering with the live webpage's styling (with the help of the [Stylish](https://addons.mozilla.org/en-US/firefox/addon/stylish/) browser extension): + + +```css +.card .card-content li { + float: right; + width: 200px; +} +.card .card-content { + border-right: unset; + padding: 0 0 5px 0; +} +.card .card-content:not(:last-child) { + border-bottom-width: 1px; + border-bottom-style: dashed; + border-bottom-color: var(--main-dark-grey); +} +``` + +The vertical stack is implemented by the rules in the first selector: list items are floated right and assigned a fixed width, which aligns them neatly. The dashed borders and padding used to separate category lists was also adjusted to accomodate the new design (pictured below): + +[![https://github.com/layer5io/layer5/issues/191#issuecomment-537304508](https://user-images.githubusercontent.com/13500769/66013483-5e049a80-e499-11e9-8920-52c3da81ece7.webp)](https://user-images.githubusercontent.com/13500769/66013483-5e049a80-e499-11e9-8920-52c3da81ece7.webp) + +The above image is one of the [two mockups of the redesign](https://github.com/layer5io/layer5/issues/191#issuecomment-537304508) that I produced for the consideration of the project's developers. As luck would have it, Layer5 project lead [Lee Calcote](https://github.com/leecalcote) provided [a lightning-quick response](https://github.com/layer5io/layer5/issues/191#issuecomment-537310179), welcoming a pull request to it! + +[![https://github.com/layer5io/layer5/issues/191#issuecomment-537310179](https://raungar.files.wordpress.com/2019/10/image-2.webp?w=1024)](https://raungar.files.wordpress.com/2019/10/image-2.webp?w=1024) + +#### Future research area: Materialize CSS + +I discovered that the 'cards' comprising the category section are styled using [Materialize CSS](https://materializecss.com/). I considered using this framework in my solution, but ultimately decided to opt for a simple, intuitive solution. This framework appears interesting, and would definitely merits research were this a more-involved styling task. + +## Implementing the solution + +While using my browser's developer tools to tinker with styling, I discovered an inline `style` tag that serviced the categories section. I determined that this tag would present the best place to add the styling rules that I wrote (following the coding style of a prior contributor). + +Finding the location of this `style` tag (i.e. of the "Service Mesh Landscape" page) in the source code was a lot more trouble than I thought it would be. After paging through too many HTML documents, I gave in and used Visual Studio's global search functionality to locate it. + +## Testing the solution + +Although I knew that my styling worked well when loaded from a browser extension, before I could contribute code, I needed to ensure that the styling worked equally-well when loaded inline from an HTML document. Little did I know, at that time, what I would be getting myself into... + +#### Ruby, Gems and Jekyll? `rvm`, `bundle` and `make`? + +Picking through my ~/.bash\_history file, here is the sequence of Bash shell commands that I issued (via WSL Ubuntu) in order to execute a local copy of the layer5 website (annotated for your convenience): +```sh +## Install dependency packages ## +sudo apt-get install build-essential +sudo apt-get install software-properties-common + +## Install specific version of Ruby via Ruby Version Manager ## +sudo apt-add-repository -y ppa:rael-gc/rvm +sudo apt-get update +sudo apt-get install rvm +rvm install "ruby-2.6.3" # install specific version of Ruby specified in Layer5's Gemfile + # (Yes, it must be that exact version.) + +## Configure RubyGems ## +echo 'export GEM\_HOME="$HOME/gems"' >> ~/.bashrc +echo 'export PATH="$HOME/gems/bin:$PATH"' >> ~/.bashrc +source ~/.bashrc + +## Install Jekyll and dependencies ## +gem install jekyll bundler +bundle install # install dependencies listed in Gemfile + +## Execute project! ## +make site # references Layer5's Makefile + # alias for "bundle exec jekyll serve --drafts --livereload" +``` +#### Stray thoughts on documentation + +Reflecting back on the process, a question has stuck with me: how much should projects hold the hands of novice contributors? Setting up the means to run `make site` is not included within Layer5's [CONTRIBUTING.md file](https://github.com/layer5io/layer5/blob/master/CONTRIBUTING.md). As such, for the most novice of contributors, like myself (who have never even heard of `make` before), setting up the prerequisite development environment presented a lengthy and piecemeal (albeit ultimately valuable) learning experience. + +How much documentation is too little? Too much? How high should the bar be set for contribution? I suppose it is up to the project's community to decide upon the answers to these questions themselves (and write documentation, accordingly). + +## Creating a pull request + +After successfully testing and fixing the styling on my local fork, I created [a pull request](https://github.com/layer5io/layer5/pull/192): + +[![https://github.com/layer5io/layer5/pull/192](https://raungar.files.wordpress.com/2019/10/image-3.webp?w=1024)](https://raungar.files.wordpress.com/2019/10/image-3.webp?w=1024) + +Pull request – [Restyle landscape categories (#192)](https://github.com/layer5io/layer5/pull/192) + +...and it got merged! First Hacktoberfest contribution, completed! + +## Up next! + +I ended [my last post](https://raungar.wordpress.com/2019/09/27/planning-for-hacktoberfest-2019/) by stating that I have yet to gain any experience with makefiles. Well, thanks to my work on Layer5, that is no longer true: I have since used a makefile (to launch a Jekyll executable)! This experience will undoubtedly save me some time with resolving [the Comcast issue I found](https://github.com/Comcast/RestfulHttpsProxy/issues/5)! However, the next Hacktoberfest issue I resolve will be [_the first one I blogged about_](https://github.com/layer5io/layer5/issues/65). + +Stay tuned! + + + diff --git a/src/collections/blog/2019/2019-10-12-hacktoberfest-2019-is-heating-up/index.mdx b/src/collections/blog/2019/2019-10-12-hacktoberfest-2019-is-heating-up/index.mdx index 486778931892..e67be4011cf0 100644 --- a/src/collections/blog/2019/2019-10-12-hacktoberfest-2019-is-heating-up/index.mdx +++ b/src/collections/blog/2019/2019-10-12-hacktoberfest-2019-is-heating-up/index.mdx @@ -1,92 +1,89 @@ ---- -title: "Hacktoberfest 2019: Heating up!" -date: 2019-10-12 21:58:00 +0000 -author: Rafi Ungar -thumbnail: ./hacktoberfestw2.webp -darkthumbnail: ./hacktoberfestw2.webp -category: Internship Programs -tags: - - Community - - Landscape -published: true -redirect_from: - - /blog/hacktoberfest-2019-heating-up/ ---- - -import { BlogWrapper } from "../../Blog.style.js"; - - - - -(ICYMI: [I've made my first-ever Hacktoberfest contribution](https://raungar.wordpress.com/2019/10/02/hacktoberfest-2019-documenting-my-first-ever-hacktoberfest-contribution/)!)_ - -[Hacktoberfest 2019](https://hacktoberfest.digitalocean.com/) is now well underway, and I am happy to report that I have made my second contribution to my new favorite open source community, [**Layer5**](https://layer5.io/) ([on GitHub](https://github.com/layer5io))! - -_Before I continue on, I want to extend a huge thank-you to Layer5's lead developer, Lee Calcote, as well as the Layer5 community managers for welcoming me into the Layer5 Slack channel, allowing me to introduce myself in their weekly community meeting, and even giving my blog [an awesome shout out on Twitter](https://twitter.com/layer5/status/1180317604168306688?s=12)!_ - -* * * - -This week, I helped resolve the very first issue that I outlined in my [Planning for #Hacktoberfest 2019](https://raungar.wordpress.com/2019/09/27/planning-for-hacktoberfest-2019/) post: - -[![](https://raungar.files.wordpress.com/2019/10/image-4.webp?w=1024)](https://raungar.files.wordpress.com/2019/10/image-4.webp?w=1024) - -Issue [layerio#65](https://github.com/layer5io/layer5/issues/65): enhancements for the [Layer5 Landscape page](https://layer5.io/landscape) - -At the time I found this issue, the second requested enhancement (concerning table row coloration) [was already handled](https://github.com/layer5io/layer5/commit/b313268cb578e762d1212c9910b522af2869b57b) by another contributor, leaving me with two tasks: - -1. Implementing the specified sorting functionalities (for the three tables on the [Landscape page](https://layer5.io/landscape)) -2. Restyling the font color of site hyperlinks (an enhancement [requested later on](https://github.com/layer5io/layer5/issues/65#issuecomment-483912458) in the issue) - -### The strange case of Jekyll - -Fortunately, thanks to my previous work with Layer5's website, I was already all set up with an offline development environment. However, going into my first task, I knew very little about Jekyll except how to install it. - -_[Jekyll](https://jekyllrb.com/) and [Liquid](https://shopify.github.io/liquid/)... it's got to be like React or Angular, right? I mean, all I need to do is slap in [sort](https://shopify.github.io/liquid/filters/sort/) and [reverse filters](https://shopify.github.io/liquid/filters/reverse/) and toggle them onclick, right_...? - -_...Wait, what's a "static site generator"?_ - -* * * - -After discovering what Jekyll and Liquid actually were, I determined that I would have to resort to DOM manipulation to fully accomplish my first task. However, I did succeed in accomplishing the default sorting behaviour by enhancing the Liquid tags being used by several tables. - -To do so, I followed coding style on the issue's previous contributor by encapsulating my work within a new JavaScript file in the project's assets folder: a simple bubble sort function. - -I chose to implement the [simplest of sorting algorithms](https://github.com/layer5io/layer5/blob/master/assets/js/table-sort.js#L13) in JavaScript (which I count as study for my _Data Structures and Algorithms_ midterm): - - -```js -// Excerpted from https://github.com/layer5io/layer5/blob/master/assets/js/table-sort.js -let bubbleSort = () => { - for (i = 0; i < rows.length-1; i++) { - for (j = 0; j < rows.length-i-1; j++) { - if (shouldSwap(text(j), text(j+1))) { - rows[j].parentNode.insertBefore(rows[j+1], rows[j]); - didSort = true; - } - } - } -}; -``` - -### Painting over Pumpkin Bread - -[Encycolorpedia.com](https://encycolorpedia.com) lists the hex color code `#fdac40` as "[Valspar Paint Pumpkin Bread](https://encycolorpedia.com/fdac40)". Although Layer5.io's then-difficult-to-read hyperlinks were colored `#ffa_b_40`, I'd still like to think that the second task of my second Hacktoberfest contribution was festively-themed! - -In [my last blog post](https://raungar.wordpress.com/2019/10/02/hacktoberfest-2019-documenting-my-first-ever-hacktoberfest-contribution/), I mentioned that [Materialize CSS](https://materializecss.com) was worth further research. Well, after some poking around, I discovered that all of Layer5.io's pumpkin-colored hyperlink styling (both deliberate, and incidental) originated from its materialize.css asset. - -Although this asset has been [frequently modified](https://github.com/layer5io/layer5/commits/master/assets/css/materialize.css), I was still hesitant to globally alter the site's styling (in case a return to Pumpkin Bread was desired in the future), so I instead opted to [add a new inline style tag](https://github.com/layer5io/layer5/pull/209/files#diff-48443fc170100677376b7ee11324494b) to override [a styling rule](https://github.com/layer5io/layer5/blob/master/assets/css/materialize.css#L5149) (on top of removing the 'orange-text' class from individual anchor elements). - -* * * - -All of the changes I've made can be viewed through [my (merged) pull request](https://github.com/layer5io/layer5/pull/209): - -[![](https://raungar.files.wordpress.com/2019/10/image-6.webp?w=1024)](https://raungar.files.wordpress.com/2019/10/image-6.webp?w=1024) - -Pull request [layer5io#209](https://github.com/layer5io/layer5/pull/209): resolved the remainder of issue [layerio#65](https://github.com/layer5io/layer5/issues/65) - -* * * - -I am very fortunate to be so well-supported by the open source communities I have worked with so far, both on-campus and abroad. With their support behind me, I feel equipped to start learning what I need to know to resolve the next two more-difficult issues that lie ahead of me! - - - +--- +title: "Hacktoberfest 2019: Heating up!" +date: 2019-10-12 21:58:00 +0000 +author: Rafi Ungar +thumbnail: ./hacktoberfestw2.webp +darkthumbnail: ./hacktoberfestw2.webp +category: Internship Programs +tags: + - Community + - Landscape +published: true +redirect_from: + - /blog/hacktoberfest-2019-heating-up/ +--- + + + +(ICYMI: [I've made my first-ever Hacktoberfest contribution](https://raungar.wordpress.com/2019/10/02/hacktoberfest-2019-documenting-my-first-ever-hacktoberfest-contribution/)!)_ + +[Hacktoberfest 2019](https://hacktoberfest.digitalocean.com/) is now well underway, and I am happy to report that I have made my second contribution to my new favorite open source community, [**Layer5**](https://layer5.io/) ([on GitHub](https://github.com/layer5io))! + +_Before I continue on, I want to extend a huge thank-you to Layer5's lead developer, Lee Calcote, as well as the Layer5 community managers for welcoming me into the Layer5 Slack channel, allowing me to introduce myself in their weekly community meeting, and even giving my blog [an awesome shout out on Twitter](https://twitter.com/layer5/status/1180317604168306688?s=12)!_ + +* * * + +This week, I helped resolve the very first issue that I outlined in my [Planning for #Hacktoberfest 2019](https://raungar.wordpress.com/2019/09/27/planning-for-hacktoberfest-2019/) post: + +[![](https://raungar.files.wordpress.com/2019/10/image-4.webp?w=1024)](https://raungar.files.wordpress.com/2019/10/image-4.webp?w=1024) + +Issue [layerio#65](https://github.com/layer5io/layer5/issues/65): enhancements for the [Layer5 Landscape page](https://layer5.io/landscape) + +At the time I found this issue, the second requested enhancement (concerning table row coloration) [was already handled](https://github.com/layer5io/layer5/commit/b313268cb578e762d1212c9910b522af2869b57b) by another contributor, leaving me with two tasks: + +1. Implementing the specified sorting functionalities (for the three tables on the [Landscape page](https://layer5.io/landscape)) +2. Restyling the font color of site hyperlinks (an enhancement [requested later on](https://github.com/layer5io/layer5/issues/65#issuecomment-483912458) in the issue) + +### The strange case of Jekyll + +Fortunately, thanks to my previous work with Layer5's website, I was already all set up with an offline development environment. However, going into my first task, I knew very little about Jekyll except how to install it. + +_[Jekyll](https://jekyllrb.com/) and [Liquid](https://shopify.github.io/liquid/)... it's got to be like React or Angular, right? I mean, all I need to do is slap in [sort](https://shopify.github.io/liquid/filters/sort/) and [reverse filters](https://shopify.github.io/liquid/filters/reverse/) and toggle them onclick, right_...? + +_...Wait, what's a "static site generator"?_ + +* * * + +After discovering what Jekyll and Liquid actually were, I determined that I would have to resort to DOM manipulation to fully accomplish my first task. However, I did succeed in accomplishing the default sorting behaviour by enhancing the Liquid tags being used by several tables. + +To do so, I followed coding style on the issue's previous contributor by encapsulating my work within a new JavaScript file in the project's assets folder: a simple bubble sort function. + +I chose to implement the [simplest of sorting algorithms](https://github.com/layer5io/layer5/blob/master/assets/js/table-sort.js#L13) in JavaScript (which I count as study for my _Data Structures and Algorithms_ midterm): + + +``` +// Excerpted from https://github.com/layer5io/layer5/blob/master/assets/js/table-sort.js +let bubbleSort = () => { + for (i = 0; i < rows.length-1; i++) { + for (j = 0; j < rows.length-i-1; j++) { + if (shouldSwap(text(j), text(j+1))) { + rows[j].parentNode.insertBefore(rows[j+1], rows[j]); + didSort = true; + } + } + } +}; +``` + +### Painting over Pumpkin Bread + +[Encycolorpedia.com](https://encycolorpedia.com) lists the hex color code `#fdac40` as "[Valspar Paint Pumpkin Bread](https://encycolorpedia.com/fdac40)". Although Layer5.io's then-difficult-to-read hyperlinks were colored `#ffa_b_40`, I'd still like to think that the second task of my second Hacktoberfest contribution was festively-themed! + +In [my last blog post](https://raungar.wordpress.com/2019/10/02/hacktoberfest-2019-documenting-my-first-ever-hacktoberfest-contribution/), I mentioned that [Materialize CSS](https://materializecss.com) was worth further research. Well, after some poking around, I discovered that all of Layer5.io's pumpkin-colored hyperlink styling (both deliberate, and incidental) originated from its materialize.css asset. + +Although this asset has been [frequently modified](https://github.com/layer5io/layer5/commits/master/assets/css/materialize.css), I was still hesitant to globally alter the site's styling (in case a return to Pumpkin Bread was desired in the future), so I instead opted to [add a new inline style tag](https://github.com/layer5io/layer5/pull/209/files#diff-48443fc170100677376b7ee11324494b) to override [a styling rule](https://github.com/layer5io/layer5/blob/master/assets/css/materialize.css#L5149) (on top of removing the 'orange-text' class from individual anchor elements). + +* * * + +All of the changes I've made can be viewed through [my (merged) pull request](https://github.com/layer5io/layer5/pull/209): + +[![](https://raungar.files.wordpress.com/2019/10/image-6.webp?w=1024)](https://raungar.files.wordpress.com/2019/10/image-6.webp?w=1024) + +Pull request [layer5io#209](https://github.com/layer5io/layer5/pull/209): resolved the remainder of issue [layerio#65](https://github.com/layer5io/layer5/issues/65) + +* * * + +I am very fortunate to be so well-supported by the open source communities I have worked with so far, both on-campus and abroad. With their support behind me, I feel equipped to start learning what I need to know to resolve the next two more-difficult issues that lie ahead of me! + + + diff --git a/src/collections/blog/2019/2019-11-15-introducing-comparative-spectrums-to-the-layer5-landscape/index.mdx b/src/collections/blog/2019/2019-11-15-introducing-comparative-spectrums-to-the-layer5-landscape/index.mdx index 6dfea939c071..79d761dd8bb0 100644 --- a/src/collections/blog/2019/2019-11-15-introducing-comparative-spectrums-to-the-layer5-landscape/index.mdx +++ b/src/collections/blog/2019/2019-11-15-introducing-comparative-spectrums-to-the-layer5-landscape/index.mdx @@ -1,117 +1,117 @@ ---- -title: "Introducing Comparative Spectrums to the Layer5 Landscape" -subtitle: "" -date: 2019-11-15 05:43:00 +0000 -author: Rafi Ungar -thumbnail: ./landscape_green.svg -darkthumbnail: ./landscape_green.svg -category: Internship Programs -tags: - - Community - - Landscape -published: true -type: Blog -product: Service Mesh Landscape -resource: true -redirect_from: - - /blog/introducing-comparative-spectrums-to-the-layer5-landscape/ - - /blog/introducing-comparative-spectrums-to-the-layer5-landscape ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import pr211 from "./PR-211.webp"; -import pr2112 from "./PR-211-2.webp"; -import card1 from "./card1.webp"; -import card2 from "./card2.webp"; -import arrow from "./arrow.webp"; -import gtable from "./graphical-table.webp"; -import gcomp from "./graph-compare.webp"; -import image21 from "./image.webp"; -import comment from "./comment.webp"; - - - -During [Hacktoberfest 2019](https://raungar.wordpress.com/tag/layer5/), I worked on the website of [Layer5](https://layer5.io/), open source community. More specifically, my contributions concerned one specific page of that website: its [Service Mesh Landscape page](https://layer5.io/landscape). - -Shortly after making these contributions, I was graciously welcomed into the Layer5 community by its lead developer [Lee Calcote](https://twitter.com/lcalcote?lang=en), who later directly approached me to assist him in furthering his vision for the Landscape page by implementing "comparative spectrums". Wishing to focus on my remaining two Hacktoberfest contributions at the time, I suggested surveying the interest of other potential contributors for this project. As such, an informative issue was opened: - -PR 211 - -Issue [layer5#211](https://github.com/layer5io/layer5/issues/211): add comparative spectrums to the Landscape page - -A month later, I fortunately found time enough to make some major progress into this issue. - -* * * - -This issue is quite highly conceptual, much moreso than any other issue I have thus far worked on. I decided that the best way to approach this issue would be to focus on establishing a set of tools that could be used by more-knowledgeable contributors to later construct comparative spectrums—opinionated data visualizations. As such, my first step was to build a set of responsive graphical elements that resembled [those provided as examples](https://docs.google.com/presentation/d/1P6LzzG0_alAxshpdfLnix53S9WU4vjbpSCrHJQoWPqc/edit#slide=id.p6). These include: - -#### (1) _Sleek information cards:_ - - - - - - - - - -
Card or this Card
- -_(Source: [ONIF Container Networking Panel, slides 5 and 6](https://docs.google.com/presentation/d/1P6LzzG0_alAxshpdfLnix53S9WU4vjbpSCrHJQoWPqc/edit#slide=id.p6))_ - -#### (2) _Gradiented, labelable double-arrow banners:_ - -Arrow - -_(Source: [ONIF Container Networking Panel, slide 5](https://docs.google.com/presentation/d/1P6LzzG0_alAxshpdfLnix53S9WU4vjbpSCrHJQoWPqc/edit#slide=id.p6))_ - -#### (3) _Graphically-augmented tables:_ - -Table - -_(Source: [ONIF Container Networking Panel, slide 8](https://docs.google.com/presentation/d/1P6LzzG0_alAxshpdfLnix53S9WU4vjbpSCrHJQoWPqc/edit#slide=id.p12))_ - -#### (4) _Spectrum-like graphical comparisons:_ - -Comparison - -_(Source: [ONIF Container Networking Panel, slide 7](https://docs.google.com/presentation/d/1P6LzzG0_alAxshpdfLnix53S9WU4vjbpSCrHJQoWPqc/edit#slide=id.p6))_ - -* * * - -(1) Although there may exist libraries that may help construct such graphical elements, I did not want to introduce additional libraries to accomplish my work. Instead, I wanted to make good use of Layer5io's preexisting [Materialize](https://materializecss.com/) library. Fortunately, Materialize strongly supports the design of card-like structures, allowing me to more easily [implement some](https://github.com/layer5io/layer5/pull/238/files#diff-20fc098534d6aab31ad8e5c9db51bde0R10). - -(2) Unfortunately, it does not seem that Materialize supports the creation of graphical arrows, so I just ended up [styling my own](https://github.com/layer5io/layer5/pull/238/files#diff-1d5fe92e61759723c94b009b32e9e1b7R2). - -(3) These tables can be quite easily implemented and styled with or without the use of `` tags. I anticipate these will be given a proper fleshing out after the other graphical elements are further developed. - -(4) These unique spectrum graphics present the most challenging, of all the comparison tools, to implement. Snaking spectrum bar aside, I needed to develop a _responsive_ solution that (a) allowed contributors to programmatically place image thumbnails at preset horizontal positions, while (b) ensuring those thumbnails placed at the same position do not overlap with one another (and instead align vertically atop each other). - -This presented a problem to solve: I required a means to 'float' elements toward a horizontal line; to 'stack' thumbnails atop one another, without overlap, if they are given the same horizontal position. After researching quite deeply into potential solutions to this problem, I ended up stumbling across some CSS property-value pairings that I had never heard of before: [`display: grid`](https://www.w3schools.com/css/css_grid.asp) and [`grid-auto-flow: row dense`](https://www.w3schools.com/cssref/pr_grid-auto-flow.asp). Miraculously, I discovered that these could actually function as [a basis for a solution](https://github.com/layer5io/layer5/pull/238/files#diff-1d5fe92e61759723c94b009b32e9e1b7R76). - -* * * - -After styling the graphical elements, I continued the website's trend of using [Liquid](https://help.shopify.com/en/themes/liquid) tags (e.g. [`for`](https://help.shopify.com/en/themes/liquid/tags/iteration-tags#for)) and [YAML lists](https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html) to help modularize my solutions, which should aid future contributors in generalizing them. - -* * * - -I opened [a pull request](https://github.com/layer5io/layer5/pull/238) to share my work as well as invite collaboration: - -PR 211-2 - -Pull request [layer5#238](https://github.com/layer5io/layer5/pull/238): description of tooling introduced - -Image - -Pull request [layer5#238](https://github.com/layer5io/layer5/pull/238): example images of tooling introduced - -The pull request was quite well-recieved: - -Comment - -[Comment](https://github.com/layer5io/layer5/pull/238#issuecomment-554181763) by Layer5 team lead on pull request [layer5#238](https://github.com/layer5io/layer5/pull/238) - -As I mentioned in a recent Layer5 community meeting, I am very excited to continue working with Layer5; to refine and expand upon this set of new, visionary tooling for their landscape! - - - +--- +title: "Introducing Comparative Spectrums to the Layer5 Landscape" +subtitle: "" +date: 2019-11-15 05:43:00 +0000 +author: Rafi Ungar +thumbnail: ./landscape_green.svg +darkthumbnail: ./landscape_green.svg +category: Internship Programs +tags: + - Community + - Landscape +published: true +type: Blog +product: Service Mesh Landscape +resource: true +redirect_from: + - /blog/introducing-comparative-spectrums-to-the-layer5-landscape/ + - /blog/introducing-comparative-spectrums-to-the-layer5-landscape +--- + + +import pr211 from "./PR-211.webp"; +import pr2112 from "./PR-211-2.webp"; +import card1 from "./card1.webp"; +import card2 from "./card2.webp"; +import arrow from "./arrow.webp"; +import gtable from "./graphical-table.webp"; +import gcomp from "./graph-compare.webp"; +import image21 from "./image.webp"; +import comment from "./comment.webp"; + + + +During [Hacktoberfest 2019](https://raungar.wordpress.com/tag/layer5/), I worked on the website of [Layer5](https://layer5.io/), open source community. More specifically, my contributions concerned one specific page of that website: its [Service Mesh Landscape page](https://layer5.io/landscape). + +Shortly after making these contributions, I was graciously welcomed into the Layer5 community by its lead developer [Lee Calcote](https://twitter.com/lcalcote?lang=en), who later directly approached me to assist him in furthering his vision for the Landscape page by implementing "comparative spectrums". Wishing to focus on my remaining two Hacktoberfest contributions at the time, I suggested surveying the interest of other potential contributors for this project. As such, an informative issue was opened: + +PR 211 + +Issue [layer5#211](https://github.com/layer5io/layer5/issues/211): add comparative spectrums to the Landscape page + +A month later, I fortunately found time enough to make some major progress into this issue. + +* * * + +This issue is quite highly conceptual, much moreso than any other issue I have thus far worked on. I decided that the best way to approach this issue would be to focus on establishing a set of tools that could be used by more-knowledgeable contributors to later construct comparative spectrums—opinionated data visualizations. As such, my first step was to build a set of responsive graphical elements that resembled [those provided as examples](https://docs.google.com/presentation/d/1P6LzzG0_alAxshpdfLnix53S9WU4vjbpSCrHJQoWPqc/edit#slide=id.p6). These include: + +#### (1) _Sleek information cards:_ + +
+ + + + + + + +
Card or this Card
+ +_(Source: [ONIF Container Networking Panel, slides 5 and 6](https://docs.google.com/presentation/d/1P6LzzG0_alAxshpdfLnix53S9WU4vjbpSCrHJQoWPqc/edit#slide=id.p6))_ + +#### (2) _Gradiented, labelable double-arrow banners:_ + +Arrow + +_(Source: [ONIF Container Networking Panel, slide 5](https://docs.google.com/presentation/d/1P6LzzG0_alAxshpdfLnix53S9WU4vjbpSCrHJQoWPqc/edit#slide=id.p6))_ + +#### (3) _Graphically-augmented tables:_ + +Table + +_(Source: [ONIF Container Networking Panel, slide 8](https://docs.google.com/presentation/d/1P6LzzG0_alAxshpdfLnix53S9WU4vjbpSCrHJQoWPqc/edit#slide=id.p12))_ + +#### (4) _Spectrum-like graphical comparisons:_ + +Comparison + +_(Source: [ONIF Container Networking Panel, slide 7](https://docs.google.com/presentation/d/1P6LzzG0_alAxshpdfLnix53S9WU4vjbpSCrHJQoWPqc/edit#slide=id.p6))_ + +* * * + +(1) Although there may exist libraries that may help construct such graphical elements, I did not want to introduce additional libraries to accomplish my work. Instead, I wanted to make good use of Layer5io's preexisting [Materialize](https://materializecss.com/) library. Fortunately, Materialize strongly supports the design of card-like structures, allowing me to more easily [implement some](https://github.com/layer5io/layer5/pull/238/files#diff-20fc098534d6aab31ad8e5c9db51bde0R10). + +(2) Unfortunately, it does not seem that Materialize supports the creation of graphical arrows, so I just ended up [styling my own](https://github.com/layer5io/layer5/pull/238/files#diff-1d5fe92e61759723c94b009b32e9e1b7R2). + +(3) These tables can be quite easily implemented and styled with or without the use of `` tags. I anticipate these will be given a proper fleshing out after the other graphical elements are further developed. + +(4) These unique spectrum graphics present the most challenging, of all the comparison tools, to implement. Snaking spectrum bar aside, I needed to develop a _responsive_ solution that (a) allowed contributors to programmatically place image thumbnails at preset horizontal positions, while (b) ensuring those thumbnails placed at the same position do not overlap with one another (and instead align vertically atop each other). + +This presented a problem to solve: I required a means to 'float' elements toward a horizontal line; to 'stack' thumbnails atop one another, without overlap, if they are given the same horizontal position. After researching quite deeply into potential solutions to this problem, I ended up stumbling across some CSS property-value pairings that I had never heard of before: [`display: grid`](https://www.w3schools.com/css/css_grid.asp) and [`grid-auto-flow: row dense`](https://www.w3schools.com/cssref/pr_grid-auto-flow.asp). Miraculously, I discovered that these could actually function as [a basis for a solution](https://github.com/layer5io/layer5/pull/238/files#diff-1d5fe92e61759723c94b009b32e9e1b7R76). + +* * * + +After styling the graphical elements, I continued the website's trend of using [Liquid](https://help.shopify.com/en/themes/liquid) tags (e.g. [`for`](https://help.shopify.com/en/themes/liquid/tags/iteration-tags#for)) and [YAML lists](https://docs.ansible.com/ansible/latest/reference_appendices/YAMLSyntax.html) to help modularize my solutions, which should aid future contributors in generalizing them. + +* * * + +I opened [a pull request](https://github.com/layer5io/layer5/pull/238) to share my work as well as invite collaboration: + +PR 211-2 + +Pull request [layer5#238](https://github.com/layer5io/layer5/pull/238): description of tooling introduced + +Image + +Pull request [layer5#238](https://github.com/layer5io/layer5/pull/238): example images of tooling introduced + +The pull request was quite well-recieved: + +Comment + +[Comment](https://github.com/layer5io/layer5/pull/238#issuecomment-554181763) by Layer5 team lead on pull request [layer5#238](https://github.com/layer5io/layer5/pull/238) + +As I mentioned in a recent Layer5 community meeting, I am very excited to continue working with Layer5; to refine and expand upon this set of new, visionary tooling for their landscape! + + + diff --git a/src/collections/blog/2019/2019-12-04-layer5-landscape-spectrums-revisited/index.mdx b/src/collections/blog/2019/2019-12-04-layer5-landscape-spectrums-revisited/index.mdx index 2c7ba7447aeb..9510ee30c1ca 100644 --- a/src/collections/blog/2019/2019-12-04-layer5-landscape-spectrums-revisited/index.mdx +++ b/src/collections/blog/2019/2019-12-04-layer5-landscape-spectrums-revisited/index.mdx @@ -1,72 +1,72 @@ ---- -title: "Layer5: Landscape Spectrums Revisited" -subtitle: "" -date: 2019-12-04 18:10:00 +0000 -author: Rafi Ungar -thumbnail: ./landscape_green.svg -darkthumbnail: ./landscape_green.svg -category: Internship Programs -tags: - - Community - - Landscape -published: true -type: Blog -product: Service Mesh Landscape -resource: true -redirect_from: - - /blog/layer5-landscape-spectrums-revisited/ ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import issueImage from "./issue.webp"; - - - -Several weeks ago, I wrote [a blog post](https://raungar.wordpress.com/2019/11/15/introducing-comparative-spectrums-to-the-layer5-landscape/) about introducing "comparative spectrum" tools to [the Layer5 landscape](https://layer5.io/landscape)—a webpage which I have transformed multiple times, now! - -Up until now, the contents of each blog post I have written were centered upon a freshly-opened pull request. Shortly before writing my last post, I did open [one such pull request (layer5#238)](https://github.com/layer5io/layer5/pull/238). However, since my PR remains open, and since I am still working on the same issue my PR addresses, I have opted to instead push [a new commit](https://github.com/layer5io/layer5/pull/238/commits/4d396aaa6d3ca46add71531daedc8c0e2a5d2495) to the aformentioned (but, now, renamed) PR instead of creating a whole new one. This newest commit introduces a major step towards resolving the issue at hand, and will be the subject of this blog post! - -Issue - -The issue at hand: [layer5#211](https://github.com/layer5io/layer5/issues/211) - add comparative spectrums to the Landscape page - -* * * - -_**Note:** this blog post will frequently reference [the update and documentation comment that I made](https://github.com/layer5io/layer5/pull/238#issuecomment-561613644) to accompany my last commit to my PR. I consider this hefty comment to be an extension of this blog post, so I strongly recommend giving it a read!_ - -* * * - -My initial commit towards introducing comparative spectrum tooling did not represent a full solution. Thinking about what might constitute a full solution for the issue at hand, I came up with three criteria: - -## What was still needed: - -#### 1\. A complete toolset - -Within [Issue #211](https://github.com/layer5io/layer5/issues/211), Layer5 lead developer Lee indicates [four slides](https://docs.google.com/presentation/d/1P6LzzG0_alAxshpdfLnix53S9WU4vjbpSCrHJQoWPqc/edit#slide=id.p6) upon which comparative spectrum graphics may be based upon. During my initial commit, I created graphics that emulated those found within the first three of those four slides, but I had yet to implement the graphic found in [the fourth](https://docs.google.com/presentation/d/1P6LzzG0_alAxshpdfLnix53S9WU4vjbpSCrHJQoWPqc/edit#slide=id.p12): a table. I was also less-than-satisfied with the 'grid' design I had implemented in response to [slide 7](https://docs.google.com/presentation/d/1P6LzzG0_alAxshpdfLnix53S9WU4vjbpSCrHJQoWPqc/edit#slide=id.p10). - -#### 2\. A modular design - -The designs I am implementing are meant to be used to present opinionated information. As I am not nearly knowledgeable to form opinionated comparisons between service meshes and related technologies, I have instead made my goal to make it as easy as possible for other Layer5 contributors to utilize the graphics ("\[comparative\] spectrums") that I am designing. Doing so would require encapsulating (templating) the spectrums I design (new and old), within their own HTML files, and providing a means to easily invoke (and customize) instances of those templates into the Landscape page. - -#### 3\. Documentation - -Because the templates I design are intended to be implemented and customized by other contributors, it is _especially_ critical that those contributors have access to complete and thorough documentation detailing the intended use of each templated design. - -* * * - -## What I delivered: - -#### 1\. A complete toolset - -As documented in my [update comment](https://github.com/layer5io/layer5/pull/238#issuecomment-561613644), I designed a table that very closely resembles that of Lee's slides. Implementing the table was interesting, as it ended up requiring [quite a few nested Liquid for-loops](https://github.com/layer5io/layer5/blob/4d396aaa6d3ca46add71531daedc8c0e2a5d2495/_includes/partials/spectrum/table.html#L23). Also as documented, I revamped the grid-based tooling and am quite pleased with the improvements made. The end result of these efforts is a complete set of comparative spectrums. - -#### 2, 3. A modular design and documentation - -The bulk of the documentation I wrote details how to deal with the modular solution that I designed and implemented to enable comparative spectrums to be included into the Landscape page (through the use of Liquid `include` tags). The documentation speaks for itself; [check it out!](https://github.com/layer5io/layer5/pull/238#issuecomment-561613644) - -## What's next? - -I would not have considered the documentation I delivered to be complete if I did not report on the issues still present in the work I delivered. I denoted these as 'Current issues' in the documentation, and they represent work that still remains to be done. I know that I can count on the Layer5 community to assist me with small issues like these, and, once this pull request receives some forward motion, I hope to start zeroing in on its smaller issues. Fortunately, I have made plans to continue working with open source well into the new year! - - - +--- +title: "Layer5: Landscape Spectrums Revisited" +subtitle: "" +date: 2019-12-04 18:10:00 +0000 +author: Rafi Ungar +thumbnail: ./landscape_green.svg +darkthumbnail: ./landscape_green.svg +category: Internship Programs +tags: + - Community + - Landscape +published: true +type: Blog +product: Service Mesh Landscape +resource: true +redirect_from: + - /blog/layer5-landscape-spectrums-revisited/ +--- + + +import issueImage from "./issue.webp"; + + + +Several weeks ago, I wrote [a blog post](https://raungar.wordpress.com/2019/11/15/introducing-comparative-spectrums-to-the-layer5-landscape/) about introducing "comparative spectrum" tools to [the Layer5 landscape](https://layer5.io/landscape)—a webpage which I have transformed multiple times, now! + +Up until now, the contents of each blog post I have written were centered upon a freshly-opened pull request. Shortly before writing my last post, I did open [one such pull request (layer5#238)](https://github.com/layer5io/layer5/pull/238). However, since my PR remains open, and since I am still working on the same issue my PR addresses, I have opted to instead push [a new commit](https://github.com/layer5io/layer5/pull/238/commits/4d396aaa6d3ca46add71531daedc8c0e2a5d2495) to the aformentioned (but, now, renamed) PR instead of creating a whole new one. This newest commit introduces a major step towards resolving the issue at hand, and will be the subject of this blog post! + +Issue + +The issue at hand: [layer5#211](https://github.com/layer5io/layer5/issues/211) - add comparative spectrums to the Landscape page + +* * * + +_**Note:** this blog post will frequently reference [the update and documentation comment that I made](https://github.com/layer5io/layer5/pull/238#issuecomment-561613644) to accompany my last commit to my PR. I consider this hefty comment to be an extension of this blog post, so I strongly recommend giving it a read!_ + +* * * + +My initial commit towards introducing comparative spectrum tooling did not represent a full solution. Thinking about what might constitute a full solution for the issue at hand, I came up with three criteria: + +## What was still needed: + +#### 1\. A complete toolset + +Within [Issue #211](https://github.com/layer5io/layer5/issues/211), Layer5 lead developer Lee indicates [four slides](https://docs.google.com/presentation/d/1P6LzzG0_alAxshpdfLnix53S9WU4vjbpSCrHJQoWPqc/edit#slide=id.p6) upon which comparative spectrum graphics may be based upon. During my initial commit, I created graphics that emulated those found within the first three of those four slides, but I had yet to implement the graphic found in [the fourth](https://docs.google.com/presentation/d/1P6LzzG0_alAxshpdfLnix53S9WU4vjbpSCrHJQoWPqc/edit#slide=id.p12): a table. I was also less-than-satisfied with the 'grid' design I had implemented in response to [slide 7](https://docs.google.com/presentation/d/1P6LzzG0_alAxshpdfLnix53S9WU4vjbpSCrHJQoWPqc/edit#slide=id.p10). + +#### 2\. A modular design + +The designs I am implementing are meant to be used to present opinionated information. As I am not nearly knowledgeable to form opinionated comparisons between service meshes and related technologies, I have instead made my goal to make it as easy as possible for other Layer5 contributors to utilize the graphics ("\[comparative\] spectrums") that I am designing. Doing so would require encapsulating (templating) the spectrums I design (new and old), within their own HTML files, and providing a means to easily invoke (and customize) instances of those templates into the Landscape page. + +#### 3\. Documentation + +Because the templates I design are intended to be implemented and customized by other contributors, it is _especially_ critical that those contributors have access to complete and thorough documentation detailing the intended use of each templated design. + +* * * + +## What I delivered: + +#### 1\. A complete toolset + +As documented in my [update comment](https://github.com/layer5io/layer5/pull/238#issuecomment-561613644), I designed a table that very closely resembles that of Lee's slides. Implementing the table was interesting, as it ended up requiring [quite a few nested Liquid for-loops](https://github.com/layer5io/layer5/blob/4d396aaa6d3ca46add71531daedc8c0e2a5d2495/_includes/partials/spectrum/table.html#L23). Also as documented, I revamped the grid-based tooling and am quite pleased with the improvements made. The end result of these efforts is a complete set of comparative spectrums. + +#### 2, 3. A modular design and documentation + +The bulk of the documentation I wrote details how to deal with the modular solution that I designed and implemented to enable comparative spectrums to be included into the Landscape page (through the use of Liquid `include` tags). The documentation speaks for itself; [check it out!](https://github.com/layer5io/layer5/pull/238#issuecomment-561613644) + +## What's next? + +I would not have considered the documentation I delivered to be complete if I did not report on the issues still present in the work I delivered. I denoted these as 'Current issues' in the documentation, and they represent work that still remains to be done. I know that I can count on the Layer5 community to assist me with small issues like these, and, once this pull request receives some forward motion, I hope to start zeroing in on its smaller issues. Fortunately, I have made plans to continue working with open source well into the new year! + + + diff --git a/src/collections/blog/2020/2020-03-11-deploying-linkerd-with-meshery/index.mdx b/src/collections/blog/2020/2020-03-11-deploying-linkerd-with-meshery/index.mdx index 793b9edf0b11..d905e19a9fbc 100644 --- a/src/collections/blog/2020/2020-03-11-deploying-linkerd-with-meshery/index.mdx +++ b/src/collections/blog/2020/2020-03-11-deploying-linkerd-with-meshery/index.mdx @@ -1,152 +1,150 @@ ---- -title: "Deploying Linkerd with Meshery" -subtitle: "" -date: 2020-03-11 08:15:05 +0000 -author: Anton Weiss -thumbnail: ./Linkerd-with-Meshery.webp -darkthumbnail: ./Linkerd-with-Meshery.webp -category: Meshery -tags: - - Linkerd - - Meshery -published: true -type: Blog -mesh: Linkerd -product: Meshery -resource: true -redirect_from: - - /blog/deploying-linkerd-with-meshery/ ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import awsappmesh from '../../../../assets/images/service-mesh-icons/aws-app-mesh.webp'; -import consul from '../../../../assets/images/service-mesh-icons/consul.svg'; -import istio from '../../../../assets/images/service-mesh-icons/istio.svg'; -import linkerd from '../../../../assets/images/service-mesh-icons/linkerd.svg'; -import maesh from '../../../../assets/images/service-mesh-icons/maesh.webp'; -import nsm from '../../../../assets/images/service-mesh-icons/nsm.svg'; -import octarine from '../../../../assets/images/service-mesh-icons/octarine.svg'; -import kuma from '../../../../assets/images/service-mesh-icons/kuma.svg'; -import {Link} from "gatsby" - - - -It’s no secret that service mesh tech is boiling hot. Microservice architectures brought on as many challenges as they have advantages. With operational complexity being one of the most acute pains. Service meshes do offer solutions to a number of these operational concerns. Including but not limited to: resilience, improved observability, security and advanced service discovery. -
-
- - -
-But with so many mesh options around - how do we choose, evaluate and compare them? And once we’ve chosen a solution - how do we make it accessible to all our engineers? It is to provide an answer to these questions that the Layer5 community has created Meshery, the open-source, service mesh management plane. Meshery already supports a number of leading mesh providers with adapters for additional meshes on the way. In today’s video, I’ll show how to use Meshery for rolling out and evaluating Linkerd. - - Linkerd is a system that comes from the service mesh pioneers - the company called Buoyant. They were the first to realise the need for a distributed network of smart, centrally configured proxies and coin the term “service mesh” back in 2016. Today, we’ll be looking at Linkerd 2.x - the second generation of this now CNCF project. -
-
-
Meshery Adapters
-
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
stable
- Istio Service Mesh adapterMeshery adapter for Istio -
- LinkerdMeshery adapter for Linkerd -
- Consul ConnectMeshery adapter for Consul -
- Octarine Service MeshMeshery adapter for Octarine -
- Network MeshMeshery adapter for Network Service Mesh -
beta - Citrix CPX Service MeshMeshery adapter for Citrix CPX -
alpha
- Maesh Service MeshMeshery adapter for Maesh -
- AWS App Mesh Service MeshMeshery adapter for App Mesh -
- Kuma Service MeshMeshery adapter for Kuma -
- - -Some things that Linkerd is known for: - -
  • Purpose-built for Kubernetes
  • -
  • Featuring custom-built, highly performant proxies written in Rust
  • -
  • Zero-config option (works out-of-the-box)
  • -
  • Network telemetry built-in (includes a pre-configured, optimised Prometheus instance)
  • -
  • Low-overhead control-plane
  • -
  • Operational simplicity (when compared to Istio, for example, even though Istio is getting better in this regard)
  • - -So what is covered in the video? More or less the following: - -
  • What service mesh tech allows us to do
  • -
  • What a typical service mesh architecture looks like
  • -
  • What Layer5 is about (Lookout - it may surprise you! 😯)
  • -
  • What Meshery is. What Linkerd is.
  • -
  • How easy it is to install Meshery on your PC (be it Linux, Mac or Windows)
  • -
    • All it takes is: - -```sh -$ curl -L https://meshery.io/install | PLATFORM=kubernetes bash - -``` - -
    -
  • How Meshery connects to your Kubernetes cluster (nothing to be done if it’s in your kubectl config current-context)
  • -
  • How to correctly install and remove Linkerd on your Kubernetes cluster using Meshery
  • -
  • How to install one of included Linkerd sample applications and verify the installation
  • - -That’s quite a lot of content for a 20 minute clip. In the follow-up videos, we’ll dive deeper into many of these concepts. And also show how to use Meshery with other service mesh providers. - -This video is also the opening shot of Layer5's [Learn to Service Mesh](https://www.youtube.com/playlist?list=PL3A-A6hPO2IN_HSU0pSfijBboiHggs5mC) playlist, which is specifically dedicated to tutorials and webinars. If service mesh tech interests you and you’re willing to learn more about it, then make sure to [subscribe to the channel](https://www.youtube.com/channel/UCFL1af7_wdnhHXL1InzaMvA?sub_confirmation=1) and watch for updates. - -And let us know if there’s any specific content you want us to create. Or maybe anything you’ve created yourself and would like to share? Layer5 is all about knowledge sharing and we want to talk to you, so please [join the cloud native community](http://slack.layer5.io)! - -Happy meshing! -
    - - -
    +--- +title: "Deploying Linkerd with Meshery" +subtitle: "" +date: 2020-03-11 08:15:05 +0000 +author: Anton Weiss +thumbnail: ./Linkerd-with-Meshery.webp +darkthumbnail: ./Linkerd-with-Meshery.webp +category: Meshery +tags: + - Linkerd + - Meshery +published: true +type: Blog +mesh: Linkerd +product: Meshery +resource: true +redirect_from: + - /blog/deploying-linkerd-with-meshery/ +--- + + +import awsappmesh from "../../../../assets/images/service-mesh-icons/aws-app-mesh.webp"; +import consul from "../../../../assets/images/service-mesh-icons/consul.svg"; +import istio from "../../../../assets/images/service-mesh-icons/istio.svg"; +import linkerd from "../../../../assets/images/service-mesh-icons/linkerd.svg"; +import maesh from "../../../../assets/images/service-mesh-icons/maesh.webp"; +import nsm from "../../../../assets/images/service-mesh-icons/nsm.svg"; +import octarine from "../../../../assets/images/service-mesh-icons/octarine.svg"; +import kuma from "../../../../assets/images/service-mesh-icons/kuma.svg"; + + + + +It’s no secret that service mesh tech is boiling hot. Microservice architectures brought on as many challenges as they have advantages. With operational complexity being one of the most acute pains. Service meshes do offer solutions to a number of these operational concerns. Including but not limited to: resilience, improved observability, security and advanced service discovery. +
    +
    + + +
    +But with so many mesh options around - how do we choose, evaluate and compare them? And once we’ve chosen a solution - how do we make it accessible to all our engineers? It is to provide an answer to these questions that the Layer5 community has created Meshery, the open-source, service mesh management plane. Meshery already supports a number of leading mesh providers with adapters for additional meshes on the way. In today’s video, I’ll show how to use Meshery for rolling out and evaluating Linkerd. + + Linkerd is a system that comes from the service mesh pioneers - the company called Buoyant. They were the first to realise the need for a distributed network of smart, centrally configured proxies and coin the term “service mesh” back in 2016. Today, we’ll be looking at Linkerd 2.x - the second generation of this now CNCF project. +
    + + +Some things that Linkerd is known for: + +
  • Purpose-built for Kubernetes
  • +
  • Featuring custom-built, highly performant proxies written in Rust
  • +
  • Zero-config option (works out-of-the-box)
  • +
  • Network telemetry built-in (includes a pre-configured, optimised Prometheus instance)
  • +
  • Low-overhead control-plane
  • +
  • Operational simplicity (when compared to Istio, for example, even though Istio is getting better in this regard)
  • + +So what is covered in the video? More or less the following: + +
  • What service mesh tech allows us to do
  • +
  • What a typical service mesh architecture looks like
  • +
  • What Layer5 is about (Lookout - it may surprise you! 😯)
  • +
  • What Meshery is. What Linkerd is.
  • +
  • How easy it is to install Meshery on your PC (be it Linux, Mac or Windows)
  • +
      +
    • +All it takes is: + +```sh +$ curl -L https://meshery.io/install | PLATFORM=kubernetes bash - +``` + +
    +
  • How Meshery connects to your Kubernetes cluster (nothing to be done if it’s in your kubectl config current-context)
  • +
  • How to correctly install and remove Linkerd on your Kubernetes cluster using Meshery
  • +
  • How to install one of included Linkerd sample applications and verify the installation
  • + +That’s quite a lot of content for a 20 minute clip. In the follow-up videos, we’ll dive deeper into many of these concepts. And also show how to use Meshery with other service mesh providers. + +This video is also the opening shot of Layer5's [Learn to Service Mesh](https://www.youtube.com/playlist?list=PL3A-A6hPO2IN_HSU0pSfijBboiHggs5mC) playlist, which is specifically dedicated to tutorials and webinars. If service mesh tech interests you and you’re willing to learn more about it, then make sure to [subscribe to the channel](https://www.youtube.com/channel/UCFL1af7_wdnhHXL1InzaMvA?sub_confirmation=1) and watch for updates. + +And let us know if there’s any specific content you want us to create. Or maybe anything you’ve created yourself and would like to share? Layer5 is all about knowledge sharing and we want to talk to you, so please [join the cloud native community](http://slack.layer5.io)! + +Happy meshing! +
    + + +
    diff --git a/src/collections/blog/2020/2020-05-21-getting-started-with-mesheryctl/index.mdx b/src/collections/blog/2020/2020-05-21-getting-started-with-mesheryctl/index.mdx index 6c28cd5e7322..486a222bbe21 100644 --- a/src/collections/blog/2020/2020-05-21-getting-started-with-mesheryctl/index.mdx +++ b/src/collections/blog/2020/2020-05-21-getting-started-with-mesheryctl/index.mdx @@ -1,228 +1,228 @@ ---- -title: "Getting started with mesheryctl" -subtitle: "No easier way to get started with a Cloud Native" -date: 2020-05-21 08:00:05 -0530 -author: Layer5 Team -thumbnail: ./mesheryctl.webp -darkthumbnail: ./mesheryctl.webp -category: Meshery -tags: - - Meshery - - mesheryctl -published: true -type: Blog -product: Meshery -resource: true -redirect_from: - - /blog/getting-started-with-mesheryctl/ ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import { Link } from "gatsby"; - - - - -### Introduction to Meshery - -For all those who are unaware of Meshery, Meshery is a cloud native management plane which provides users with operational best practices, lifecycle and configuration management, but also interoperates between various infrastructure, while enabling you with the tools and knowledge to glean the most of out your infrastructure performance, while keeping your overhead to a minimum. - -Meshery's vision is to make the operating of any cloud infrastructure simplified. Meshery is created by the Layer5. - -Layer5 is a community-first, Cloud Native company which has technology partnerships with various tech giants like Microsoft, CNCF, RedHat and many more to enlist. The community consists of open source leaders like maintainers of trending open-source projects, Google SoCers, Docker Captains, Cloud Native Ambassadors and many more (join in!). - - -### What is mesheryctl? - -Meshery provides you with a clean, robust, streamlined command-line interface to manage and benchmark your infrastructure, `mesheryctl`. With `mesheryctl`, not only you can manage your adapters & containers but you can also benchmark your mesh using the command line. `mesheryctl` provides support to a number of platforms so that we never miss out users. `mesheryctl` can be installed with a single bash command by simply executing: - -```bash -$ curl -L https://meshery.io/install | PLATFORM=kubernetes bash - -```` - -in your terminal. You will see Meshery getting installed & fired up on port: 9081. -You will see the output as - - -``` -Extracting mesheryctl-v0.3.14... -Archive: /Users/user/meshery.zip - inflating: LICENSE - inflating: README.md - inflating: mesheryctl - -Installing mesheryctl in /usr/local/bin. -mesheryctl installed. -permissions moved to user -Removing installation files and opening Meshery...Updating Meshery now... -Pulling meshery ... download complete -Pulling meshery-istio ... done -Pulling meshery-linkerd ... done -Pulling meshery-consul ... done -Pulling meshery-octarine ... done -Pulling meshery-nsm ... done -Pulling meshery-cpx ... done -Pulling watchtower ... done -``` - -and you will be able to see the Meshery UI on `https://localhost:9081`. - -If you are wondering if bash is only way to get `mesheryctl`, then here is the list of platforms which you can get `mesheryctl` describing all the different ways to get it. - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    PlatformSupported?
    Docker✔️
    - Docker - Docker App✔️
    Kubernetes✔️
    - Kubernetes - AKS✔️
    - Kubernetes - Docker Desktop✔️
    - Kubernetes - EKS✔️
    - Kubernetes - GKE✔️
    - Kubernetes - Helm✔️
    - Kubernetes - Minikube✔️
    - Kubernetes - OpenShiftIn Progress
    Linux✔️
    Mac✔️
    - Mac - Homebrew✔️
    Windows✔️
    - Scoop✔️
    - WSL2✔️
    Raspberry PiIn Progress
    - -
    -We believe we have not missed any of the popular platforms for what it’s worth, we will be rolling out support for RaspberryPi and OpenShift soon 🎉🎉🎉. - -If you are thinking about the requirements you would have to run `mesheryctl`, so to your surprise, to successfully run `mesheryctl` you will only need : - -
    a running Docker daemon
    - -### Into the MesheryCTL - -Once you have successfully installed, you will be having the power of a new CLI Command MesheryCTL. As you type `mesheryctl` into your terminal, you will be shown with the various sub-commands and flags `mesheryctl` can support. - -``` -Meshery is the cloud native management plane, providing lifecycle, performance, and configuration management of cloud infrastructure and their workloads. - -Usage: - mesheryctl [command] - -Available Commands: - help Help about any command - perf Performance Management - system Meshery Lifecyle Management - version Print mesheryctl version - - -Flags: - --config string config file (default location is: $HOME/.meshery//meshery.yaml) - -h, --help help for mesheryctl - -v, --version Version of mesheryctl - -Use "mesheryctl [command] --help" for more information about a command. -``` - -Once you do `mesheryctl system start`, Meshery will pull its adapters and latest docker images. Meshery will also detect your Kubernetes configuration and will let you know if Kubernetes is running. Meshery will run it’s web-based user interface on localhost port `9081` and will let you select your choice of Provider before you can start managing your infrastructure with this powerful utility. - -
    One of the most interesting sub-commands of mesheryctl is perf.
    - -The `perf` subcommand enables you to being managing the performance of your cloud native deployment and your workloads running atop of them. It lets you benchmark your infrastructure without using the Meshery UI from the command line interface itself. Once you type `mesheryctl perf`, it will present you with all the powerful flags you can control with CLI, including providing it with a `--file` flag that points to any of a number of performance test profiles that you may have saved. - -``` -Performance Management and Benchmarking using Meshery CLI. - -Usage: - mesheryctl perf --[flags] - -Available Flags for Performance Command: - name[string] (optional) A short descriptor to serve as reference for this test. If not provided, a random name will be generate. - url[string] (required) URL endpoint to send requests. - duration[string] (required) Length of time to perform test (e.g 30s, 15m, 1hr). See standard notation https://golang.org/pkg/time/#ParseDuration - load-generator[string] (optional) Name of load generator to be used to perform test (default: "fortio") - provider[string] (required) Choice of Provider (default: "Meshery") - concurrent-requests[string] (optional) Number of parallel requests to be sent (default: "1") - qps[string] (required) Queries per second (default: "0") - file[string] (optional) file containing SMPS-compatible test configuration. - help Help for perf subcommand - -url, duration, concurrent-requests, and qps can be considered optional flags if specified through an SMPS compatible yaml file using --file -``` - -An example usage of `mesheryctl perf --[flags]` can be - -```bash - mesheryctl perf --name "a quick stress test" --url http://192.168.1.15/productpage --qps 300 --concurrent-requests 2 --duration 30s --token "provider=Meshery" -``` - -You can also provide a SMPS Configuration file with `perf` subcommand, with this file provided you will not have to specify url, duration, concurrent-requests & qps. However, if specified the value provided through file will be over-rided by value through CLI. For more info about file configuration, see [here](https://github.com/service-mesh-performance/service-mesh-performance/blob/master/docs/assets/spec/readme/service%20mesh%20performance%20specification%20result.yaml). - -```bash - mesheryctl perf --name "a quick stress test" --file {path}/smps.yaml --token "provider=Meshery" -``` - -### What's next? - -Meshery is an ever-growing community with attracting contributors from across the globe. We always have a role for everyone whether to be a code-writer, a community manager or a marketer. Layer5 community is always open to welcome you warmly. - -If this makes you excited, [join the Layer5 community](http://slack.layer5.io) with just a click & someone will be there to make sure you do not get missed. - - -
    +--- +title: "Getting started with mesheryctl" +subtitle: "No easier way to get started with a Cloud Native" +date: 2020-05-21 08:00:05 -0530 +author: Layer5 Team +thumbnail: ./mesheryctl.webp +darkthumbnail: ./mesheryctl.webp +category: Meshery +tags: + - Meshery + - mesheryctl +published: true +type: Blog +product: Meshery +resource: true +redirect_from: + - /blog/getting-started-with-mesheryctl/ +--- + + + + + + + +### Introduction to Meshery + +For all those who are unaware of Meshery, Meshery is a cloud native management plane which provides users with operational best practices, lifecycle and configuration management, but also interoperates between various infrastructure, while enabling you with the tools and knowledge to glean the most of out your infrastructure performance, while keeping your overhead to a minimum. + +Meshery's vision is to make the operating of any cloud infrastructure simplified. Meshery is created by the Layer5. + +Layer5 is a community-first, Cloud Native company which has technology partnerships with various tech giants like Microsoft, CNCF, RedHat and many more to enlist. The community consists of open source leaders like maintainers of trending open-source projects, Google SoCers, Docker Captains, Cloud Native Ambassadors and many more (join in!). + + +### What is mesheryctl? + +Meshery provides you with a clean, robust, streamlined command-line interface to manage and benchmark your infrastructure, `mesheryctl`. With `mesheryctl`, not only you can manage your adapters & containers but you can also benchmark your mesh using the command line. `mesheryctl` provides support to a number of platforms so that we never miss out users. `mesheryctl` can be installed with a single bash command by simply executing: + +```bash +$ curl -L https://meshery.io/install | PLATFORM=kubernetes bash - +```` + +in your terminal. You will see Meshery getting installed & fired up on port: 9081. +You will see the output as + + +``` +Extracting mesheryctl-v0.3.14... +Archive: /Users/user/meshery.zip + inflating: LICENSE + inflating: README.md + inflating: mesheryctl + +Installing mesheryctl in /usr/local/bin. +mesheryctl installed. +permissions moved to user +Removing installation files and opening Meshery...Updating Meshery now... +Pulling meshery ... download complete +Pulling meshery-istio ... done +Pulling meshery-linkerd ... done +Pulling meshery-consul ... done +Pulling meshery-octarine ... done +Pulling meshery-nsm ... done +Pulling meshery-cpx ... done +Pulling watchtower ... done +``` + +and you will be able to see the Meshery UI on `https://localhost:9081`. + +If you are wondering if bash is only way to get `mesheryctl`, then here is the list of platforms which you can get `mesheryctl` describing all the different ways to get it. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    PlatformSupported?
    Docker✔️
    - Docker - Docker App✔️
    Kubernetes✔️
    - Kubernetes - AKS✔️
    - Kubernetes - Docker Desktop✔️
    - Kubernetes - EKS✔️
    - Kubernetes - GKE✔️
    - Kubernetes - Helm✔️
    - Kubernetes - Minikube✔️
    - Kubernetes - OpenShiftIn Progress
    Linux✔️
    Mac✔️
    - Mac - Homebrew✔️
    Windows✔️
    - Scoop✔️
    - WSL2✔️
    Raspberry PiIn Progress
    + +
    +We believe we have not missed any of the popular platforms for what it’s worth, we will be rolling out support for RaspberryPi and OpenShift soon 🎉🎉🎉. + +If you are thinking about the requirements you would have to run `mesheryctl`, so to your surprise, to successfully run `mesheryctl` you will only need : + +
    a running Docker daemon
    + +### Into the MesheryCTL + +Once you have successfully installed, you will be having the power of a new CLI Command MesheryCTL. As you type `mesheryctl` into your terminal, you will be shown with the various sub-commands and flags `mesheryctl` can support. + +``` +Meshery is the cloud native management plane, providing lifecycle, performance, and configuration management of cloud infrastructure and their workloads. + +Usage: + mesheryctl [command] + +Available Commands: + help Help about any command + perf Performance Management + system Meshery Lifecyle Management + version Print mesheryctl version + + +Flags: + --config string config file (default location is: $HOME/.meshery//meshery.yaml) + -h, --help help for mesheryctl + -v, --version Version of mesheryctl + +Use "mesheryctl [command] --help" for more information about a command. +``` + +Once you do `mesheryctl system start`, Meshery will pull its adapters and latest docker images. Meshery will also detect your Kubernetes configuration and will let you know if Kubernetes is running. Meshery will run it’s web-based user interface on localhost port `9081` and will let you select your choice of Provider before you can start managing your infrastructure with this powerful utility. + +
    One of the most interesting sub-commands of mesheryctl is perf.
    + +The `perf` subcommand enables you to being managing the performance of your cloud native deployment and your workloads running atop of them. It lets you benchmark your infrastructure without using the Meshery UI from the command line interface itself. Once you type `mesheryctl perf`, it will present you with all the powerful flags you can control with CLI, including providing it with a `--file` flag that points to any of a number of performance test profiles that you may have saved. + +``` +Performance Management and Benchmarking using Meshery CLI. + +Usage: + mesheryctl perf --[flags] + +Available Flags for Performance Command: + name[string] (optional) A short descriptor to serve as reference for this test. If not provided, a random name will be generate. + url[string] (required) URL endpoint to send requests. + duration[string] (required) Length of time to perform test (e.g 30s, 15m, 1hr). See standard notation https://golang.org/pkg/time/#ParseDuration + load-generator[string] (optional) Name of load generator to be used to perform test (default: "fortio") + provider[string] (required) Choice of Provider (default: "Meshery") + concurrent-requests[string] (optional) Number of parallel requests to be sent (default: "1") + qps[string] (required) Queries per second (default: "0") + file[string] (optional) file containing SMPS-compatible test configuration. + help Help for perf subcommand + +url, duration, concurrent-requests, and qps can be considered optional flags if specified through an SMPS compatible yaml file using --file +``` + +An example usage of `mesheryctl perf --[flags]` can be + +```bash + mesheryctl perf --name "a quick stress test" --url http://192.168.1.15/productpage --qps 300 --concurrent-requests 2 --duration 30s --token "provider=Meshery" +``` + +You can also provide a SMPS Configuration file with `perf` subcommand, with this file provided you will not have to specify url, duration, concurrent-requests & qps. However, if specified the value provided through file will be over-rided by value through CLI. For more info about file configuration, see [here](https://github.com/service-mesh-performance/service-mesh-performance/blob/master/docs/assets/spec/readme/service%20mesh%20performance%20specification%20result.yaml). + +```bash + mesheryctl perf --name "a quick stress test" --file {path}/smps.yaml --token "provider=Meshery" +``` + +### What's next? + +Meshery is an ever-growing community with attracting contributors from across the globe. We always have a role for everyone whether to be a code-writer, a community manager or a marketer. Layer5 community is always open to welcome you warmly. + +If this makes you excited, [join the Layer5 community](http://slack.layer5.io) with just a click & someone will be there to make sure you do not get missed. + + +
    diff --git a/src/collections/blog/2020/2020-06-01-meshery-accepted-into-cncf-landscape/index.mdx b/src/collections/blog/2020/2020-06-01-meshery-accepted-into-cncf-landscape/index.mdx index b35122a76131..6b3b4c1ed863 100644 --- a/src/collections/blog/2020/2020-06-01-meshery-accepted-into-cncf-landscape/index.mdx +++ b/src/collections/blog/2020/2020-06-01-meshery-accepted-into-cncf-landscape/index.mdx @@ -1,71 +1,71 @@ ---- -title: "Meshery lands in the CNCF Landscape" -subtitle: "This is a story about growing together as a community and building a project that matters." -date: 2020-06-01 10:30:05 -0530 -author: Anton Weiss -thumbnail: ./cncf-meshery.webp -darkthumbnail: ./cncf-meshery.webp -category: Announcements -tags: - - Meshery - - Landscape -published: true -type: Blog -product: Meshery -resource: true -redirect_from: - - /blog/meshery-lands-in-the-cncf-landscape/ ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import cncf from "./cncf-landscape-stacked-color.svg" -import cncfmeshery from "./cncf-meshery-landscape.webp" - - - -cncf-landscape-stacked-color - -### Digging into Service Meshes - -About a year and a half ago I got interested in service mesh technology. A customer needed some advanced routing capabilities and we started looking at Envoy and Istio. Then - invitations to talk about Istio at meetups and conferences started flowing in. That's when I got excited about progressive delivery capabilities that service meshes enable. I even wrote a Kubernetes Istio canary controller - BirdWatch. - -### Finding Meshery - -Digging deeper into what service meshes had to offer I discovered Meshery - the universal service mesh management plane. And immediately joined Layer5 - the great, welcoming open-source community that created it. - -### Community Matters - -Being a member of Layer5 was one of the nicest community experiences I've ever had. Mainly thanks to community's founder and captain - Lee Calcote. He always makes sure everybody feels significant, included and motivated to participate. And this spirit spreads out to all community activities. - -In no time, I had my first commits approved and merged and started joining weekly community and development video calls. - -### We're on CNCF Landscape! - -Now - I won't be reviewing Meshery in this post. I've spoken about it in this video and some great introductory articles by community members can be found here and here. This post is more of a celebration, because last week... - -
    Meshery now featured in the CNCF Landscape!
    - -cncf-meshery-landscape - -And this is only the first step - there's already an application filed for Meshery to become a full-fledged CNCF sandbox project. I had a chance to collaborate on the sandbox proposal and am so eager for this to happen. - -### Getting Meshy - -This is also an invitation to participate - Meshery is a young, ambitious project - it requires a ton of work to make it what it aims to become. Integrating with all of the leading service mesh solutions asks for extensive expertise. In many areas Meshery's functionality is still young. But these are normal growth stages, aren't they? To put it simple - the community and the project need more hands! And these should be your hands! - -

    As already mentioned - Layer5 is a very welcoming bunch!

    - -Open source contributions are a must-do for becoming a true cloud native hero. Cloud native is all about the community and one can't be a part of a community by only taking and never giving back. So if you were looking for a promising and welcoming project to join - look no further! Hop on to Layer5 Slack and we'll happily embrace you and help you get started. - -And it's not only coding! Documentation, testing, UI design, logos, blogs, videos - you decide where to apply your talent. - -For example - I sometimes wish I had more time and motivation to code new Meshery features or fix existing bugs. But instead I'm writing this post. Because lately I enjoy writing texts more than coding. Coding for longer than a couple of days at a time throws me into a coding fatigue… Actually also many other activities do. I'm just not very good at keeping a routine. But I'm sure many of you out there aren't like me. So why not join forces? - -### Join the cloud native community! - -* Meshery is an exciting opportunity to learn more about service meshes. -* We're already on CNCF Landscape and are headed for the sandbox. -* Now is a great time to hop on board. Are you ready? Get into the mesh pit! - - -
    +--- +title: "Meshery lands in the CNCF Landscape" +subtitle: "This is a story about growing together as a community and building a project that matters." +date: 2020-06-01 10:30:05 -0530 +author: Anton Weiss +thumbnail: ./cncf-meshery.webp +darkthumbnail: ./cncf-meshery.webp +category: Announcements +tags: + - Meshery + - Landscape +published: true +type: Blog +product: Meshery +resource: true +redirect_from: + - /blog/meshery-lands-in-the-cncf-landscape/ +--- + + +import cncf from "./cncf-landscape-stacked-color.svg" +import cncfmeshery from "./cncf-meshery-landscape.webp" + + + +cncf-landscape-stacked-color + +### Digging into Service Meshes + +About a year and a half ago I got interested in service mesh technology. A customer needed some advanced routing capabilities and we started looking at Envoy and Istio. Then - invitations to talk about Istio at meetups and conferences started flowing in. That's when I got excited about progressive delivery capabilities that service meshes enable. I even wrote a Kubernetes Istio canary controller - BirdWatch. + +### Finding Meshery + +Digging deeper into what service meshes had to offer I discovered Meshery - the universal service mesh management plane. And immediately joined Layer5 - the great, welcoming open-source community that created it. + +### Community Matters + +Being a member of Layer5 was one of the nicest community experiences I've ever had. Mainly thanks to community's founder and captain - Lee Calcote. He always makes sure everybody feels significant, included and motivated to participate. And this spirit spreads out to all community activities. + +In no time, I had my first commits approved and merged and started joining weekly community and development video calls. + +### We're on CNCF Landscape! + +Now - I won't be reviewing Meshery in this post. I've spoken about it in this video and some great introductory articles by community members can be found here and here. This post is more of a celebration, because last week... + +
    Meshery now featured in the CNCF Landscape!
    + +cncf-meshery-landscape + +And this is only the first step - there's already an application filed for Meshery to become a full-fledged CNCF sandbox project. I had a chance to collaborate on the sandbox proposal and am so eager for this to happen. + +### Getting Meshy + +This is also an invitation to participate - Meshery is a young, ambitious project - it requires a ton of work to make it what it aims to become. Integrating with all of the leading service mesh solutions asks for extensive expertise. In many areas Meshery's functionality is still young. But these are normal growth stages, aren't they? To put it simple - the community and the project need more hands! And these should be your hands! + +

    As already mentioned - Layer5 is a very welcoming bunch!

    + +Open source contributions are a must-do for becoming a true cloud native hero. Cloud native is all about the community and one can't be a part of a community by only taking and never giving back. So if you were looking for a promising and welcoming project to join - look no further! Hop on to Layer5 Slack and we'll happily embrace you and help you get started. + +And it's not only coding! Documentation, testing, UI design, logos, blogs, videos - you decide where to apply your talent. + +For example - I sometimes wish I had more time and motivation to code new Meshery features or fix existing bugs. But instead I'm writing this post. Because lately I enjoy writing texts more than coding. Coding for longer than a couple of days at a time throws me into a coding fatigue… Actually also many other activities do. I'm just not very good at keeping a routine. But I'm sure many of you out there aren't like me. So why not join forces? + +### Join the cloud native community! + +* Meshery is an exciting opportunity to learn more about service meshes. +* We're already on CNCF Landscape and are headed for the sandbox. +* Now is a great time to hop on board. Are you ready? Get into the mesh pit! + + +
    diff --git a/src/collections/blog/2020/2020-06-23-google-summer-of-code-2020-service-mesh-performance-with-envoy-nighthawk/index.mdx b/src/collections/blog/2020/2020-06-23-google-summer-of-code-2020-service-mesh-performance-with-envoy-nighthawk/index.mdx index 7762529fa91a..75cf323d9efb 100644 --- a/src/collections/blog/2020/2020-06-23-google-summer-of-code-2020-service-mesh-performance-with-envoy-nighthawk/index.mdx +++ b/src/collections/blog/2020/2020-06-23-google-summer-of-code-2020-service-mesh-performance-with-envoy-nighthawk/index.mdx @@ -1,56 +1,56 @@ ---- -title: "Google Summer of Code 2020: Service Mesh Performance with Envoy Nighthawk" -subtitle: "One of the greatest learning experiences yet." -date: 2020-06-23 10:30:05 -0530 -author: Kush Trivedi -thumbnail: ./gsoc-wide.webp -darkthumbnail: ./gsoc-wide.webp -category: Programs -tags: - - GSoC - - Programs - - Performance - - Nighthawk - - Service Mesh Performance -published: true -redirect_from: - - /blog/google-summer-of-code-2020-service-mesh-performance-with-envoy-nighthawk/ ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import gsocLogo from "./gsoc.webp"; -import { Link } from "gatsby"; - - - -

    How did it all start?

    -gsoc-image -

    -I was introduced to the Layer5 community by our very own Lee Calcote, and since then I have been exploring the vast world of service meshes and their performance characteristics. Before being accepted as a Google Summer of Code intern, I had been working with the Layer5 community as an active contributor, exploring various new DevOps tooling like service meshes, the sidecar concept, and performance benchmarking of services. I have had a run-in with the Kubernetes community before and initially believed Kubernetes to be the final stage of DevOps, but I was happily surprised when I found out that the end of Kubernetes merely marked the entrypoint to a whole new world of service meshes. -

    -

    -And so, we reach the beginning of my GSoC 2020 internship, which began on the night of May 3rd, 2020 when I learned that I had been selected as a GSoC Participant with the Cloud Native Computing Foundation (CNCF). Admittedly, I had tried my best an year ago to get into GSoC’19 with another organisation but due to reasons only Google can tell you, I was not accepted. Everything happens for a reason though, right? -Six months ago, if you would have told me that I would be working with service meshes, gRPC, load testing, performance benchmarking alongside prominent members of the open source world of Cloud Native, I would have ignored you with the least possible amount of prudence I could muster. -

    - -

    What is my project about?

    -

    -My GSoC project is to Enable Distributed Load Testing for various Service Mesh Planes using Envoy Nighthawk. For those who are not familiar with Nighthawk, it is a performance benchmark tool written and maintained by the Envoy community. We are in the process of incorporating Nighthawk into Meshery - the cloud native management plane.Meshery already supports performance testing of service meshes using fortio & wrk2 and is maintained by the Layer5 community and is also a member of CNCF Landscape. Alongside this effort, we are creating a new industry standard: Service Mesh Performance Specification which is another initiative of the Layer5 community to establish a common format for describing and capturing service mesh performance. -

    -

    -It has been a month since I have started my GSoC’20 tenure with the Layer5 community, and in this month, I have learned a lot from my code contributions and mentor. I began with setting up the project roadmap and discussing the potential use cases of Nighthawk with its maintainers during my community bonding period. I came to know some incredible people during the community bonding from big tech giants like Google, Facebook, Microsoft, Affirmed Networks, Red Hat and many more to list. Before incorporating Nighthawk, we had to make various enhancements in Meshery, like adding user preferences for performance settings, specifying the SMPS format for exporting and importing of load-test preferences, load-generator interface and more. -

    -

    -I have learned a hoard of new things, like gRPC services and how they communicate using protocol buffers, load generation using fortio, writing handlers for various endpoints using golang, and some frontend architecture with Nextjs. -

    - - -

    About the community

    -

    -Layer5 has one of the healthiest open source communities that I have ever worked with. In the past, I have worked with a variety of well-maintained and large scale open source communities but I have never experienced a more welcoming and nurturing environment than Layer5. At Layer5, we respect each contributor and their contributions, whether it is a new adapter or just a typo fix. If you can contribute, please do. It’s that simple! With many awesome initiatives like SMPS, Distributed Load Testing, Performance Benchmarking, Learn Layer5, and Image Hub, the exponential increase of Layer5 and its various projects is inevitable. -

    - - -_**P.S.: If these topics excite you and you want to explore the beautiful realm of service meshes, come and say "Hi" on our [Slack Channel](http://slack.layer5.io) and one of us will reach out to you!**_ - -
    +--- +title: "Google Summer of Code 2020: Service Mesh Performance with Envoy Nighthawk" +subtitle: "One of the greatest learning experiences yet." +date: 2020-06-23 10:30:05 -0530 +author: Kush Trivedi +thumbnail: ./gsoc-wide.webp +darkthumbnail: ./gsoc-wide.webp +category: Programs +tags: + - GSoC + - Programs + - Performance + - Nighthawk + - Service Mesh Performance +published: true +redirect_from: + - /blog/google-summer-of-code-2020-service-mesh-performance-with-envoy-nighthawk/ +--- + + +import gsocLogo from "./gsoc.webp"; + + + + +

    How did it all start?

    +gsoc-image +

    +I was introduced to the Layer5 community by our very own Lee Calcote, and since then I have been exploring the vast world of service meshes and their performance characteristics. Before being accepted as a Google Summer of Code intern, I had been working with the Layer5 community as an active contributor, exploring various new DevOps tooling like service meshes, the sidecar concept, and performance benchmarking of services. I have had a run-in with the Kubernetes community before and initially believed Kubernetes to be the final stage of DevOps, but I was happily surprised when I found out that the end of Kubernetes merely marked the entrypoint to a whole new world of service meshes. +

    +

    +And so, we reach the beginning of my GSoC 2020 internship, which began on the night of May 3rd, 2020 when I learned that I had been selected as a GSoC Participant with the Cloud Native Computing Foundation (CNCF). Admittedly, I had tried my best an year ago to get into GSoC’19 with another organisation but due to reasons only Google can tell you, I was not accepted. Everything happens for a reason though, right? +Six months ago, if you would have told me that I would be working with service meshes, gRPC, load testing, performance benchmarking alongside prominent members of the open source world of Cloud Native, I would have ignored you with the least possible amount of prudence I could muster. +

    + +

    What is my project about?

    +

    +My GSoC project is to Enable Distributed Load Testing for various Service Mesh Planes using Envoy Nighthawk. For those who are not familiar with Nighthawk, it is a performance benchmark tool written and maintained by the Envoy community. We are in the process of incorporating Nighthawk into Meshery - the cloud native management plane.Meshery already supports performance testing of service meshes using fortio & wrk2 and is maintained by the Layer5 community and is also a member of CNCF Landscape. Alongside this effort, we are creating a new industry standard: Service Mesh Performance Specification which is another initiative of the Layer5 community to establish a common format for describing and capturing service mesh performance. +

    +

    +It has been a month since I have started my GSoC’20 tenure with the Layer5 community, and in this month, I have learned a lot from my code contributions and mentor. I began with setting up the project roadmap and discussing the potential use cases of Nighthawk with its maintainers during my community bonding period. I came to know some incredible people during the community bonding from big tech giants like Google, Facebook, Microsoft, Affirmed Networks, Red Hat and many more to list. Before incorporating Nighthawk, we had to make various enhancements in Meshery, like adding user preferences for performance settings, specifying the SMPS format for exporting and importing of load-test preferences, load-generator interface and more. +

    +

    +I have learned a hoard of new things, like gRPC services and how they communicate using protocol buffers, load generation using fortio, writing handlers for various endpoints using golang, and some frontend architecture with Nextjs. +

    + + +

    About the community

    +

    +Layer5 has one of the healthiest open source communities that I have ever worked with. In the past, I have worked with a variety of well-maintained and large scale open source communities but I have never experienced a more welcoming and nurturing environment than Layer5. At Layer5, we respect each contributor and their contributions, whether it is a new adapter or just a typo fix. If you can contribute, please do. It’s that simple! With many awesome initiatives like SMPS, Distributed Load Testing, Performance Benchmarking, Learn Layer5, and Image Hub, the exponential increase of Layer5 and its various projects is inevitable. +

    + + +_**P.S.: If these topics excite you and you want to explore the beautiful realm of service meshes, come and say "Hi" on our [Slack Channel](http://slack.layer5.io) and one of us will reach out to you!**_ + +
    diff --git a/src/collections/blog/2020/2020-06-25-SMI-conformance-testing-with-meshery/index.mdx b/src/collections/blog/2020/2020-06-25-SMI-conformance-testing-with-meshery/index.mdx index 7ce9bd56fc1a..67b9a9ca0ac1 100644 --- a/src/collections/blog/2020/2020-06-25-SMI-conformance-testing-with-meshery/index.mdx +++ b/src/collections/blog/2020/2020-06-25-SMI-conformance-testing-with-meshery/index.mdx @@ -1,81 +1,81 @@ ---- -title: "Starting SMI Conformance Testing with Meshery" -subtitle: "" -date: 2020-06-25 10:30:05 -0530 -author: Naveen Kumar -thumbnail: ./smi-conformance.svg -darkthumbnail: ./smi-conformance.svg -category: Programs -tags: - - Community - - Programs - - "Service Mesh Interface" -published: true -type: Blog -product: Meshery -resource: true -redirect_from: - - /blog/community/SMI-conformance-testing-with-meshery/ - - /blog/community/blog/smi-conformance-testing-with-meshery/ - - /blog/smi-conformance-testing-with-meshery/ ---- -import { Link } from "gatsby"; -import { BlogWrapper } from "../../Blog.style.js"; -import smilogo from "./smi-logo.webp"; -import checklist from "./checklist.svg" - - - -smilogo - -### About SMI - -The Service Mesh Interface (SMI) is a specification for service meshes that run on Kubernetes. It utilizes CRDs to modify the behavior of service meshes. The project is under development at [SMI Github Repository](https://github.com/servicemeshinterface/smi-spec). Please visit the github repository page to know the latest advancements in the characteristics. The complete spec can be found [here](https://github.com/servicemeshinterface/smi-spec/blob/master/SPEC.md). - -### APIs in SMI - -Currently SMI supports 4 set of APIs: - -- [Traffic Specs](https://github.com/servicemeshinterface/smi-spec/blob/master/SPEC.md#traffic-specs) - Used to define traffic, currently only supports TCP, HTTP traffic. -- [Traffic Access Control](https://github.com/servicemeshinterface/smi-spec/blob/master/SPEC.md#traffic-access-control) - Used to specify whether a particular form of traffic is allowed or not -- [Traffic Split](https://github.com/servicemeshinterface/smi-spec/blob/master/SPEC.md#traffic-split) - Used to redirect/divide a request for a resource between 2 or more resources. Useful in canary testing -- [Traffic Metrics](https://github.com/servicemeshinterface/smi-spec/blob/master/SPEC.md#traffic-metrics) - Used to expose common traffic metrics like p99 in a specific format that can be utilized by single dashboard for all the service meshes. - -### About SMI Conformance Tests - -**SMI Conformance Tests** check whether the service mesh that is installed in the kubernetes cluster, conforms to SMI specs or not. This involves asking some major questions. Does it have the required CRDs? Do these CRDs perform as they should when applied or not applied? Are we able to get metrics in a proper format? - -All these questions will be answered by SMI conformance tests. The biggest benefit of your service mesh conforming to SMI is that it makes building tools an easier process.Also, one time development of any tool would in turn support all the meshes that conform to SMI. - -Sounds fun, right? Let's dig deeper into the SMI conformance project and find out. - -### Meshery'ing with Conformance Tests - -checklist - -Meshery is _the cloud native management plane__. It supports all the popular meshes, teaches you how to manage them, assists you in applying custom or recommended configurations, tests for compatibility, performs performance tests for meshes and a lot more. The SMI conformance testing requires performance testing capabilities, load generation (Meshery is about to support distributed load generation as well), and other functionalities such that these conformance tests can be easily used in the pipelines of all the popular service meshes. mesheryctl does have a perf command that can be used in the pipelines of service meshes. I aim at making such capabilities for SMI conformance as well. - -As you have made your way halfway through the post (thank you for your patience), you should now be aware of SMI, its conformance practices and how Meshery’s incredible engineering can be utilized for conformance tests. We can now tackle the larger questions and hope to see the bigger picture. - -### The Bigger Picture - -Do you know that almost all of the test cases that we would write in this project would be raw YAML files? To those doing traditional unit and integration tests, we might sound unhinged at this point. We assure you that we are completely sober and serious (if you don’t count the temporary euphoria from geeky jokes). - -#### Forking [kuttl](https://kuttl.dev/) - -`kuttl` is a tool for writing tests against Kubernetes operators and controllers. It can ascertain whether any kind of resources exist or not in the Kubernetes cluster, spring up a kind cluster and do other convenient things. Another plus is that It's entirely declarative. Consider a scenario in which we have a special use case where we wanted to run some go code after each individual step in the test case was executed. To accomplish this, we forked `kuttl` and modified it a little. You can see our modified version [here](https://github.com/kanishkarj/kuttl). - - -We are planning to use `kuttl` for all the APIs in SMI. We are also planning to use the Meshery load generator with the modified version of `kuttl`. - -#### [Learn Layer5](https://github.com/layer5io/learn-layer5/) - -Learn Layer5 is a sample app which is very lightweight and simple to deploy. It is a simple sample app for learning about service meshes. We are planning to use the same app for testing for SMI conformance. The app is deployed when we test for SMI conformance and traffic is generated from one service/deployment/pod to another. This is a great tool for playing around with service meshes and the tools provided by Layer5 and its projects without investing any personal resources. - -This is where all the test cases along with the code will be placed. Currently, there is a large overlap in the learn-layer5 and `smi-conformance` testing files. All those changes will be transferred here. - -If any of this sounds remotely exciting, I implore you to give this a chance. You won’t regret it. -Head over to our [Slack Channel](http://slack.layer5.io) and join the #smi channel where everything related to conformance testing is discussed. We would love to hear your feedback. Stay tuned for more blogs related to SMI Conformance and all things meshy!!! - - - +--- +title: "Starting SMI Conformance Testing with Meshery" +subtitle: "" +date: 2020-06-25 10:30:05 -0530 +author: Naveen Kumar +thumbnail: ./smi-conformance.svg +darkthumbnail: ./smi-conformance.svg +category: Programs +tags: + - Community + - Programs + - "Service Mesh Interface" +published: true +type: Blog +product: Meshery +resource: true +redirect_from: + - /blog/community/SMI-conformance-testing-with-meshery/ + - /blog/community/blog/smi-conformance-testing-with-meshery/ + - /blog/smi-conformance-testing-with-meshery/ +--- + + +import smilogo from "./smi-logo.webp"; +import checklist from "./checklist.svg" + + + +smilogo + +### About SMI + +The Service Mesh Interface (SMI) is a specification for service meshes that run on Kubernetes. It utilizes CRDs to modify the behavior of service meshes. The project is under development at [SMI Github Repository](https://github.com/servicemeshinterface/smi-spec). Please visit the github repository page to know the latest advancements in the characteristics. The complete spec can be found [here](https://github.com/servicemeshinterface/smi-spec/blob/master/SPEC.md). + +### APIs in SMI + +Currently SMI supports 4 set of APIs: + +- [Traffic Specs](https://github.com/servicemeshinterface/smi-spec/blob/master/SPEC.md#traffic-specs) - Used to define traffic, currently only supports TCP, HTTP traffic. +- [Traffic Access Control](https://github.com/servicemeshinterface/smi-spec/blob/master/SPEC.md#traffic-access-control) - Used to specify whether a particular form of traffic is allowed or not +- [Traffic Split](https://github.com/servicemeshinterface/smi-spec/blob/master/SPEC.md#traffic-split) - Used to redirect/divide a request for a resource between 2 or more resources. Useful in canary testing +- [Traffic Metrics](https://github.com/servicemeshinterface/smi-spec/blob/master/SPEC.md#traffic-metrics) - Used to expose common traffic metrics like p99 in a specific format that can be utilized by single dashboard for all the service meshes. + +### About SMI Conformance Tests + +**SMI Conformance Tests** check whether the service mesh that is installed in the kubernetes cluster, conforms to SMI specs or not. This involves asking some major questions. Does it have the required CRDs? Do these CRDs perform as they should when applied or not applied? Are we able to get metrics in a proper format? + +All these questions will be answered by SMI conformance tests. The biggest benefit of your service mesh conforming to SMI is that it makes building tools an easier process.Also, one time development of any tool would in turn support all the meshes that conform to SMI. + +Sounds fun, right? Let's dig deeper into the SMI conformance project and find out. + +### Meshery'ing with Conformance Tests + +checklist + +Meshery is _the cloud native management plane__. It supports all the popular meshes, teaches you how to manage them, assists you in applying custom or recommended configurations, tests for compatibility, performs performance tests for meshes and a lot more. The SMI conformance testing requires performance testing capabilities, load generation (Meshery is about to support distributed load generation as well), and other functionalities such that these conformance tests can be easily used in the pipelines of all the popular service meshes. mesheryctl does have a perf command that can be used in the pipelines of service meshes. I aim at making such capabilities for SMI conformance as well. + +As you have made your way halfway through the post (thank you for your patience), you should now be aware of SMI, its conformance practices and how Meshery’s incredible engineering can be utilized for conformance tests. We can now tackle the larger questions and hope to see the bigger picture. + +### The Bigger Picture + +Do you know that almost all of the test cases that we would write in this project would be raw YAML files? To those doing traditional unit and integration tests, we might sound unhinged at this point. We assure you that we are completely sober and serious (if you don’t count the temporary euphoria from geeky jokes). + +#### Forking [kuttl](https://kuttl.dev/) + +`kuttl` is a tool for writing tests against Kubernetes operators and controllers. It can ascertain whether any kind of resources exist or not in the Kubernetes cluster, spring up a kind cluster and do other convenient things. Another plus is that It's entirely declarative. Consider a scenario in which we have a special use case where we wanted to run some go code after each individual step in the test case was executed. To accomplish this, we forked `kuttl` and modified it a little. You can see our modified version [here](https://github.com/kanishkarj/kuttl). + + +We are planning to use `kuttl` for all the APIs in SMI. We are also planning to use the Meshery load generator with the modified version of `kuttl`. + +#### [Learn Layer5](https://github.com/layer5io/learn-layer5/) + +Learn Layer5 is a sample app which is very lightweight and simple to deploy. It is a simple sample app for learning about service meshes. We are planning to use the same app for testing for SMI conformance. The app is deployed when we test for SMI conformance and traffic is generated from one service/deployment/pod to another. This is a great tool for playing around with service meshes and the tools provided by Layer5 and its projects without investing any personal resources. + +This is where all the test cases along with the code will be placed. Currently, there is a large overlap in the learn-layer5 and `smi-conformance` testing files. All those changes will be transferred here. + +If any of this sounds remotely exciting, I implore you to give this a chance. You won’t regret it. +Head over to our [Slack Channel](http://slack.layer5.io) and join the #smi channel where everything related to conformance testing is discussed. We would love to hear your feedback. Stay tuned for more blogs related to SMI Conformance and all things meshy!!! + + + diff --git a/src/collections/blog/2020/2020-07-03-my-meshy-journey/index.mdx b/src/collections/blog/2020/2020-07-03-my-meshy-journey/index.mdx index 22608bd770af..f17b5078b9c2 100644 --- a/src/collections/blog/2020/2020-07-03-my-meshy-journey/index.mdx +++ b/src/collections/blog/2020/2020-07-03-my-meshy-journey/index.mdx @@ -1,51 +1,51 @@ ---- -title: "My Meshy Journey" -subtitle: "" -date: 2020-07-03 12:15:05 +0000 -author: Ishita Kumar -thumbnail: ./ishita-kumar.webp -darkthumbnail: ./ishita-kumar.webp -category: Internship Programs -tags: - - Community -published: true ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import IshitaProfile from "./ishita-kumar-profile.webp"; - - - -Ishita Kumar Profile - -As a graduate student at the Indiana University Bloomington, studying for my Masters in Computer Science, little did I consider that my thesis project would lead me on this amazing journey to becoming an open source contributor. - -My adventure with Layer5 has been a highly informative and invigorating experience, from coming aboard as a Meshery user to becoming an open source contributor. My initial interest in Layer5 was sparked when, for a project in my Masters course, I was required to build a microservice architecture and develop a service layer on top of it. -A basic Google search led me to a plethora of resources, which in turn led me to understand how different service meshes could be compared. Comparison and selection of a service mesh was my first step to deploying one on my VM cluster. Amidst the varied resources available to me, stumbling onto Layer5 and Meshery was a happy boon. - -## Why Meshery? - -From the beginning, Meshery proved to be an intuitive and easy-to-use application. Among other benefits, it could be implemented into my project with ease which was also a major contributing factor behind my choice of taking advantage of its features for my project thesis. -There are tons of resources online that compare different service meshes for your deployment however meshery was the only project that actually offered a practical way of comparing service meshes. In just a few easy steps, I could download and deploy Meshery into my VM instance and compare the performance of my microservice application running atop two different service meshes: Istio and Linkerd, thereby gathering various statistics on how they worked on my application. - -What really got my hooked though was Meshery's intuitive UI and the amazing open platform support, which made me strive to rise above and beyond my project goals, to truly understand and value the underlying idea. - -## Insights While Meshing Around - -While using Meshery to deploy both Istio and Linkerd, I came to the understanding that while Meshery uses common methods for interfacing with and managing service meshes, that Meshery is also capable of exposing service mesh-specific features. This became apparent by how robust Meshery’s adapter for Istio is, which includes the ability to analyze and validate my deployment’s configuration against best practices. Each adapter includes a set of sample applications that makes it convenient to explore the functionality of different meshes, using the same application across them. - -The behavior that was of keen interest to me, however, was that of my custom, microservices. When deploying my microservices application, Meshery helped me understand how different service meshes were interacting with my software application. - -I learned that in addition to the easy integration of Meshery in my application, it also provides one of the best platforms out there to manage service meshes and gives you a fair assessment of your deployment, which can otherwise prove to be a daunting task. - -While presenting my findings to my class and professor, they were able to gauge the brilliancy each service mesh would bring into the microservice application. - -## Shout out to the Community - -The Layer5 community has proved to be incredibly helpful in my journey. Communicating mainly through Slack channels, the community is vibrant and very welcoming. Any integration issues that arose for me were quickly and efficiently solved.
    -I am thankful that my experiences as a user, as well as a contributor, has allowed me to be a valued part of this wholesome group. Layer5 has truly made me understand the significance of an open source "community" and I’ll admit - I’m hooked. The number and variety of novel projects that are pushing the envelope of emerging technology within this community is enthralling.
    -I’m here for the long-haul, so expect to hear from me again as I wrap my arms around these projects. If the suite of Layer5 projects interests you, please [join the community](http://slack.layer5.io)!
    -Then, drop me a line as I work toward becoming a [MeshMate](https://layer5.io/community/meshmates). - - -
    +--- +title: "My Meshy Journey" +subtitle: "" +date: 2020-07-03 12:15:05 +0000 +author: Ishita Kumar +thumbnail: ./ishita-kumar.webp +darkthumbnail: ./ishita-kumar.webp +category: Internship Programs +tags: + - Community +published: true +--- + + +import IshitaProfile from "./ishita-kumar-profile.webp"; + + + +Ishita Kumar Profile + +As a graduate student at the Indiana University Bloomington, studying for my Masters in Computer Science, little did I consider that my thesis project would lead me on this amazing journey to becoming an open source contributor. + +My adventure with Layer5 has been a highly informative and invigorating experience, from coming aboard as a Meshery user to becoming an open source contributor. My initial interest in Layer5 was sparked when, for a project in my Masters course, I was required to build a microservice architecture and develop a service layer on top of it. +A basic Google search led me to a plethora of resources, which in turn led me to understand how different service meshes could be compared. Comparison and selection of a service mesh was my first step to deploying one on my VM cluster. Amidst the varied resources available to me, stumbling onto Layer5 and Meshery was a happy boon. + +## Why Meshery? + +From the beginning, Meshery proved to be an intuitive and easy-to-use application. Among other benefits, it could be implemented into my project with ease which was also a major contributing factor behind my choice of taking advantage of its features for my project thesis. +There are tons of resources online that compare different service meshes for your deployment however meshery was the only project that actually offered a practical way of comparing service meshes. In just a few easy steps, I could download and deploy Meshery into my VM instance and compare the performance of my microservice application running atop two different service meshes: Istio and Linkerd, thereby gathering various statistics on how they worked on my application. + +What really got my hooked though was Meshery's intuitive UI and the amazing open platform support, which made me strive to rise above and beyond my project goals, to truly understand and value the underlying idea. + +## Insights While Meshing Around + +While using Meshery to deploy both Istio and Linkerd, I came to the understanding that while Meshery uses common methods for interfacing with and managing service meshes, that Meshery is also capable of exposing service mesh-specific features. This became apparent by how robust Meshery’s adapter for Istio is, which includes the ability to analyze and validate my deployment’s configuration against best practices. Each adapter includes a set of sample applications that makes it convenient to explore the functionality of different meshes, using the same application across them. + +The behavior that was of keen interest to me, however, was that of my custom, microservices. When deploying my microservices application, Meshery helped me understand how different service meshes were interacting with my software application. + +I learned that in addition to the easy integration of Meshery in my application, it also provides one of the best platforms out there to manage service meshes and gives you a fair assessment of your deployment, which can otherwise prove to be a daunting task. + +While presenting my findings to my class and professor, they were able to gauge the brilliancy each service mesh would bring into the microservice application. + +## Shout out to the Community + +The Layer5 community has proved to be incredibly helpful in my journey. Communicating mainly through Slack channels, the community is vibrant and very welcoming. Any integration issues that arose for me were quickly and efficiently solved.
    +I am thankful that my experiences as a user, as well as a contributor, has allowed me to be a valued part of this wholesome group. Layer5 has truly made me understand the significance of an open source "community" and I’ll admit - I’m hooked. The number and variety of novel projects that are pushing the envelope of emerging technology within this community is enthralling.
    +I’m here for the long-haul, so expect to hear from me again as I wrap my arms around these projects. If the suite of Layer5 projects interests you, please [join the community](http://slack.layer5.io)!
    +Then, drop me a line as I work toward becoming a [MeshMate](https://layer5.io/community/meshmates). + + +
    diff --git a/src/collections/blog/2020/2020-07-16-communitybridge-2020-teaching-service-meshes-to-be-compliant/index.mdx b/src/collections/blog/2020/2020-07-16-communitybridge-2020-teaching-service-meshes-to-be-compliant/index.mdx index d8f5f3aff8cb..9c492cdb9b99 100644 --- a/src/collections/blog/2020/2020-07-16-communitybridge-2020-teaching-service-meshes-to-be-compliant/index.mdx +++ b/src/collections/blog/2020/2020-07-16-communitybridge-2020-teaching-service-meshes-to-be-compliant/index.mdx @@ -1,72 +1,72 @@ ---- -title: "CommunityBridge 2020: Teaching service meshes to be compliant" -subtitle: "" -date: 2020-07-16 10:30:05 -0530 -author: Kanishkar J -thumbnail: ./communitybridge.webp -darkthumbnail: ./communitybridge.webp -category: Internship Programs -tags: - - Programs - - "Service Mesh Interface" - - "Internship" -published: true -redirect_from: - - /blog/programs/community/communitybridge-2020-teaching-service-meshes-to-be-compliant - - /blog/programs/communitybridge-2020-teaching-service-meshes-to-be-compliant - - /blog/community-bridge-with-layer5/ ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import cblogo from "./cblogo.webp"; -import smiLogo from "./smi.webp"; - - - -community-bridge-logo - -My journey into service meshes began on April 27, 2020 when I was selected to be a mentee under the banner of Community Bridge for the Summer of 2020. The Community Bridge Mentorship is a structured remote learning opportunity for aspiring open source software developers. The projects they host are mentored by experienced open source project developers and maintainers. - -

    Stumbling into Service Mesh Interface (SMI)

    - -I began working on SMI Conformance testing under the guidance of Lee Calcote, Founder of Layer5, in February 2020. Since then, my path into the world of service meshes has brought me an avalanche of opportunities and has helped me grow by leaps and bounds as a developer. -The Service Mesh Interface (SMI) is a standard interface that encapsulates various common service mesh functionalities. It explains several Custom Resource Definitions (CRDs), their configuration variables, and their corresponding effect on the service mesh underneath in full detail. What makes SMI vital is that these CRDs are generic, and the specifications are implemented and actively followed up by various service meshes. Some of these service meshes have developed adapters that define SMI CRDs as a wrapper over the APIs they already provide, instead of adhering to the SMI spec internally. SMI specifications address essential features for the most common service mesh use cases: - -smi-logo - -- Traffic policy – To apply policies like identity and transport encryption across services -- Traffic telemetry – To capture key metrics like error rate and latency between services -- Traffic management – To shift traffic between different services - -However, at the moment, no service meshes adhere to the SMI specifications completely. Service meshes are rapidly developing and making active efforts to extend their feature set. Simultaneously, SMI has also been working towards adding more features to its specifications. - -Consequently, it becomes a necessity for continual validation of service mesh conformance with respect to SMI specifications and the various versions of those specifications. The process of verifying conformance needs to be standardized and tooling made available. Hence, our project efforts to create an SMI conformance tool. - -

    Meshery to the Rescue

    - -Meshery is the multi-service mesh management plane, offering lifecycle, configuration, and performance management of service meshes and their workloads. It is closely connected to the Kubernetes cluster and allows easy deployment of various service meshes and sample applications onto those meshes. Meshery enables operators to run performance tests on workloads, collect, store, and manage the test results. - - -We had found our solution. By leveraging the features provided in Meshery, we would be able to focus on the conformance validation and testing instead of sweating over the complexity in deployments. We can also use the performance management infrastructure to manage the conformance tests and their results. And so, the tool will be developed as an integral part of Meshery to aid and abate SMI conformance woes. -We are now enhancing Meshery to automate the process of verifying conformance against a standard set of tests against a sample workload designed specifically for SMI conformance testing. By the time we’re through, this capability of Meshery will allow each service mesh project to validate its conformance to each version of the SMI specifications and will provide a detailed report. - -

    My Projects

    - -The goals accomplished in my tenure at Layer5 are summarized as follows: - -1. **[Meshery Providers](https://docs.meshery.io/extensibility)** - Ported Meshery and its remote provider from using session based authentication to JWT based auth. This opened doors to: - - Usage of refresh tokens for longevity of sessions instead of asking user to re-login frequently. - - CLI based authentication (not done yet, but is on the roadmap) -2. **[Image Hub](https://github.com/layer5io/image-hub)** - WASM based envoy network packet filters in Rust-lang. Built a demo app demonstrating its potentials; we also built a WASM filter which performs custom user specific rate limiting. This app was demo’ed in Dockercon 2020 under the header “Service Meshing with Docker Desktop and WebAssembly”. -3. **[Implementing the Service Mesh Performance Specification](/projects/cloud-native-performance)** - Enhanced Meshery’s performance testing and profile management capabilities. Added support for customizing the requests made by the load generator, and added the capability of using performance test profiles in the tool. - -You can find my code in the [**Learn Layer5 repository**](https://github.com/layer5io/learn-layer5/). - -

    Love for the Community

    - -I have been actively involved in the Layer5 community for a number of months now and am proud of the contributions I have made to various projects under the Layer5 banner. The Layer5 community represents an eclectic mix of geeky developers, out of the box thinkers, sassy writers and some of the most amazing people I have met so far in the open source community. We build projects to provide learning environments, deployment, and operational best practices, performance benchmarks, create documentation, and more. I am truly ecstatic to be a part of such an enthusiastic and welcoming community.
    - -As you’ve made it to the end of my post, why not stick around and take a look at the amazing projects I just described? You might just find your dream project and if not, I can promise that you will at least end up becoming a part of one of the best open source communities out there.
    -To stay tuned with the progress of the project, please join us in the [Slack](http://slack.layer5.io) channel! - -
    +--- +title: "CommunityBridge 2020: Teaching service meshes to be compliant" +subtitle: "" +date: 2020-07-16 10:30:05 -0530 +author: Kanishkar J +thumbnail: ./communitybridge.webp +darkthumbnail: ./communitybridge.webp +category: Internship Programs +tags: + - Programs + - "Service Mesh Interface" + - "Internship" +published: true +redirect_from: + - /blog/programs/community/communitybridge-2020-teaching-service-meshes-to-be-compliant + - /blog/programs/communitybridge-2020-teaching-service-meshes-to-be-compliant + - /blog/community-bridge-with-layer5/ +--- + + +import cblogo from "./cblogo.webp"; +import smiLogo from "./smi.webp"; + + + +community-bridge-logo + +My journey into service meshes began on April 27, 2020 when I was selected to be a mentee under the banner of Community Bridge for the Summer of 2020. The Community Bridge Mentorship is a structured remote learning opportunity for aspiring open source software developers. The projects they host are mentored by experienced open source project developers and maintainers. + +

    Stumbling into Service Mesh Interface (SMI)

    + +I began working on SMI Conformance testing under the guidance of Lee Calcote, Founder of Layer5, in February 2020. Since then, my path into the world of service meshes has brought me an avalanche of opportunities and has helped me grow by leaps and bounds as a developer. +The Service Mesh Interface (SMI) is a standard interface that encapsulates various common service mesh functionalities. It explains several Custom Resource Definitions (CRDs), their configuration variables, and their corresponding effect on the service mesh underneath in full detail. What makes SMI vital is that these CRDs are generic, and the specifications are implemented and actively followed up by various service meshes. Some of these service meshes have developed adapters that define SMI CRDs as a wrapper over the APIs they already provide, instead of adhering to the SMI spec internally. SMI specifications address essential features for the most common service mesh use cases: + +smi-logo + +- Traffic policy – To apply policies like identity and transport encryption across services +- Traffic telemetry – To capture key metrics like error rate and latency between services +- Traffic management – To shift traffic between different services + +However, at the moment, no service meshes adhere to the SMI specifications completely. Service meshes are rapidly developing and making active efforts to extend their feature set. Simultaneously, SMI has also been working towards adding more features to its specifications. + +Consequently, it becomes a necessity for continual validation of service mesh conformance with respect to SMI specifications and the various versions of those specifications. The process of verifying conformance needs to be standardized and tooling made available. Hence, our project efforts to create an SMI conformance tool. + +

    Meshery to the Rescue

    + +Meshery is the multi-service mesh management plane, offering lifecycle, configuration, and performance management of service meshes and their workloads. It is closely connected to the Kubernetes cluster and allows easy deployment of various service meshes and sample applications onto those meshes. Meshery enables operators to run performance tests on workloads, collect, store, and manage the test results. + + +We had found our solution. By leveraging the features provided in Meshery, we would be able to focus on the conformance validation and testing instead of sweating over the complexity in deployments. We can also use the performance management infrastructure to manage the conformance tests and their results. And so, the tool will be developed as an integral part of Meshery to aid and abate SMI conformance woes. +We are now enhancing Meshery to automate the process of verifying conformance against a standard set of tests against a sample workload designed specifically for SMI conformance testing. By the time we’re through, this capability of Meshery will allow each service mesh project to validate its conformance to each version of the SMI specifications and will provide a detailed report. + +

    My Projects

    + +The goals accomplished in my tenure at Layer5 are summarized as follows: + +1. **[Meshery Providers](https://docs.meshery.io/extensibility)** - Ported Meshery and its remote provider from using session based authentication to JWT based auth. This opened doors to: + - Usage of refresh tokens for longevity of sessions instead of asking user to re-login frequently. + - CLI based authentication (not done yet, but is on the roadmap) +2. **[Image Hub](https://github.com/layer5io/image-hub)** - WASM based envoy network packet filters in Rust-lang. Built a demo app demonstrating its potentials; we also built a WASM filter which performs custom user specific rate limiting. This app was demo’ed in Dockercon 2020 under the header “Service Meshing with Docker Desktop and WebAssembly”. +3. **[Implementing the Service Mesh Performance Specification](/projects/cloud-native-performance)** - Enhanced Meshery’s performance testing and profile management capabilities. Added support for customizing the requests made by the load generator, and added the capability of using performance test profiles in the tool. + +You can find my code in the [**Learn Layer5 repository**](https://github.com/layer5io/learn-layer5/). + +

    Love for the Community

    + +I have been actively involved in the Layer5 community for a number of months now and am proud of the contributions I have made to various projects under the Layer5 banner. The Layer5 community represents an eclectic mix of geeky developers, out of the box thinkers, sassy writers and some of the most amazing people I have met so far in the open source community. We build projects to provide learning environments, deployment, and operational best practices, performance benchmarks, create documentation, and more. I am truly ecstatic to be a part of such an enthusiastic and welcoming community.
    + +As you’ve made it to the end of my post, why not stick around and take a look at the amazing projects I just described? You might just find your dream project and if not, I can promise that you will at least end up becoming a part of one of the best open source communities out there.
    +To stay tuned with the progress of the project, please join us in the [Slack](http://slack.layer5.io) channel! + +
    diff --git a/src/collections/blog/2020/2020-07-16-growing-as-an-open-source-contributor-with-layer5/index.mdx b/src/collections/blog/2020/2020-07-16-growing-as-an-open-source-contributor-with-layer5/index.mdx index 2af2109366bf..c72f39832964 100644 --- a/src/collections/blog/2020/2020-07-16-growing-as-an-open-source-contributor-with-layer5/index.mdx +++ b/src/collections/blog/2020/2020-07-16-growing-as-an-open-source-contributor-with-layer5/index.mdx @@ -1,56 +1,56 @@ ---- -title: "Growing as an open source contributor with Layer5" -subtitle: "" -date: 2020-07-16 10:30:06 -0530 -author: Ashis Kumar Singh -thumbnail: ./the-enterprise-path-to-service-mesh-book-signed-by-lee-calcote.webp -darkthumbnail: ./the-enterprise-path-to-service-mesh-book-signed-by-lee-calcote.webp -category: Community -tags: - - Community -published: true ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import pic1 from "./pic1.webp"; -import pic2 from "./pic2.jpeg"; -import pic3 from "./pic3.webp"; -import pic4 from "./pic4.webp"; -import pic5 from "./pic5.webp"; - - -It all started 9 months ago when I stumbled across the following LinkedIn post, written by a college senior who had recently scored an internship with Redhat. - -book - -This led me to a long-winding conversation with Subham Kumar Rai and Anand Kumar Singh about Layer5 and how amazing an opportunity it would be to be a part of this emerging community. I did some research on service meshes and made my way to the Layer5 Github repo. From there, it was a swift journey to the Layer5 Slack Channel where I truly understood what Subham had meant about the warm welcome. I was amazed by how helpful and willing the entire community was. Armed with the resources I needed, I delved into the projects and churned out a few PRs and I was hooked. I dove aggressively into the projects and handled any curve balls with the help of my mentors. My participation in the Layer5 community drove me to a well earned obsession with open source projects which led me to make my own contributions in the FOSSASIA and GATSBY projects and take part in many open-source contests such as Hacktoberfest, DevopsCember, Kharagpur Winter Of Code (KWOC), NJACK Winter Of Code (NWOC), Girlscript Summer Of Code (GSSOC). - -github-profile - -#### What is Meshery? - -Meshery is a multi-service mesh management plane that offers lifecycle, configuration, and performance management of service meshes and applications running on top of those meshes.
    - -meshry - -Meshery uses a common service mesh performance specification to describe and capture performance benchmarks and results. The spec contains general information about the performance test (e.g. start/end times), service mesh and proxy build numbers, Kubernetes cluster details (nodes, type of nodes, memory information), and the actual results. One of the ideas behind Meshery is to be a vendor and project-neutral tool that can benchmark the performance of different service meshes.
    -It is a one stop for all your service meshing needs. Service meshes are still a novel concept for both, developers and users. Meshery steps in to bridge this gap and allows you to have a better understanding of what a service mesh can provide by helping you judge service mesh for your personal and professional needs. Meshery accomplishes this by providing you a thorough analysis of the options available so that you can make an informed choice.
    - -Lee Calcote - -#### Lee Calcote - -Lee Calcote is an innovative leader and has previously made waves in the tech community as a Docker Captain and a Cloud Native Ambassador and that is just a milestone in his impressive journey, which consists of his admirable work with developer platforms, cloud technology, containers, functions, and applications. Advanced and emerging technologies have been a consistent focus through Calcote’s tenure at SolarWinds, Seagate, Cisco, and Pelco. In my tenure at Layer5, Lee has been an amazing mentor, someone you can always look towards for encouragement, inspiration and a kind word, especially when you’re melting under the heat to make that late night deadline. - - -#### Layer5 and UEM Jaipur Partnership Program -In an effort to foster the open source community in my college, I along with four of my batchmates (Anand, Subham, Nikhil, Gunjan) decided to start an open source partnership program, encouraged by Lee and Rupayan Das (Faculty, UEM Jaipur). This will hopefully lead to making future batches more aware about the essence of open source and encourage them to participate in communities like Layer5. - -layer5 - -#### Community Love - -The Layer5 community has welcomed me with patience and has given me a sense of purpose, which is more than I could have asked for at the beginning as a novice developer. The warm welcome and a sincere string of mentors can do wonders in building your confidence and enabling you to put in your best foot forward. Open source has introduced me to a horde of essential qualities, such as the importance of teamwork, candor and earnestness.
    -It has been a prodigious journey so far and I don’t intend to stop here. The pace at which the projects under the Layer5 community are unwinding is awe-inspiring. It is my aim to be a witness and a partner in crime in its future endeavors. If you’re looking for an opportunity to be a part of the Layer5 family, check out our projects and head over to our [Slack](http://slack.layer5.io) channel! - -
    +--- +title: "Growing as an open source contributor with Layer5" +subtitle: "" +date: 2020-07-16 10:30:06 -0530 +author: Ashis Kumar Singh +thumbnail: ./the-enterprise-path-to-service-mesh-book-signed-by-lee-calcote.webp +darkthumbnail: ./the-enterprise-path-to-service-mesh-book-signed-by-lee-calcote.webp +category: Community +tags: + - Community +published: true +--- + + +import pic1 from "./pic1.webp"; +import pic2 from "./pic2.jpeg"; +import pic3 from "./pic3.webp"; +import pic4 from "./pic4.webp"; +import pic5 from "./pic5.webp"; + + +It all started 9 months ago when I stumbled across the following LinkedIn post, written by a college senior who had recently scored an internship with Redhat. + +book + +This led me to a long-winding conversation with Subham Kumar Rai and Anand Kumar Singh about Layer5 and how amazing an opportunity it would be to be a part of this emerging community. I did some research on service meshes and made my way to the Layer5 Github repo. From there, it was a swift journey to the Layer5 Slack Channel where I truly understood what Subham had meant about the warm welcome. I was amazed by how helpful and willing the entire community was. Armed with the resources I needed, I delved into the projects and churned out a few PRs and I was hooked. I dove aggressively into the projects and handled any curve balls with the help of my mentors. My participation in the Layer5 community drove me to a well earned obsession with open source projects which led me to make my own contributions in the FOSSASIA and GATSBY projects and take part in many open-source contests such as Hacktoberfest, DevopsCember, Kharagpur Winter Of Code (KWOC), NJACK Winter Of Code (NWOC), Girlscript Summer Of Code (GSSOC). + +github-profile + +#### What is Meshery? + +Meshery is a multi-service mesh management plane that offers lifecycle, configuration, and performance management of service meshes and applications running on top of those meshes.
    + +meshry + +Meshery uses a common service mesh performance specification to describe and capture performance benchmarks and results. The spec contains general information about the performance test (e.g. start/end times), service mesh and proxy build numbers, Kubernetes cluster details (nodes, type of nodes, memory information), and the actual results. One of the ideas behind Meshery is to be a vendor and project-neutral tool that can benchmark the performance of different service meshes.
    +It is a one stop for all your service meshing needs. Service meshes are still a novel concept for both, developers and users. Meshery steps in to bridge this gap and allows you to have a better understanding of what a service mesh can provide by helping you judge service mesh for your personal and professional needs. Meshery accomplishes this by providing you a thorough analysis of the options available so that you can make an informed choice.
    + +Lee Calcote + +#### Lee Calcote + +Lee Calcote is an innovative leader and has previously made waves in the tech community as a Docker Captain and a Cloud Native Ambassador and that is just a milestone in his impressive journey, which consists of his admirable work with developer platforms, cloud technology, containers, functions, and applications. Advanced and emerging technologies have been a consistent focus through Calcote’s tenure at SolarWinds, Seagate, Cisco, and Pelco. In my tenure at Layer5, Lee has been an amazing mentor, someone you can always look towards for encouragement, inspiration and a kind word, especially when you’re melting under the heat to make that late night deadline. + + +#### Layer5 and UEM Jaipur Partnership Program +In an effort to foster the open source community in my college, I along with four of my batchmates (Anand, Subham, Nikhil, Gunjan) decided to start an open source partnership program, encouraged by Lee and Rupayan Das (Faculty, UEM Jaipur). This will hopefully lead to making future batches more aware about the essence of open source and encourage them to participate in communities like Layer5. + +layer5 + +#### Community Love + +The Layer5 community has welcomed me with patience and has given me a sense of purpose, which is more than I could have asked for at the beginning as a novice developer. The warm welcome and a sincere string of mentors can do wonders in building your confidence and enabling you to put in your best foot forward. Open source has introduced me to a horde of essential qualities, such as the importance of teamwork, candor and earnestness.
    +It has been a prodigious journey so far and I don’t intend to stop here. The pace at which the projects under the Layer5 community are unwinding is awe-inspiring. It is my aim to be a witness and a partner in crime in its future endeavors. If you’re looking for an opportunity to be a part of the Layer5 family, check out our projects and head over to our [Slack](http://slack.layer5.io) channel! + +
    diff --git a/src/collections/blog/2020/2020-07-18-service-mesh-patterns-for-multitenancy/index.mdx b/src/collections/blog/2020/2020-07-18-service-mesh-patterns-for-multitenancy/index.mdx index 3ef71b10d20e..44be0ad8a4a2 100644 --- a/src/collections/blog/2020/2020-07-18-service-mesh-patterns-for-multitenancy/index.mdx +++ b/src/collections/blog/2020/2020-07-18-service-mesh-patterns-for-multitenancy/index.mdx @@ -1,280 +1,278 @@ ---- -title: "Service Mesh (Istio) patterns for Multitenancy" -subtitle: "" -date: 2020-07-18 10:30:05 -0530 -author: Sudeep Batra -thumbnail: ./image2.webp -darkthumbnail: ./image2.webp -category: Service Mesh -tags: - - Service Mesh - - Open Source - - Istio -published: true -type: Blog -technology: Kubernetes -mesh: Istio -resource: true -redirect_from: - - /blog/service-mesh-patterns-for-multitenancy/ ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import listioLayer5 from "./layer5-and-istio.webp"; -import img1 from "./image1.webp"; -import img2 from "./image2.webp"; -import img3 from "./image3.webp"; -import img4 from "./image4.webp"; - - - -Layer5 and Istio - -Recently, I started learning on Service Mesh and it was a very interesting journey as I explored the Service Mesh -landscape starting with [Layer5 tutorials](https://github.com/layer5io/istio-service-mesh-workshop) and by exploring -the blogs at [Istio.io](https://istio.io/). - -Our organization decided to use the features of Istio for securing, managing and automating microservices. However, we have to support a multi-tenant environment and that became a challenge due to lack of sufficient documentation and clarity. To give a little bit of background on the problem, we have a single cluster with multiple tenants in different namespaces sharing the same cluster . We do not want to provide each tenant their own separate Kubernetes Cluster because that would be additional provisioning overhead, management overhead and also additional resource overhead on the platform. - -In this blog, I will go over the concepts and visual representation as well as the steps to learn and build your setup. -Now there are different combinations possible depending on the requirements. These could be : - -1. Single Istio Control Plane with its own Ingress-Gateway to ensure traffic for the control plane is coming via the same control plane Ingress-Gateway. -1. One or more Workspace namespaces for the workload applications and each with its own instance of the ingress gateway -1. More advanced scenario would be multiple Control Plane and its associated Data Plane or essentially Multiple Service Mesh within a single Kubernetes Cluster. This is presently feasible using the Maistra Istio Operator, but its not fully supported using the upstream Istio at present. I intend to go over this use case in a later article. - -Here by Ingress Gateway we mean the Istio Ingress Gateway and not the Kubernetes Ingress Gateway. -Now, before we get into the steps for building an Istio Multi-tenant setup, lets quickly review the prerequisite : - -- Kubernetes setup (in the steps below I am using v1.18 on ubuntu 18.04) - - ```sh - $ sudo apt-get install -y docker.io - $ sudo sh -c “echo ‘deb http://apt.kubernetes.io/ kubernetes-xenial main’ >> /etc/apt/sources.list.d/kubernetes.list” - $ sudo sh -c “curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -” - $ sudo apt-get update - $ sudo apt-get install -y kubeadm=1.18.1–00 kubelet=1.18.1–00 kubectl=1.18.1–00 - $ sudo kubeadm init — kubernetes-version 1.18.1 — pod-network-cidr 192.168.0.0/16 - $ mkdir -p $HOME/.kube - $ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config - $ sudo chown $(id -u):$(id -g) $HOME/.kube/config - $ kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml - ``` - -- Get the latest istioctl binary - - ```sh - $ curl -L https://git.io/getLatestIstio | sh - - cd istio-* - export PATH=$PWD/bin:$PATH - istioctl version - ``` - -- Initialize the Istio Operator - ```sh - $ istioctl operator init - Using operator Deployment image: docker.io/istio/operator:1.6.3 - ✔ Istio operator installed - ✔ Installation complete - $ kubectl get all -n istio-operator - NAME READY STATUS RESTARTS AGE - pod/istio-operator-5998f6c744-vrkbk 1/1 Running 1 78m - NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE - service/istio-operator ClusterIP 10.107.183.94 8383/TCP 78m - NAME READY UP-TO-DATE AVAILABLE AGE - deployment.apps/istio-operator 1/1 1 1 78m - NAME DESIRED CURRENT READY AGE - replicaset.apps/istio-operator-5998f6c744 1 1 1 78m - ``` - -Next we will look into the details of the multitenancy scenarios; but before that a few word on the Istio operator would be nice. The Istio Operator follows the Kubernetes Controller and Custom Resource Definition mechanism and basically the above steps create an Istio operator controller in the istio-operator namespace and also registers the CRDs in the Kubernetes Registry. Basically, it extends the API for Kubernetes and allows management of a Custom Resource(CR). A word of caution, the existing upstream Istio Operator does not follow any Operator Framework like kubebuilder or Operator SDK. Hence, many of the expected behavior fail like trying to create two Istio Operator Custom Resource(the community mentions it as `iop` instances) in different namespaces or multiple `iop` instances and are under heavy development. - -Ok, so now lets jump into action. We will build our Istio Setup for the scenario 1 &2 above shown in the diagram below. There are three different instances of Ingress Gateway(and it could be egress gateway as well) : - -a. Ingress Gateway in Control Plane for traffic entry point to the Control plane Observability Components like `Kiali`(for the Service Mesh Graph), `Prometheus`(for metrics),Grafana(for visual charts of the metrics)and `Jaeger` (for distributed tracing between the services) -b. Ingress Gateway in the Worskpace 1 namespace for traffic entry point to the workspace 1 microservices. -c. Ingress Gateway in the Worskpace 2 namespace for traffic entry point to the workspace 2 microservices. - -kubernetes-cluster -

    - Single Control Plane with Multiple Data Plane each with separate Ingress - Gateway -

    - -- Creation of Control Plane CR and Data Plane CR - A sample CR for creation of the Control plane and Data Plane CR can be referred below : - ```sh - $ cat iop-platform.yaml - apiVersion: install.istio.io/v1alpha1 - kind: IstioOperator - metadata: - namespace: istio-system - name: platform-istiocontrolplane - spec: - profile: demo - $ cat iop-wk1-gw.yaml - apiVersion: install.istio.io/v1alpha1 - kind: IstioOperator - metadata: - namespace: istio-system - name: wk1-gwconfig - spec: - profile: empty - components: - ingressGateways: - — name: wk1-ingressgw - namespace: workspace-1 - enabled: true - label: - istio: ingressgateway-1 - app: istio-ingressgateway-1 - values: - gateways: - istio-ingressgateway: - debug: error - $ cat iop-wk2-gw.yaml - apiVersion: install.istio.io/v1alpha1 - kind: IstioOperator - metadata: - namespace: istio-system - name: wk2-gwconfig - spec: - profile: empty - components: - ingressGateways: - — name: wk2-ingressgw - namespace: workspace-2 - enabled: true - label: - istio: ingressgateway-2 - app: istio-ingressgateway-2 - values: - gateways: - istio-ingressgateway: - debug: error - ``` - -It is important to make sure the indentation is correct ,otherwise it would lead to errors. -Reference: [Istio Website](https://istio.io/latest/docs/setup/install/) - -Deploy the CRs using kubectl: - -```sh -$ kubectl create ns istio-system -$ kubectl create ns workspace-1 -$ kubectl create ns workspace-2 -$ kubectl apply -f ../iop-platform.yaml -istiooperator.install.istio.io/platform-istiocontrolplane created -$ kubectl apply -f ../iop-wk1-gw.yaml -istiooperator.install.istio.io/wk1-gwconfig configured -$ kubectl apply -f ../iop-wk2-gw.yaml -istiooperator.install.istio.io/wk2-gwconfig configured -``` - -- Troubleshooting the Istio Operator Controller. - Its a good idea to run another window and execute the below command to observe the running logs on the controller pod. - ```sh - $ kubectl logs -f -n istio-operator - $(kubectl get pods -n istio-operator -lname=istio-operator -o jsonpath=’{.items[0].metadata.name}’) - ``` - -image - -- Observe the created objects in istio-system and the workspace namespaces for all pods to be in running state. - - ```sh - $ kubectl get all -n istio-system - NAME READY STATUS RESTARTS AGE - pod/grafana-b54bb57b9-k84xf 1/1 Running 0 79s - pod/istio-egressgateway-77c7d594c5-fr79j 1/1 Running 0 83s - pod/istio-ingressgateway-766c84dfdc-p6g6t 1/1 Running 0 83s - pod/istio-tracing-9dd6c4f7c-ndjvn 1/1 Running 0 79s - pod/istiod-7b69ff6f8c-9gwp8 1/1 Running 0 94s - pod/kiali-d45468dc4–4sww2 1/1 Running 0 79s - pod/prometheus-5fdfc44fb7–67khx 2/2 Running 0 78s - - esudbat@istio:~/istio$ kubectl get all -n workspace-1 - NAME READY STATUS RESTARTS AGE - pod/wk1-ingressgw-5674488c8b-fg2w5 1/1 Running 0 21s - - esudbat@istio:~/istio$ kubectl get all -n workspace-2 - ``` - -- Now we will label the namespaces for istio-injection - - ```sh - $kubectl label namespace workspace-1 istio-injection=enabled - $kubectl label namespace workspace-2 istio-injection=enabled - ``` - -- Now we will deploy the bookinfo sample application in both namespaces but before that we need to make sure that the Gateway resource is updated with the correct label selector as below : - - ```sh - $ cat istio/bookinfo-gateway-1.yaml - apiVersion: networking.istio.io/v1alpha3 - kind: Gateway - metadata: - name: bookinfo-gateway - spec: - selector: - istio: ingressgateway-1 # use istio gateway-1 controller in workspace-1 - servers: - — port: - number: 80 - name: http - protocol: HTTP - hosts: - — “*” - $ cat istio/bookinfo-gateway-2.yaml - apiVersion: networking.istio.io/v1alpha3 - kind: Gateway - metadata: - name: bookinfo-gateway - spec: - selector: - istio: ingressgateway-2 # use istio gateway-2 controller in workspace-1 - servers: - — port: - number: 80 - name: http - protocol: HTTP - hosts: - — “*” - ``` - -Deploy the applications in workspace-1 and workspace-2 and deploy the Gateway,VirtualService and DestinationRules. - -```sh -$kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n workspace-1 -$kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n workspace-2 -$kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml -n workspace-1 -$kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml -n workspace-2 -$kubectl apply -f samples/bookinfo/networking/destination-rule-all-mtls.yaml -n workspace-1 -$kubectl apply -f samples/bookinfo/networking/destination-rule-all-mtls.yaml -n workspace-2 -``` - -Essentially what is happening is the Gateway CR is configuring the traffic to come via the ingress-gateway, it specifies the label selector based on which the ingress-gateway is selected and the host from where the traffic is allowed and port on which the traffic is allowed. It is important to ensure the label maps the label on the ingress-gateway. -Once this is done the traffic will start flowing the intended gateway and it could be observed on the Kiali dashboard. -Please note that in this scenario the Kiali is also accessed via the default control plane ingress-gateway running in the istio-system control plane namespace. - -image -

    Kiali view for Workspace-1

    - -image -

    Kiali view for Workspace-2

    - -Shortly, we will go over the 3rd scenario which is to run multiple Istio Control Planes (Multiple Service Meshes) within the same Kubernetes Cluster. For that, we will need to build an open-shift setup and deploy the Maistra Istio Operator. -Special thanks to the [Istio Community](https://istio.slack.com/) for helping me understand the concepts and also answering my queries and of course to [Lee Calcote](https://calcotestudios.com/talks/), who helped me embark on my Istio journey. - -
    - - Connect with Sudeep Batra on - LinkedIn, - {" "} - GitHub - , or - Twitter. - -
    - -
    +--- +title: "Service Mesh (Istio) patterns for Multitenancy" +subtitle: "" +date: 2020-07-18 10:30:05 -0530 +author: Sudeep Batra +thumbnail: ./image2.webp +darkthumbnail: ./image2.webp +category: Service Mesh +tags: + - Service Mesh + - Open Source + - Istio +published: true +type: Blog +technology: Kubernetes +mesh: Istio +resource: true +redirect_from: + - /blog/service-mesh-patterns-for-multitenancy/ +--- + + +import listioLayer5 from "./layer5-and-istio.webp"; +import img1 from "./image1.webp"; +import img2 from "./image2.webp"; +import img3 from "./image3.webp"; +import img4 from "./image4.webp"; + + + +Layer5 and Istio + +Recently, I started learning on Service Mesh and it was a very interesting journey as I explored the Service Mesh +landscape starting with [Layer5 tutorials](https://github.com/layer5io/istio-service-mesh-workshop) and by exploring +the blogs at [Istio.io](https://istio.io/). + +Our organization decided to use the features of Istio for securing, managing and automating microservices. However, we have to support a multi-tenant environment and that became a challenge due to lack of sufficient documentation and clarity. To give a little bit of background on the problem, we have a single cluster with multiple tenants in different namespaces sharing the same cluster . We do not want to provide each tenant their own separate Kubernetes Cluster because that would be additional provisioning overhead, management overhead and also additional resource overhead on the platform. + +In this blog, I will go over the concepts and visual representation as well as the steps to learn and build your setup. +Now there are different combinations possible depending on the requirements. These could be : + +1. Single Istio Control Plane with its own Ingress-Gateway to ensure traffic for the control plane is coming via the same control plane Ingress-Gateway. +1. One or more Workspace namespaces for the workload applications and each with its own instance of the ingress gateway +1. More advanced scenario would be multiple Control Plane and its associated Data Plane or essentially Multiple Service Mesh within a single Kubernetes Cluster. This is presently feasible using the Maistra Istio Operator, but its not fully supported using the upstream Istio at present. I intend to go over this use case in a later article. + +Here by Ingress Gateway we mean the Istio Ingress Gateway and not the Kubernetes Ingress Gateway. +Now, before we get into the steps for building an Istio Multi-tenant setup, lets quickly review the prerequisite : + +- Kubernetes setup (in the steps below I am using v1.18 on ubuntu 18.04) + + ```sh + $ sudo apt-get install -y docker.io + $ sudo sh -c “echo ‘deb http://apt.kubernetes.io/ kubernetes-xenial main’ >> /etc/apt/sources.list.d/kubernetes.list” + $ sudo sh -c “curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | apt-key add -” + $ sudo apt-get update + $ sudo apt-get install -y kubeadm=1.18.1–00 kubelet=1.18.1–00 kubectl=1.18.1–00 + $ sudo kubeadm init — kubernetes-version 1.18.1 — pod-network-cidr 192.168.0.0/16 + $ mkdir -p $HOME/.kube + $ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config + $ sudo chown $(id -u):$(id -g) $HOME/.kube/config + $ kubectl apply -f https://docs.projectcalico.org/manifests/calico.yaml + ``` + +- Get the latest istioctl binary + + ```sh + $ curl -L https://git.io/getLatestIstio | sh - + cd istio-* + export PATH=$PWD/bin:$PATH + istioctl version + ``` + +- Initialize the Istio Operator + ```sh + $ istioctl operator init + Using operator Deployment image: docker.io/istio/operator:1.6.3 + ✔ Istio operator installed + ✔ Installation complete + $ kubectl get all -n istio-operator + NAME READY STATUS RESTARTS AGE + pod/istio-operator-5998f6c744-vrkbk 1/1 Running 1 78m + NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE + service/istio-operator ClusterIP 10.107.183.94 8383/TCP 78m + NAME READY UP-TO-DATE AVAILABLE AGE + deployment.apps/istio-operator 1/1 1 1 78m + NAME DESIRED CURRENT READY AGE + replicaset.apps/istio-operator-5998f6c744 1 1 1 78m + ``` + +Next we will look into the details of the multitenancy scenarios; but before that a few word on the Istio operator would be nice. The Istio Operator follows the Kubernetes Controller and Custom Resource Definition mechanism and basically the above steps create an Istio operator controller in the istio-operator namespace and also registers the CRDs in the Kubernetes Registry. Basically, it extends the API for Kubernetes and allows management of a Custom Resource(CR). A word of caution, the existing upstream Istio Operator does not follow any Operator Framework like kubebuilder or Operator SDK. Hence, many of the expected behavior fail like trying to create two Istio Operator Custom Resource(the community mentions it as `iop` instances) in different namespaces or multiple `iop` instances and are under heavy development. + +Ok, so now lets jump into action. We will build our Istio Setup for the scenario 1 &2 above shown in the diagram below. There are three different instances of Ingress Gateway(and it could be egress gateway as well) : + +a. Ingress Gateway in Control Plane for traffic entry point to the Control plane Observability Components like `Kiali`(for the Service Mesh Graph), `Prometheus`(for metrics),Grafana(for visual charts of the metrics)and `Jaeger` (for distributed tracing between the services) +b. Ingress Gateway in the Worskpace 1 namespace for traffic entry point to the workspace 1 microservices. +c. Ingress Gateway in the Worskpace 2 namespace for traffic entry point to the workspace 2 microservices. + +kubernetes-cluster +

    + Single Control Plane with Multiple Data Plane each with separate Ingress + Gateway +

    + +- Creation of Control Plane CR and Data Plane CR + A sample CR for creation of the Control plane and Data Plane CR can be referred below : + ```sh + $ cat iop-platform.yaml + apiVersion: install.istio.io/v1alpha1 + kind: IstioOperator + metadata: + namespace: istio-system + name: platform-istiocontrolplane + spec: + profile: demo + $ cat iop-wk1-gw.yaml + apiVersion: install.istio.io/v1alpha1 + kind: IstioOperator + metadata: + namespace: istio-system + name: wk1-gwconfig + spec: + profile: empty + components: + ingressGateways: + — name: wk1-ingressgw + namespace: workspace-1 + enabled: true + label: + istio: ingressgateway-1 + app: istio-ingressgateway-1 + values: + gateways: + istio-ingressgateway: + debug: error + $ cat iop-wk2-gw.yaml + apiVersion: install.istio.io/v1alpha1 + kind: IstioOperator + metadata: + namespace: istio-system + name: wk2-gwconfig + spec: + profile: empty + components: + ingressGateways: + — name: wk2-ingressgw + namespace: workspace-2 + enabled: true + label: + istio: ingressgateway-2 + app: istio-ingressgateway-2 + values: + gateways: + istio-ingressgateway: + debug: error + ``` + +It is important to make sure the indentation is correct ,otherwise it would lead to errors. +Reference: [Istio Website](https://istio.io/latest/docs/setup/install/) + +Deploy the CRs using kubectl: + +```sh +$ kubectl create ns istio-system +$ kubectl create ns workspace-1 +$ kubectl create ns workspace-2 +$ kubectl apply -f ../iop-platform.yaml +istiooperator.install.istio.io/platform-istiocontrolplane created +$ kubectl apply -f ../iop-wk1-gw.yaml +istiooperator.install.istio.io/wk1-gwconfig configured +$ kubectl apply -f ../iop-wk2-gw.yaml +istiooperator.install.istio.io/wk2-gwconfig configured +``` + +- Troubleshooting the Istio Operator Controller. + Its a good idea to run another window and execute the below command to observe the running logs on the controller pod. + ```sh + $ kubectl logs -f -n istio-operator + $(kubectl get pods -n istio-operator -lname=istio-operator -o jsonpath=’{.items[0].metadata.name}’) + ``` + +image + +- Observe the created objects in istio-system and the workspace namespaces for all pods to be in running state. + + ```sh + $ kubectl get all -n istio-system + NAME READY STATUS RESTARTS AGE + pod/grafana-b54bb57b9-k84xf 1/1 Running 0 79s + pod/istio-egressgateway-77c7d594c5-fr79j 1/1 Running 0 83s + pod/istio-ingressgateway-766c84dfdc-p6g6t 1/1 Running 0 83s + pod/istio-tracing-9dd6c4f7c-ndjvn 1/1 Running 0 79s + pod/istiod-7b69ff6f8c-9gwp8 1/1 Running 0 94s + pod/kiali-d45468dc4–4sww2 1/1 Running 0 79s + pod/prometheus-5fdfc44fb7–67khx 2/2 Running 0 78s + + esudbat@istio:~/istio$ kubectl get all -n workspace-1 + NAME READY STATUS RESTARTS AGE + pod/wk1-ingressgw-5674488c8b-fg2w5 1/1 Running 0 21s + + esudbat@istio:~/istio$ kubectl get all -n workspace-2 + ``` + +- Now we will label the namespaces for istio-injection + + ```sh + $kubectl label namespace workspace-1 istio-injection=enabled + $kubectl label namespace workspace-2 istio-injection=enabled + ``` + +- Now we will deploy the bookinfo sample application in both namespaces but before that we need to make sure that the Gateway resource is updated with the correct label selector as below : + + ```sh + $ cat istio/bookinfo-gateway-1.yaml + apiVersion: networking.istio.io/v1alpha3 + kind: Gateway + metadata: + name: bookinfo-gateway + spec: + selector: + istio: ingressgateway-1 # use istio gateway-1 controller in workspace-1 + servers: + — port: + number: 80 + name: http + protocol: HTTP + hosts: + — “*” + $ cat istio/bookinfo-gateway-2.yaml + apiVersion: networking.istio.io/v1alpha3 + kind: Gateway + metadata: + name: bookinfo-gateway + spec: + selector: + istio: ingressgateway-2 # use istio gateway-2 controller in workspace-1 + servers: + — port: + number: 80 + name: http + protocol: HTTP + hosts: + — “*” + ``` + +Deploy the applications in workspace-1 and workspace-2 and deploy the Gateway,VirtualService and DestinationRules. + +```sh +$kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n workspace-1 +$kubectl apply -f samples/bookinfo/platform/kube/bookinfo.yaml -n workspace-2 +$kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml -n workspace-1 +$kubectl apply -f samples/bookinfo/networking/bookinfo-gateway.yaml -n workspace-2 +$kubectl apply -f samples/bookinfo/networking/destination-rule-all-mtls.yaml -n workspace-1 +$kubectl apply -f samples/bookinfo/networking/destination-rule-all-mtls.yaml -n workspace-2 +``` + +Essentially what is happening is the Gateway CR is configuring the traffic to come via the ingress-gateway, it specifies the label selector based on which the ingress-gateway is selected and the host from where the traffic is allowed and port on which the traffic is allowed. It is important to ensure the label maps the label on the ingress-gateway. +Once this is done the traffic will start flowing the intended gateway and it could be observed on the Kiali dashboard. +Please note that in this scenario the Kiali is also accessed via the default control plane ingress-gateway running in the istio-system control plane namespace. + +image +

    Kiali view for Workspace-1

    + +image +

    Kiali view for Workspace-2

    + +Shortly, we will go over the 3rd scenario which is to run multiple Istio Control Planes (Multiple Service Meshes) within the same Kubernetes Cluster. For that, we will need to build an open-shift setup and deploy the Maistra Istio Operator. +Special thanks to the [Istio Community](https://istio.slack.com/) for helping me understand the concepts and also answering my queries and of course to [Lee Calcote](https://calcotestudios.com/talks/), who helped me embark on my Istio journey. + +
    + + Connect with Sudeep Batra on + LinkedIn, + {" "}GitHub, or + Twitter. + +
    + +
    diff --git a/src/collections/blog/2020/2020-08-04-how-i-schooled-my-seniors/index.mdx b/src/collections/blog/2020/2020-08-04-how-i-schooled-my-seniors/index.mdx index df53555bb452..c9209716bb0d 100644 --- a/src/collections/blog/2020/2020-08-04-how-i-schooled-my-seniors/index.mdx +++ b/src/collections/blog/2020/2020-08-04-how-i-schooled-my-seniors/index.mdx @@ -1,36 +1,36 @@ ---- -title: "How I schooled my seniors" -subtitle: "and why I swear by the experience" -date: 2020-08-04 10:15:05 +0000 -author: Nupur Thakur -thumbnail: ./feature-image.svg -darkthumbnail: ./feature-image.svg -category: Community -tags: - - Community - - MeshMate -published: true -redirect_from: - - /blog/how-i-schooled-my-seniors/ ---- - -import { BlogWrapper } from "../../Blog.style.js"; - - - -I started a new job at [RemoteState](https://www.linkedin.com/company/remotestate/) as a software development engineer in May of 2020. -Post the initial plunge, settling into the role was relatively easier for me due to the experience I had gained in working on open source contributions in the Layer5 community. My experience with open source had also been a big plus for me throughout the application and interview process. As a direct result, my colleagues and seniors became genuinely inquisitive about Meshery and its functionality as the Kubernetes Manager. So when asked, I happily agreed to deliver a session on the subject to the entire team. - -I pitched my idea to [Lee Calcote](https://layer5.io/community/members/lee-calcote) and in his usual supportive form, he was as excited as I was about the session. A brainstorm session led to creating an entire presentation with suggestions from Lee. The Layer5 community offers a number of resources to contributors, including these two decks ([Meshery - the cloud native management plane](https://layer5.io/meshery) and [Layer5](https://docs.google.com/presentation/d/1tLcMcyQ-Z6YYISYyR0Eyb30dojQiKHIjs7Rt5m8kcag/edit?usp=sharing) that I drew from as a basis for a personalized presentation and demonstration to my new team. - -
    -
    - -When the day arrived to present the concepts of service meshes, Meshery, and other cloud native initiatives to my team, I held a Google Meet with a full attendance. I started the session with a reader’s digest version of microservices and service meshes to set the stage for any newcomers to the world of cloud native, I went on to elaborate on Layer5 ‘s contributions to the CNCF landscape and the SMI project. This was followed by an in-depth discussion on data planes, control planes, and management planes. I spoke at-length about Meshery’s functionality including, its features for facilitating the benchmarking, interoperability and standardization of service meshes. I wrapped up the session with some insider tips that I have learned in my months as an open source contributor in the Layer5 community. In the stream of feedback received from my colleagues, the session seems to have been a success. - -This whole experience has been an amazing journey for me. From being a complete noob to utilizing my expertise in the service mesh domain to landing an actual job, the experience has been a maze of ups and downs. But, I feel like I have finally arrived and arrived with a pot of gold. I’m eternally grateful to Lee Calcote for motivating me and providing me with the appropriate resources. Entering and exploring an open source community can be a daunting task and the [resources provided by Layer5](https://layer5.io/community/newcomers) helped them in overcoming that challenge and enabled them to learn more about the widespread work of [Meshery](https://meshery.io). - -I’m glad to have found a community that not only feeds my professional success, but also my personal growth. It’s not out of obligation, but out of a sense of gratitude and paying it forward to others (a tenant of the Layer5 community) that I now spend much of my time as a MeshMate. I help welcome and guide other new contributors along their open source path as they learn and grow. Giving to others and while continuing to grow professionally and personally is time well spent. I encourage you to join me and others in the Layer5 community by jumping into our [Slack](https://slack.layer5.io/) to start meshing around! - - -
    +--- +title: "How I schooled my seniors" +subtitle: "and why I swear by the experience" +date: 2020-08-04 10:15:05 +0000 +author: Nupur Thakur +thumbnail: ./feature-image.svg +darkthumbnail: ./feature-image.svg +category: Community +tags: + - Community + - MeshMate +published: true +redirect_from: + - /blog/how-i-schooled-my-seniors/ +--- + + + + + +I started a new job at [RemoteState](https://www.linkedin.com/company/remotestate/) as a software development engineer in May of 2020. +Post the initial plunge, settling into the role was relatively easier for me due to the experience I had gained in working on open source contributions in the Layer5 community. My experience with open source had also been a big plus for me throughout the application and interview process. As a direct result, my colleagues and seniors became genuinely inquisitive about Meshery and its functionality as the Kubernetes Manager. So when asked, I happily agreed to deliver a session on the subject to the entire team. + +I pitched my idea to [Lee Calcote](https://layer5.io/community/members/lee-calcote) and in his usual supportive form, he was as excited as I was about the session. A brainstorm session led to creating an entire presentation with suggestions from Lee. The Layer5 community offers a number of resources to contributors, including these two decks ([Meshery - the cloud native management plane](https://layer5.io/meshery) and [Layer5](https://docs.google.com/presentation/d/1tLcMcyQ-Z6YYISYyR0Eyb30dojQiKHIjs7Rt5m8kcag/edit?usp=sharing) that I drew from as a basis for a personalized presentation and demonstration to my new team. + +
    +
    + +When the day arrived to present the concepts of service meshes, Meshery, and other cloud native initiatives to my team, I held a Google Meet with a full attendance. I started the session with a reader’s digest version of microservices and service meshes to set the stage for any newcomers to the world of cloud native, I went on to elaborate on Layer5 ‘s contributions to the CNCF landscape and the SMI project. This was followed by an in-depth discussion on data planes, control planes, and management planes. I spoke at-length about Meshery’s functionality including, its features for facilitating the benchmarking, interoperability and standardization of service meshes. I wrapped up the session with some insider tips that I have learned in my months as an open source contributor in the Layer5 community. In the stream of feedback received from my colleagues, the session seems to have been a success. + +This whole experience has been an amazing journey for me. From being a complete noob to utilizing my expertise in the service mesh domain to landing an actual job, the experience has been a maze of ups and downs. But, I feel like I have finally arrived and arrived with a pot of gold. I’m eternally grateful to Lee Calcote for motivating me and providing me with the appropriate resources. Entering and exploring an open source community can be a daunting task and the [resources provided by Layer5](https://layer5.io/community/newcomers) helped them in overcoming that challenge and enabled them to learn more about the widespread work of [Meshery](https://meshery.io). + +I’m glad to have found a community that not only feeds my professional success, but also my personal growth. It’s not out of obligation, but out of a sense of gratitude and paying it forward to others (a tenant of the Layer5 community) that I now spend much of my time as a MeshMate. I help welcome and guide other new contributors along their open source path as they learn and grow. Giving to others and while continuing to grow professionally and personally is time well spent. I encourage you to join me and others in the Layer5 community by jumping into our [Slack](https://slack.layer5.io/) to start meshing around! + + +
    diff --git a/src/collections/blog/2020/2020-08-07-announcing-meshery-v0.4/index.mdx b/src/collections/blog/2020/2020-08-07-announcing-meshery-v0.4/index.mdx index c511c4b9b41c..4e10107ef423 100644 --- a/src/collections/blog/2020/2020-08-07-announcing-meshery-v0.4/index.mdx +++ b/src/collections/blog/2020/2020-08-07-announcing-meshery-v0.4/index.mdx @@ -1,98 +1,98 @@ ---- -title: "Announcing Meshery v0.4.0" -subtitle: "" -date: 2020-08-07 08:00:00 +0000 -author: Layer5 Team -thumbnail: ./meshery-v040.webp -darkthumbnail: ./meshery-v040.webp -category: Announcements -tags: - - Meshery - - Projects -published: true -type: Blog -product: Meshery -resource: true -redirect_from: - - /blog/meshery/announcing-meshery-v0.4.0/ ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import operator from "./meshery-operator-dark.svg"; -import MesheryArchitecture from "./meshery-architecture.webp"; - - - -[Meshery](https://meshery.io) is the cloud native management plane offering lifecycle, configuration and performance management of service meshes and their workloads. - -Layer5 community members are hard at work providing our users with easy access to any service mesh and myriad management features. New releases for Meshery are published on a frequent cadence with new features and bug fixes. Today, we are announcing version 0.4.0 of Meshery. This summary highlights Meshery's latest developments and elucidates new features. - -## What's New? - -The v0.4.0 release of Meshery introduces a plethora of new features and bug fixes across service mesh environments spanning Meshery and it's various adapters. - -### Meshery's CLI: `mesheryctl` -**New Command Structure**
    -`mesheryctl` commands and subcommands have been restructured in v0.4.0 into the categories: -- Global Commands and Flags -- Meshery Lifecycle Management -- Performance Management -- Service Mesh Lifecycle Management -- Workload Lifecycle Management - -Organizing commnands [under these categories](https://docs.meshery.io/reference/mesheryctl) is done with both the intention to make `mesheryctl` functions intuitively at your fingertips, but also to make room for forthcoming functionality. - -**Exposing Performance Management in the CLI**
    -`perf:` a new `mesheryctl`command. Introduction of new performance sub-commands, now benchmark your service mesh at the tip of your fingers using our new CLI command `perf`. - -**Support for Scoop**
    -Support extended to Scoop Bucket. You can now install mesheryctl on your Windows machine with Scoop Bucket. Visit the [Meshery Scoop Bucket](https://github.com/layer5io/scoop-bucket) to install Meshery on Windows. - -**Rename `cleanup` to `reset`**
    -The `cleanup` is used to reset your Meshery deployment configuration back to its default settings. This command has been renamed to `reset` to more appropriately reflect its purpose. - -### MeshSync
    -meshery-operator-dark - -- A component of the [Meshery Operator](https://github.com/layer5io/meshery-operator), MeshSync can scan the environment to get the deployment details of specific types of service meshes and the connected Kubernetes cluster. -- MeshSync is a new component addition to Meshery. Meshery needs to be constantly updated given that service meshes and their underlying infrastructure are dynamic, constantly changing. Meshery operations should be resilient in the face of this change. -- MeshSync brings a service mesh agnostic object model that defines relationships between all objects under management. - -### Meshery Adapter for Citrix Service Mesh (beta)
    - -meshery-architecture - -- [Citrix Service Mesh](https://github.com/layer5io/meshery-cpx) is now a supported service mesh. Meshery incorporates support for the Citrix ADC CPX, which is a cloud-ready, container-based application delivery controller that can be provisioned on a Docker host. -- CPX runs as the Istio Data Plane component, displacing Envoy as the default data plane service proxy.
    - -### Security & Authentication - -- Meshery has moved from using session authentication to JWT authentication. Meshery's JWT authentication is powered by Hydra Auth. -- You can now opt to authenticate yourself on mesheryctl while performing performance tests using `mesheryctl`, you can authenticate yourself by getting the JWT Token from Meshery UI. - -### Meshery Server - -- Support provided for [wrk2 as an alternative load generator](https://docs.meshery.io/functionality/performance-management#load-generators). -- [Providers](https://docs.meshery.io/extensibility) - A new project construct that allows users to select authentication, long-term storage etc. -- Ad-hoc [connectivity tests for Prometheus and Grafana](https://docs.meshery.io/functionality/performance-management#grafana-and-meshery) are now supported. -- Extraneous information beyond IP address and port in Grafana and Prometheus endpoints have been stripped off. - -### Meshery UI - -- ES-Lint has been added to the client side to ensure the quality of code and increase maintainaiblity of code. -- Cypress has been set-up to enable end-to-end tests and integration tests for Meshery UI. - -
    - - -### Other notable changes - -- From within the [Meshery Continuous Integration Working Group](https://www.youtube.com/watch?v=ds9D2KgZKxo&list=PL3A-A6hPO2IM7rYiKxG4l3eQNc6X3IUex), we have strengthened our continuous integration (CI) actions & tests by introducing new workflows like `static check`, `vet check`, `security check` for our server code. -- ReleaseDrafter & WelcomeBot has been added to the repository to enable automation of release notes and for welcoming new contributors, respectively. - -To get a more comprehensive list of the bug fixes and enhancements packaged in the v0.4.0 release, see the [Meshery Documentation](https://docs.meshery.io/project/releases) - - -_**P.S.: If these topics excite you and you want to explore the beautiful realm of service meshes, come and say "Hi" on our [Slack Channel](http://slack.layer5.io) and one of us will reach out to you!**_ - -
    +--- +title: "Announcing Meshery v0.4.0" +subtitle: "" +date: 2020-08-07 08:00:00 +0000 +author: Layer5 Team +thumbnail: ./meshery-v040.webp +darkthumbnail: ./meshery-v040.webp +category: Announcements +tags: + - Meshery + - Projects +published: true +type: Blog +product: Meshery +resource: true +redirect_from: + - /blog/meshery/announcing-meshery-v0.4.0/ +--- + + +import operator from "./meshery-operator-dark.svg"; +import MesheryArchitecture from "./meshery-architecture.webp"; + + + +[Meshery](https://meshery.io) is the cloud native management plane offering lifecycle, configuration and performance management of service meshes and their workloads. + +Layer5 community members are hard at work providing our users with easy access to any service mesh and myriad management features. New releases for Meshery are published on a frequent cadence with new features and bug fixes. Today, we are announcing version 0.4.0 of Meshery. This summary highlights Meshery's latest developments and elucidates new features. + +## What's New? + +The v0.4.0 release of Meshery introduces a plethora of new features and bug fixes across service mesh environments spanning Meshery and it's various adapters. + +### Meshery's CLI: `mesheryctl` +**New Command Structure**
    +`mesheryctl` commands and subcommands have been restructured in v0.4.0 into the categories: +- Global Commands and Flags +- Meshery Lifecycle Management +- Performance Management +- Service Mesh Lifecycle Management +- Workload Lifecycle Management + +Organizing commnands [under these categories](https://docs.meshery.io/reference/mesheryctl) is done with both the intention to make `mesheryctl` functions intuitively at your fingertips, but also to make room for forthcoming functionality. + +**Exposing Performance Management in the CLI**
    +`perf:` a new `mesheryctl`command. Introduction of new performance sub-commands, now benchmark your service mesh at the tip of your fingers using our new CLI command `perf`. + +**Support for Scoop**
    +Support extended to Scoop Bucket. You can now install mesheryctl on your Windows machine with Scoop Bucket. Visit the [Meshery Scoop Bucket](https://github.com/layer5io/scoop-bucket) to install Meshery on Windows. + +**Rename `cleanup` to `reset`**
    +The `cleanup` is used to reset your Meshery deployment configuration back to its default settings. This command has been renamed to `reset` to more appropriately reflect its purpose. + +### MeshSync
    +meshery-operator-dark + +- A component of the [Meshery Operator](https://github.com/layer5io/meshery-operator), MeshSync can scan the environment to get the deployment details of specific types of service meshes and the connected Kubernetes cluster. +- MeshSync is a new component addition to Meshery. Meshery needs to be constantly updated given that service meshes and their underlying infrastructure are dynamic, constantly changing. Meshery operations should be resilient in the face of this change. +- MeshSync brings a service mesh agnostic object model that defines relationships between all objects under management. + +### Meshery Adapter for Citrix Service Mesh (beta)
    + +meshery-architecture + +- [Citrix Service Mesh](https://github.com/layer5io/meshery-cpx) is now a supported service mesh. Meshery incorporates support for the Citrix ADC CPX, which is a cloud-ready, container-based application delivery controller that can be provisioned on a Docker host. +- CPX runs as the Istio Data Plane component, displacing Envoy as the default data plane service proxy.
    + +### Security & Authentication + +- Meshery has moved from using session authentication to JWT authentication. Meshery's JWT authentication is powered by Hydra Auth. +- You can now opt to authenticate yourself on mesheryctl while performing performance tests using `mesheryctl`, you can authenticate yourself by getting the JWT Token from Meshery UI. + +### Meshery Server + +- Support provided for [wrk2 as an alternative load generator](https://docs.meshery.io/functionality/performance-management#load-generators). +- [Providers](https://docs.meshery.io/extensibility) - A new project construct that allows users to select authentication, long-term storage etc. +- Ad-hoc [connectivity tests for Prometheus and Grafana](https://docs.meshery.io/functionality/performance-management#grafana-and-meshery) are now supported. +- Extraneous information beyond IP address and port in Grafana and Prometheus endpoints have been stripped off. + +### Meshery UI + +- ES-Lint has been added to the client side to ensure the quality of code and increase maintainaiblity of code. +- Cypress has been set-up to enable end-to-end tests and integration tests for Meshery UI. + +
    + + +### Other notable changes + +- From within the [Meshery Continuous Integration Working Group](https://www.youtube.com/watch?v=ds9D2KgZKxo&list=PL3A-A6hPO2IM7rYiKxG4l3eQNc6X3IUex), we have strengthened our continuous integration (CI) actions & tests by introducing new workflows like `static check`, `vet check`, `security check` for our server code. +- ReleaseDrafter & WelcomeBot has been added to the repository to enable automation of release notes and for welcoming new contributors, respectively. + +To get a more comprehensive list of the bug fixes and enhancements packaged in the v0.4.0 release, see the [Meshery Documentation](https://docs.meshery.io/project/releases) + + +_**P.S.: If these topics excite you and you want to explore the beautiful realm of service meshes, come and say "Hi" on our [Slack Channel](http://slack.layer5.io) and one of us will reach out to you!**_ + +
    diff --git a/src/collections/blog/2020/2020-08-11-20-learn-how-to-write-wasm-filters-for-envoy-in-rust-and-deploy-with-consul/index.mdx b/src/collections/blog/2020/2020-08-11-20-learn-how-to-write-wasm-filters-for-envoy-in-rust-and-deploy-with-consul/index.mdx index 4306a69a7804..ee04a4764a3c 100644 --- a/src/collections/blog/2020/2020-08-11-20-learn-how-to-write-wasm-filters-for-envoy-in-rust-and-deploy-with-consul/index.mdx +++ b/src/collections/blog/2020/2020-08-11-20-learn-how-to-write-wasm-filters-for-envoy-in-rust-and-deploy-with-consul/index.mdx @@ -1,28 +1,28 @@ ---- -title: "Learn How to Write WASM Filters" -subtitle: "for Envoy in Rust and Deploy with Consul" -date: 2020-08-11 08:00:00 -0530 -author: Lee Calcote -thumbnail: ./layer5-white-bg.webp -darkthumbnail: ./layer5-white-bg.webp -category: WebAssembly -tags: - - WASM - - WebAssembly - - Rust - - Envoy - - Consul -published: false -redirect_from: - - /blog/webassembly/learn-how-to-write-wasm-filters-for-envoy-in-rust-and-deploy-with-consul/ ---- - -import { BlogWrapper } from "../../Blog.style.js"; - - - - [Image Hub](/projects/image-hub) was built under the vision that most people are not deriving the full potential of a service mesh. - - Whether you identify as a service owner or a product owner, you stand to significantly benefit from the use of a service mesh as the infrastructure running your application. - - +--- +title: "Learn How to Write WASM Filters" +subtitle: "for Envoy in Rust and Deploy with Consul" +date: 2020-08-11 08:00:00 -0530 +author: Lee Calcote +thumbnail: ./layer5-white-bg.webp +darkthumbnail: ./layer5-white-bg.webp +category: WebAssembly +tags: + - WASM + - WebAssembly + - Rust + - Envoy + - Consul +published: false +redirect_from: + - /blog/webassembly/learn-how-to-write-wasm-filters-for-envoy-in-rust-and-deploy-with-consul/ +--- + + + + + + [Image Hub](/projects/image-hub) was built under the vision that most people are not deriving the full potential of a service mesh. + + Whether you identify as a service owner or a product owner, you stand to significantly benefit from the use of a service mesh as the infrastructure running your application. + + diff --git a/src/collections/blog/2020/2020-08-11-my-journey-from-a-contributor-to-a-maintainer/index.mdx b/src/collections/blog/2020/2020-08-11-my-journey-from-a-contributor-to-a-maintainer/index.mdx index ed4acc75128c..6024c7457129 100644 --- a/src/collections/blog/2020/2020-08-11-my-journey-from-a-contributor-to-a-maintainer/index.mdx +++ b/src/collections/blog/2020/2020-08-11-my-journey-from-a-contributor-to-a-maintainer/index.mdx @@ -1,63 +1,63 @@ ---- -title: "My journey from a contributor to a maintainer!" -subtitle: "" -date: 2020-08-11 10:55:05 -0530 -author: Nikhil Ladha -thumbnail: ./pic1.webp -darkthumbnail: ./pic1.webp -category: Community -tags: - - MeshMate - - Community -published: true ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import SignedBook from "./pic2.jpeg"; - - - -Getting involved in something new and essentially avant garde, can be a messy challenge to navigate through. But, when it comes to contributing to Meshery it only gets more and more meshy! - -### Get set go! - -

    I was introduced to the world of open source through the Meshery project in the august of 2019 and have since then been continuously exploring the farthest reaches of Meshery, Layer5, the parent SMI project and consecutively the CNCF landscape. - -At the time of writing this, I have been a part of the Meshery project for about a year. Fascinated by the concept and further lured in by the welcoming community at Layer5, I was soon dipping my toes into the tidal wave of code. Starting out with small contributions to improve the UI, I stumbled on to my first issue, which was to open a page in a new tab instead of opening it in the same tab. Basic, right? - -I’m pointing this out to unravel the myth and smoke clouds around open source projects. Contributing can be as easy as altering a few lines of code and can be as meaningful as writing a whole new feature adapter. Since then, I have crossed small and big hurdles, meandering through countless issues and have become a part of the wholesome community, gaining friends and mentors along the way.

    - -### Stepping stones - -Let’s begin with the basics. What is Layer5? - -Layer5 is the service mesh company, which has built (or is in the process of building) an exhaustive set of projects to delve into the world of cloud native and service meshes with in-depth analyses. Intrigued? Checkout the [Layer5](https://layer5.io/) site and hop on to our [GitHub](https://github.com/layer5io) bandwagon. Before you do me the favor of reading on, make sure to click on the little star :star: button to help us stir up some more delectable meshiness. - -### Roadblocks - -Coming to my contributions at Layer5, I have mostly been involved in improving the UI and shaping the company site’s present outlook. I have also tried my hand at other projects, including the `mesheryctl` and the `landscape` at Layer5. In fact, here is a comprehensive list of **[my contributions across Layer5 projects](https://github.com/issues?page=1&q=is%3Aclosed+author%3ANikhil-Ladha+org%3Alayer5io)**. - -The above mentioned links are just the **visible** contributions made by me. With time, I have grown and was soon approached to become a [MeshMate](/community/meshmates), an initiative which involves few seasoned contributors like me who will hold the hand of a new member and help him/her bridge the gap and take the leap into open source. - -### Tricks of the Trade - -The benefits of being a UI engineer? - -Web developers are required in every company in one meaningful way or the other as every single project needs a frontend to showcase it’s capabilities to the user. Coming to Layer5, the frontend of Meshery is built on React( another masterpiece from Facebook! ), which I learned from scratch when I joined the community. - -Nikhil-ladha-work - -Now, months have passed and with some healthy dedication and hours of staring at thousands of lines of code, I have a good base and practical experience with React, something which you can’t hope to gain from personal projects and require a community for. - -The Layer5 and Meshery websites are built using Jekyll, another technology about which I didn’t have any practical knowledge a couple of months ago. Easier than react and harder than CSS, Jekyll is perfect for the aspiring web developers out there and is also another reason for you to pop over to the Layer5 repo after reading this article. - -### Meshy goodness
    - -My experience at Layer5 has made me proud of the work that we do and has challenged me time and again to reach for higher goals. I still have a hunch that someway or the other my contributions are responsible for getting me an internship at Red Hat! All heads bowed to [Lee Calcote](https://www.linkedin.com/in/leecalcote/) for his presence and guidance and to the Layer5 community for being as amazing as it is. My journey at Layer5 has been an ever growing curve to be honest from just a contributor to a MeshMate to the maintainer of few projects at Layer5. And, true to god this wouldn’t have been possible without the combined effort from me and our very own Lee Calcote. His trust and confidence in me is what encourages me to contribute more and more at Layer5 and see it grow to some next level in the coming future. -Motivated or moved or still confused? - -Want to experience the same feeling and see yourself recognized as an Open-source contributor? - -_**P.S.: If these topics excite you and you want to explore the beautiful realm of service meshes, come and say "Hi" on our [Slack Channel](http://slack.layer5.io) and one of us will reach out to you!**_ - -
    +--- +title: "My journey from a contributor to a maintainer!" +subtitle: "" +date: 2020-08-11 10:55:05 -0530 +author: Nikhil Ladha +thumbnail: ./pic1.webp +darkthumbnail: ./pic1.webp +category: Community +tags: + - MeshMate + - Community +published: true +--- + + +import SignedBook from "./pic2.jpeg"; + + + +Getting involved in something new and essentially avant garde, can be a messy challenge to navigate through. But, when it comes to contributing to Meshery it only gets more and more meshy! + +### Get set go! + +I was introduced to the world of open source through the Meshery project in the august of 2019 and have since then been continuously exploring the farthest reaches of Meshery, Layer5, the parent SMI project and consecutively the CNCF landscape. + +At the time of writing this, I have been a part of the Meshery project for about a year. Fascinated by the concept and further lured in by the welcoming community at Layer5, I was soon dipping my toes into the tidal wave of code. Starting out with small contributions to improve the UI, I stumbled on to my first issue, which was to open a page in a new tab instead of opening it in the same tab. Basic, right? + +I’m pointing this out to unravel the myth and smoke clouds around open source projects. Contributing can be as easy as altering a few lines of code and can be as meaningful as writing a whole new feature adapter. Since then, I have crossed small and big hurdles, meandering through countless issues and have become a part of the wholesome community, gaining friends and mentors along the way. + +### Stepping stones + +Let’s begin with the basics. What is Layer5? + +Layer5 is the service mesh company, which has built (or is in the process of building) an exhaustive set of projects to delve into the world of cloud native and service meshes with in-depth analyses. Intrigued? Checkout the [Layer5](https://layer5.io/) site and hop on to our [GitHub](https://github.com/layer5io) bandwagon. Before you do me the favor of reading on, make sure to click on the little star :star: button to help us stir up some more delectable meshiness. + +### Roadblocks + +Coming to my contributions at Layer5, I have mostly been involved in improving the UI and shaping the company site’s present outlook. I have also tried my hand at other projects, including the `mesheryctl` and the `landscape` at Layer5. In fact, here is a comprehensive list of **[my contributions across Layer5 projects](https://github.com/issues?page=1&q=is%3Aclosed+author%3ANikhil-Ladha+org%3Alayer5io)**. + +The above mentioned links are just the **visible** contributions made by me. With time, I have grown and was soon approached to become a [MeshMate](/community/meshmates), an initiative which involves few seasoned contributors like me who will hold the hand of a new member and help him/her bridge the gap and take the leap into open source. + +### Tricks of the Trade + +The benefits of being a UI engineer? + +Web developers are required in every company in one meaningful way or the other as every single project needs a frontend to showcase it’s capabilities to the user. Coming to Layer5, the frontend of Meshery is built on React( another masterpiece from Facebook! ), which I learned from scratch when I joined the community. + +Nikhil-ladha-work + +Now, months have passed and with some healthy dedication and hours of staring at thousands of lines of code, I have a good base and practical experience with React, something which you can’t hope to gain from personal projects and require a community for. + +The Layer5 and Meshery websites are built using Jekyll, another technology about which I didn’t have any practical knowledge a couple of months ago. Easier than react and harder than CSS, Jekyll is perfect for the aspiring web developers out there and is also another reason for you to pop over to the Layer5 repo after reading this article. + +### Meshy goodness
    + +My experience at Layer5 has made me proud of the work that we do and has challenged me time and again to reach for higher goals. I still have a hunch that someway or the other my contributions are responsible for getting me an internship at Red Hat! All heads bowed to [Lee Calcote](https://www.linkedin.com/in/leecalcote/) for his presence and guidance and to the Layer5 community for being as amazing as it is. My journey at Layer5 has been an ever growing curve to be honest from just a contributor to a MeshMate to the maintainer of few projects at Layer5. And, true to god this wouldn’t have been possible without the combined effort from me and our very own Lee Calcote. His trust and confidence in me is what encourages me to contribute more and more at Layer5 and see it grow to some next level in the coming future. +Motivated or moved or still confused? + +Want to experience the same feeling and see yourself recognized as an Open-source contributor? + +_**P.S.: If these topics excite you and you want to explore the beautiful realm of service meshes, come and say "Hi" on our [Slack Channel](http://slack.layer5.io) and one of us will reach out to you!**_ + +
    diff --git a/src/collections/blog/2020/2020-08-20-announcing-the-meshery-adapter-for-open-service-mesh/index.mdx b/src/collections/blog/2020/2020-08-20-announcing-the-meshery-adapter-for-open-service-mesh/index.mdx index 5a635d7a8583..0c3979b3990b 100644 --- a/src/collections/blog/2020/2020-08-20-announcing-the-meshery-adapter-for-open-service-mesh/index.mdx +++ b/src/collections/blog/2020/2020-08-20-announcing-the-meshery-adapter-for-open-service-mesh/index.mdx @@ -1,47 +1,47 @@ ---- -title: "Announcing the Meshery Adapter for Open Service Mesh" -subtitle: "Adding another service mesh to the landscape and another adapter to Meshery" -date: 2020-08-20 10:17:05 +0000 -author: Lee Calcote -thumbnail: ./meshery-open-service.webp -darkthumbnail: ./meshery-open-service.webp -category: "Service Mesh" -tags: - - Meshery - - Service Mesh -published: true -resource: true -type: Blog -product: Meshery -mesh: Open Service Mesh -redirect_from: - - /blog/meshery/announcing-the-meshery-adapter-for-open-service-mesh/ - - /blog/open-service-mesh/announcing-the-meshery-adapter-for-open-service-mesh ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import conformance from "./conformance-results.webp"; - - - -Released on August 5th, 2020 by Microsoft, [Open Service Mesh](https://openservicemesh.io/) (OSM) is a lightweight and [Service Mesh Interace conformant](https://layer5.io/smi) (SMI). Open Service Mesh is a contemporary addition to the [service mesh landscape](/service-mesh-landscape). Using Envoy as its data plane proxy component and SMI specifications as it's control plane APIs, OSM draws lessons and code from existing service mesh projects, like Linkerd. The Open Service Mesh project has some miles to go as it is one of a growing list of choices available in the service mesh landscape. - -First pronounced to be SMI compliant by [Meshery](https://meshery.io/), the cloud native management plane, the first release of OSM supports a myriad of basic - -
      -
    • Securing service to service links
    • -
    • Supporting traffic shifting
    • -
    • Managing observability for your services
    • -
    • Validating and Implementing access control policies
    • -
    • Auto addition of applications and services
    • -
    - -### Get started with OSM using Meshery -In Layer5's effort to support our multi-mesh world, our Meshery project provides an effortless way for Kubernetes operators to install, maintain and run service meshes. [Meshery v0.4.3](https://github.com/layer5io/meshery/releases/tag/v0.4.3) includes the [Meshery Adapter for Open Service Mesh](https://github.com/layer5io/meshery-osm), enabling you to quickly provision OSM, run any number of sample applications, manage its performance using [Service Mesh Performance](https://smp-spec.io/) (SMP), validate OSM's compliance to SMI using a suite of conformance tests. Meshery offers configuraiton management with builtin best practice configuration analysis giving you confidence in applying custom configuration to OSM. Meshery's documenation on the [Open Service Mesh integation](https://docs.meshery.io/service-meshes/adapters/osm) provides a complete walkthrough on how to get set up, install, deploy and configure OSM according to your needs. - -meshery-smi-conformance-results-image - -Try Open Service Mesh now, by [getting started with Meshery](/cloud-native-management/meshery/getting-started). - - -
    +--- +title: "Announcing the Meshery Adapter for Open Service Mesh" +subtitle: "Adding another service mesh to the landscape and another adapter to Meshery" +date: 2020-08-20 10:17:05 +0000 +author: Lee Calcote +thumbnail: ./meshery-open-service.webp +darkthumbnail: ./meshery-open-service.webp +category: "Service Mesh" +tags: + - Meshery + - Service Mesh +published: true +resource: true +type: Blog +product: Meshery +mesh: Open Service Mesh +redirect_from: + - /blog/meshery/announcing-the-meshery-adapter-for-open-service-mesh/ + - /blog/open-service-mesh/announcing-the-meshery-adapter-for-open-service-mesh +--- + + +import conformance from "./conformance-results.webp"; + + + +Released on August 5th, 2020 by Microsoft, [Open Service Mesh](https://openservicemesh.io/) (OSM) is a lightweight and [Service Mesh Interace conformant](https://layer5.io/smi) (SMI). Open Service Mesh is a contemporary addition to the [service mesh landscape](/service-mesh-landscape). Using Envoy as its data plane proxy component and SMI specifications as it's control plane APIs, OSM draws lessons and code from existing service mesh projects, like Linkerd. The Open Service Mesh project has some miles to go as it is one of a growing list of choices available in the service mesh landscape. + +First pronounced to be SMI compliant by [Meshery](https://meshery.io/), the cloud native management plane, the first release of OSM supports a myriad of basic + +
      +
    • Securing service to service links
    • +
    • Supporting traffic shifting
    • +
    • Managing observability for your services
    • +
    • Validating and Implementing access control policies
    • +
    • Auto addition of applications and services
    • +
    + +### Get started with OSM using Meshery +In Layer5's effort to support our multi-mesh world, our Meshery project provides an effortless way for Kubernetes operators to install, maintain and run service meshes. [Meshery v0.4.3](https://github.com/layer5io/meshery/releases/tag/v0.4.3) includes the [Meshery Adapter for Open Service Mesh](https://github.com/layer5io/meshery-osm), enabling you to quickly provision OSM, run any number of sample applications, manage its performance using [Service Mesh Performance](https://smp-spec.io/) (SMP), validate OSM's compliance to SMI using a suite of conformance tests. Meshery offers configuraiton management with builtin best practice configuration analysis giving you confidence in applying custom configuration to OSM. Meshery's documenation on the [Open Service Mesh integation](https://docs.meshery.io/service-meshes/adapters/osm) provides a complete walkthrough on how to get set up, install, deploy and configure OSM according to your needs. + +meshery-smi-conformance-results-image + +Try Open Service Mesh now, by [getting started with Meshery](/cloud-native-management/meshery/getting-started). + + +
    diff --git a/src/collections/blog/2020/2020-09-19-performance-benchmarking-using-meshery-and-nighthawk/index.mdx b/src/collections/blog/2020/2020-09-19-performance-benchmarking-using-meshery-and-nighthawk/index.mdx index 3e1d5e31e59b..cd8dcb42a738 100644 --- a/src/collections/blog/2020/2020-09-19-performance-benchmarking-using-meshery-and-nighthawk/index.mdx +++ b/src/collections/blog/2020/2020-09-19-performance-benchmarking-using-meshery-and-nighthawk/index.mdx @@ -1,76 +1,76 @@ ---- -title: "Performance benchmarking using Meshery and Nighthawk" -subtitle: "" -date: 2020-09-19 11:00:05 +0530 -author: Layer5 Team -thumbnail: ./mesheryctl.webp -darkthumbnail: ./mesheryctl.webp -category: Performance -tags: - - Nighthawk - - Performance - - Service Mesh Performance - - Meshery -published: true -type: Blog -product: Nighthawk -resource: true -redirect_from: - - /blog/performance-benchmarking-using-meshery-and-nighthawk/ ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import smpImg from "./smp.webp"; - - - -### What is performance benchmarking and why should you care? - -Many of you may remember that the HBO streaming service crashed when the final season of the popular sitcom, Game of Thrones went live on the service. Unable to engage all the user requests, the streaming service and the website broke down and ultimately resulted in DoS (Denial of Service). There are numerous examples of service crashes across different platforms, which has forced developers to take a closer look at performance benchmarking and pre-launch performance checks. - -There are several advantages of preliminary service benchmarking, which may extensively enhance the response time, resolve glitches, enhance the application's robustness, and bring together several other commendable factors, including but not limited to stability and dependability within an application. - -There are several tools for performance benchmarking. A major one is the interconnected relationship between load generators and benchmarks. Some of the well-known load generators in the cloud native realm are: - - - -The conclusion can be encapsulated as following, Meshery, the cloud native management plane possesses the ability to generate load and benchmark services in/out of your service mesh using Fortio, Wrk2 and now, Nighthawk too. - -### Meshery + Nighthawk = Robust Distributed and Scalable Services - -Nighthawk, written and maintained by the Envoy Community, is a L7 (HTTP/HTTPS/HTTP2) performance characterization tool that supports performance benchmarking using HTTP or gRPC services. - -Nighthawk is built using open-source builds and test tool Bazel and supports output formatting to well-known formats, allowing integration with other systems and dashboards. To add more to the list, it will soon support distributed performance benchmarking which is currently under an active development stage. - -On the other hand, Meshery, written and maintainer by Layer5 Community is the multi-service mesh management plane offering lifecycle, configuration and performance management of service meshes and their workloads. With Meshery, you can both, manage your service mesh's lifecycle, and benchmark them with industry-grade tools to let you know how much under or over-utilized your services are. - -smp-image - -Soon, Meshery is going to be a canonical implementation for [Service Mesh Performance](https://github.com/layer5io/service-mesh-performance) which is a common and standardised format to describe : - Performance test configuration - Service mesh configuration - Environment configuration - Workload configuration - Performance test results. - -### How did we achieve it ? -The following project was proposed as a Google Summer of Code Idea, I was selected as a student mentee to draft the design, architecture and code my way from scratch. On my journey, I received guidance from some amazing mentors, colleagues and open-source stake holders. I discussed the design proposal with Envoy Team as well as Layer5 Team and from suggestions from both, I was able to complete my project. - -In the course of the project, I came up with the idea of invoking Nighthawk as a separate container with which Meshery will communicate using a go-lang based middleware. - -To my elation, the project was a huge success and Nighthawk is now invoked as a load-generator in Meshery. Soon, the public release for the new version will be made and users will be able to utilize Nighthawk as a performance-benchamark tool alongside with Fortio and Wrk2. - -### What's next? -This is just the first relay, in the long run, there are many more milestones to come. The following is a list of projects which will be completed in upcoming months: - -- Invoke Nighthawk as an gRPC Service and support gRPC connection between Nighthawk & Meshery. -- Implement user-profiles for performance benchmarking which may store some preset preferred values according to users. -- Enhance Nighthawk to support distributed load generation and performance benchmarking. -- NATS & gRPC Performance Benchmarking for gRPC and NATS services invoked in Meshery. - -and many more awesome and bleeding-edge ideas. - -### How can I get involved? -If any of this sounds remotely exciting, I implore you to give this a chance. You won’t regret it. Head over to our [Slack Channel](http://slack.layer5.io) and join the #performance channel where everything related to performance testing is discussed. We would love to hear your feedback. Stay tuned for more blogs related to Performance Benchmarking, SMI Conformance and all things meshy!!! - - - +--- +title: "Performance benchmarking using Meshery and Nighthawk" +subtitle: "" +date: 2020-09-19 11:00:05 +0530 +author: Layer5 Team +thumbnail: ./mesheryctl.webp +darkthumbnail: ./mesheryctl.webp +category: Performance +tags: + - Nighthawk + - Performance + - Service Mesh Performance + - Meshery +published: true +type: Blog +product: Nighthawk +resource: true +redirect_from: + - /blog/performance-benchmarking-using-meshery-and-nighthawk/ +--- + + +import smpImg from "./smp.webp"; + + + +### What is performance benchmarking and why should you care? + +Many of you may remember that the HBO streaming service crashed when the final season of the popular sitcom, Game of Thrones went live on the service. Unable to engage all the user requests, the streaming service and the website broke down and ultimately resulted in DoS (Denial of Service). There are numerous examples of service crashes across different platforms, which has forced developers to take a closer look at performance benchmarking and pre-launch performance checks. + +There are several advantages of preliminary service benchmarking, which may extensively enhance the response time, resolve glitches, enhance the application's robustness, and bring together several other commendable factors, including but not limited to stability and dependability within an application. + +There are several tools for performance benchmarking. A major one is the interconnected relationship between load generators and benchmarks. Some of the well-known load generators in the cloud native realm are: + + + +The conclusion can be encapsulated as following, Meshery, the cloud native management plane possesses the ability to generate load and benchmark services in/out of your service mesh using Fortio, Wrk2 and now, Nighthawk too. + +### Meshery + Nighthawk = Robust Distributed and Scalable Services + +Nighthawk, written and maintained by the Envoy Community, is a L7 (HTTP/HTTPS/HTTP2) performance characterization tool that supports performance benchmarking using HTTP or gRPC services. + +Nighthawk is built using open-source builds and test tool Bazel and supports output formatting to well-known formats, allowing integration with other systems and dashboards. To add more to the list, it will soon support distributed performance benchmarking which is currently under an active development stage. + +On the other hand, Meshery, written and maintainer by Layer5 Community is the multi-service mesh management plane offering lifecycle, configuration and performance management of service meshes and their workloads. With Meshery, you can both, manage your service mesh's lifecycle, and benchmark them with industry-grade tools to let you know how much under or over-utilized your services are. + +smp-image + +Soon, Meshery is going to be a canonical implementation for [Service Mesh Performance](https://github.com/layer5io/service-mesh-performance) which is a common and standardised format to describe : - Performance test configuration - Service mesh configuration - Environment configuration - Workload configuration - Performance test results. + +### How did we achieve it ? +The following project was proposed as a Google Summer of Code Idea, I was selected as a student mentee to draft the design, architecture and code my way from scratch. On my journey, I received guidance from some amazing mentors, colleagues and open-source stake holders. I discussed the design proposal with Envoy Team as well as Layer5 Team and from suggestions from both, I was able to complete my project. + +In the course of the project, I came up with the idea of invoking Nighthawk as a separate container with which Meshery will communicate using a go-lang based middleware. + +To my elation, the project was a huge success and Nighthawk is now invoked as a load-generator in Meshery. Soon, the public release for the new version will be made and users will be able to utilize Nighthawk as a performance-benchamark tool alongside with Fortio and Wrk2. + +### What's next? +This is just the first relay, in the long run, there are many more milestones to come. The following is a list of projects which will be completed in upcoming months: + +- Invoke Nighthawk as an gRPC Service and support gRPC connection between Nighthawk & Meshery. +- Implement user-profiles for performance benchmarking which may store some preset preferred values according to users. +- Enhance Nighthawk to support distributed load generation and performance benchmarking. +- NATS & gRPC Performance Benchmarking for gRPC and NATS services invoked in Meshery. + +and many more awesome and bleeding-edge ideas. + +### How can I get involved? +If any of this sounds remotely exciting, I implore you to give this a chance. You won’t regret it. Head over to our [Slack Channel](http://slack.layer5.io) and join the #performance channel where everything related to performance testing is discussed. We would love to hear your feedback. Stay tuned for more blogs related to Performance Benchmarking, SMI Conformance and all things meshy!!! + + + diff --git a/src/collections/blog/2020/2020-09-25-announcing-meshmates/index.mdx b/src/collections/blog/2020/2020-09-25-announcing-meshmates/index.mdx index bbe89e595a65..b5e2bbcb0446 100644 --- a/src/collections/blog/2020/2020-09-25-announcing-meshmates/index.mdx +++ b/src/collections/blog/2020/2020-09-25-announcing-meshmates/index.mdx @@ -1,137 +1,137 @@ ---- -title: "Announcing a new line of MeshMates" -date: 2020-09-25 08:00:00 +0000 -author: Our MeshMates with 🤍 -thumbnail: ./meshmate-announcement.webp -darkthumbnail: ./meshmate-announcement.webp -category: Announcements -tags: - - Community - - MeshMate -published: true -redirect_from: - - /blog/community/announcing-meshmates/ ---- - -import { Link } from "gatsby"; - -import Ruth from "./meshmate-ruth-ikegah.webp"; -import Kelechi from "./meshmate-kelechi-precious.webp"; -import Tanuj from "./meshmate-tanuj-agarwal.webp"; - -import { BlogWrapper } from "../../Blog.style.js"; - - - -

    Layer5 MeshMates are committed to helping community members be successful contributors. MeshMates aid in identifying areas of projects to engage within, working groups to join, and in helping community members grow in their open source and cloud native knowledge. By connecting one-on-one, MeshMates will share tips on how to have the best community experience possible.

    - -

    - - Tanuj Agarwal - -

    - tanuj-agarwal -

    - I was introduced to the Layer5 community three months back. Being fairly new - to the world of open source and looking for new communities and technology to - delve into, I hopped onto the Layer5 bandwagon and was amazed by the warm - welcome I received from the wholesome community. I had done video animation - jobs on a small scale before, which is what led me to confidently take up the - task of creating a short intro jingle for the various community meetings - hosted on the Layer5 youtube channel. After iterating for about a week, I - finally came up with something worthwhile. And to my elation, it was accepted! - It still warms my heart to see the intro flash before every meeting. -

    -

    - Next up I started work on a next generation model of the layer5.io site. Being - a new project based on Gatsby and heavily relying on React, Javascript and - GraphQL, the site project was a perfect and challenging opportunity for me to - expand on my skill set. Speed learning my way through Gatsby, with a - continuous influx of help and helpful suggestions from my MeshMate, Kush - Trivedi and others within the community, I soon mastered the platform and have - spent weeks on creating countless issues and PRs in hopes of achieving the - project goals. A few months down the line, I started reviewing PRs and began - helping others contribute, something which I had never had the opportunity to - do before! After months of continuous effort, I am proud to write that I - recently joined as a maintainer on the project and was soon approached to be a - MeshMate, which I happily accepted. My learning graph has seen a soaring - positive tangent in the months I have been at Layer5 and I’m looking forward - to an even more educative and rewarding journey ahead 😊 -

    -
    -

    - - Kelechi Precious Nwachukwu - -

    - kelechi-precious -

    - It was the middle of the COVID-19 pandemic and being unproductive wasn't - something I can stomach. Wanting to expand on my technical domain knowledge, I - stumbled across an open-source challenge for women in tech with lists of - projects to contribute to by the Women of Open Source Community Africa - (WOSCA). My eyes landed on Layer5 and I haven’t looked back since. -

    -

    - A quick look through the repositories left me quaking in my boots. To give you - some much needed context and to give some hope to all the newbies out there, I - recently transitioned to working in technical domains from accounting and - managing construction site projects. Forever getting stuck trying to get my - hands on new tech and trying to find a way into the bewildering and humongous - tech domains , I didn't even understand some of the jargon, and was too - ashamed to ask questions. Stumbling through my first contribution, I somehow - made it to the finish line and to my happiness, was soon assigned another - task. Instead of complaining, I set out to study up on the issue and took a - peek at the other assignees in the repository to ensure that I was not the - only one taking inordinate amounts of time on an issue. To my surprise, I was - not. -

    -

    - I got working on the assignment and soon encountered issues that would - previously have made me quit. Thankfully, I decided to take a different - approach this time. I shared my challenge with the Layer5 community, and was - amazed at the immediate and abundant response I received. Since then, I have - helped other contributors get through their challenges, and have received an - invitation to join the organization as a member, and then as a MeshMate 😎 I - have been wholly satisfied with the learning opportunities and the friendly - environment that the Layer5 community has to offer. I have learned that I may - not be perfect, but by making full use of the resources provided to me, having - a supportive community by my side and by being open to learning and showing - determined courage in the face of difficulties, I can achieve anything! -

    -

    - Ruth Ikegah -

    - ruth-ikegah -

    - The field of open source had always been intriguing to me. The idea of a - close-knit community working with an aim had me wanting to contribute myself. - Considering the fact that I have a small skill set (Donned the coder hat only - 6 months ago), Layer5 was a great community for me to start out with. I came - to know about the Layer5 community from the She Code Africa slack channel, - after which I visited the GitHub repository and hopped on to the Layer5 slack channel. -

    -

    - To my good luck, I received a warm welcome from the community and was able to attend a community meeting the day I joined. I made my way through the Github repos and stumbled across a beginner friendly issue. I started work but to my dismay, my PR failed to pass the DCO check at the final rung. Stuck and with low spirits, I talked to Lee (Layer5 Maintainer) and related my problems with the DCO check fail. He patiently assured me that first-time checks can be hard to get right and assigned me a MeshMate, Ashis Singh (read saviour 😳). I sent a message to Ashis and told him about the issues I was having in submitting my Pull Request. He led me through a step by step tutorial on committing and signing off my changes, after which my first PR passed all the checks. I was thrilled at this point, waiting for my PR to be merged. I soon received two emails, the first relaying that my PR had been merged and a few pull requests later, a second one with an invitation to join the Layer5 organization on Github. -

    -

    - Impressed by the process and being passionate about helping others, I soon - began helping out with welcoming newcomers in the Layer5 Community and a happy two months later, I am elated to write that I have helped and held the hand of many-a contributors into Open-Source, offering them the same warm welcome that I had received. I was soon promoted to become a MeshMate. Apart from adding another feather to my cap, this also helped me enhance my own skill set and reach in a dozen different directions.The most intriguing fact about the Layer5 community is how welcoming it is. You can contribute something, even as a beginner, no matter how small your skillset is. I have been through the same journey and I recommend it to everyone reading. Experience an open-source community with Layer5 today! Once you’re set up on Slack, do send me a ping to - say hi. The exciting part, we might even meet as MeshMates 😉 -

    - - \- Tanuj, Ruth, and Kelechi - -
    +--- +title: "Announcing a new line of MeshMates" +date: 2020-09-25 08:00:00 +0000 +author: Our MeshMates with 🤍 +thumbnail: ./meshmate-announcement.webp +darkthumbnail: ./meshmate-announcement.webp +category: Announcements +tags: + - Community + - MeshMate +published: true +redirect_from: + - /blog/community/announcing-meshmates/ +--- + + + +import Ruth from "./meshmate-ruth-ikegah.webp"; +import Kelechi from "./meshmate-kelechi-precious.webp"; +import Tanuj from "./meshmate-tanuj-agarwal.webp"; + + + + + +

    Layer5 MeshMates are committed to helping community members be successful contributors. MeshMates aid in identifying areas of projects to engage within, working groups to join, and in helping community members grow in their open source and cloud native knowledge. By connecting one-on-one, MeshMates will share tips on how to have the best community experience possible.

    + +

    + + Tanuj Agarwal + +

    + tanuj-agarwal +

    + I was introduced to the Layer5 community three months back. Being fairly new + to the world of open source and looking for new communities and technology to + delve into, I hopped onto the Layer5 bandwagon and was amazed by the warm + welcome I received from the wholesome community. I had done video animation + jobs on a small scale before, which is what led me to confidently take up the + task of creating a short intro jingle for the various community meetings + hosted on the Layer5 youtube channel. After iterating for about a week, I + finally came up with something worthwhile. And to my elation, it was accepted! + It still warms my heart to see the intro flash before every meeting. +

    +

    + Next up I started work on a next generation model of the layer5.io site. Being + a new project based on Gatsby and heavily relying on React, Javascript and + GraphQL, the site project was a perfect and challenging opportunity for me to + expand on my skill set. Speed learning my way through Gatsby, with a + continuous influx of help and helpful suggestions from my MeshMate, Kush + Trivedi and others within the community, I soon mastered the platform and have + spent weeks on creating countless issues and PRs in hopes of achieving the + project goals. A few months down the line, I started reviewing PRs and began + helping others contribute, something which I had never had the opportunity to + do before! After months of continuous effort, I am proud to write that I + recently joined as a maintainer on the project and was soon approached to be a + MeshMate, which I happily accepted. My learning graph has seen a soaring + positive tangent in the months I have been at Layer5 and I’m looking forward + to an even more educative and rewarding journey ahead 😊 +

    +
    +

    + + Kelechi Precious Nwachukwu + +

    + kelechi-precious +

    + It was the middle of the COVID-19 pandemic and being unproductive wasn't + something I can stomach. Wanting to expand on my technical domain knowledge, I + stumbled across an open-source challenge for women in tech with lists of + projects to contribute to by the Women of Open Source Community Africa + (WOSCA). My eyes landed on Layer5 and I haven’t looked back since. +

    +

    + A quick look through the repositories left me quaking in my boots. To give you + some much needed context and to give some hope to all the newbies out there, I + recently transitioned to working in technical domains from accounting and + managing construction site projects. Forever getting stuck trying to get my + hands on new tech and trying to find a way into the bewildering and humongous + tech domains , I didn't even understand some of the jargon, and was too + ashamed to ask questions. Stumbling through my first contribution, I somehow + made it to the finish line and to my happiness, was soon assigned another + task. Instead of complaining, I set out to study up on the issue and took a + peek at the other assignees in the repository to ensure that I was not the + only one taking inordinate amounts of time on an issue. To my surprise, I was + not. +

    +

    + I got working on the assignment and soon encountered issues that would + previously have made me quit. Thankfully, I decided to take a different + approach this time. I shared my challenge with the Layer5 community, and was + amazed at the immediate and abundant response I received. Since then, I have + helped other contributors get through their challenges, and have received an + invitation to join the organization as a member, and then as a MeshMate 😎 I + have been wholly satisfied with the learning opportunities and the friendly + environment that the Layer5 community has to offer. I have learned that I may + not be perfect, but by making full use of the resources provided to me, having + a supportive community by my side and by being open to learning and showing + determined courage in the face of difficulties, I can achieve anything! +

    +

    + Ruth Ikegah +

    + ruth-ikegah +

    + The field of open source had always been intriguing to me. The idea of a + close-knit community working with an aim had me wanting to contribute myself. + Considering the fact that I have a small skill set (Donned the coder hat only + 6 months ago), Layer5 was a great community for me to start out with. I came + to know about the Layer5 community from the She Code Africa slack channel, + after which I visited the GitHub repository and hopped on to the Layer5 slack channel. +

    +

    + To my good luck, I received a warm welcome from the community and was able to attend a community meeting the day I joined. I made my way through the Github repos and stumbled across a beginner friendly issue. I started work but to my dismay, my PR failed to pass the DCO check at the final rung. Stuck and with low spirits, I talked to Lee (Layer5 Maintainer) and related my problems with the DCO check fail. He patiently assured me that first-time checks can be hard to get right and assigned me a MeshMate, Ashis Singh (read saviour 😳). I sent a message to Ashis and told him about the issues I was having in submitting my Pull Request. He led me through a step by step tutorial on committing and signing off my changes, after which my first PR passed all the checks. I was thrilled at this point, waiting for my PR to be merged. I soon received two emails, the first relaying that my PR had been merged and a few pull requests later, a second one with an invitation to join the Layer5 organization on Github. +

    +

    + Impressed by the process and being passionate about helping others, I soon + began helping out with welcoming newcomers in the Layer5 Community and a happy two months later, I am elated to write that I have helped and held the hand of many-a contributors into Open-Source, offering them the same warm welcome that I had received. I was soon promoted to become a MeshMate. Apart from adding another feather to my cap, this also helped me enhance my own skill set and reach in a dozen different directions.The most intriguing fact about the Layer5 community is how welcoming it is. You can contribute something, even as a beginner, no matter how small your skillset is. I have been through the same journey and I recommend it to everyone reading. Experience an open-source community with Layer5 today! Once you’re set up on Slack, do send me a ping to + say hi. The exciting part, we might even meet as MeshMates 😉 +

    + + \- Tanuj, Ruth, and Kelechi + +
    diff --git a/src/collections/blog/2020/2020-09-25-announcing-meshmates/meshmates.webp b/src/collections/blog/2020/2020-09-25-announcing-meshmates/meshmates.webp new file mode 100644 index 000000000000..de157ff26b79 Binary files /dev/null and b/src/collections/blog/2020/2020-09-25-announcing-meshmates/meshmates.webp differ diff --git a/src/collections/blog/2020/2020-11-17-layer5-at-kubecon-2020/index.mdx b/src/collections/blog/2020/2020-11-17-layer5-at-kubecon-2020/index.mdx index bb4535fce805..e00eed8b1244 100644 --- a/src/collections/blog/2020/2020-11-17-layer5-at-kubecon-2020/index.mdx +++ b/src/collections/blog/2020/2020-11-17-layer5-at-kubecon-2020/index.mdx @@ -1,92 +1,91 @@ ---- -title: "Layer5 at KubeCon NA" -subtitle: "Join us at KubeCon North America 2020" -date: 2020-11-17 11:10:00 +0000 -author: Lee Calcote -thumbnail: ./kubecon-layer5.webp -darkthumbnail: ./kubecon-layer5.webp -category: Announcements -tags: - - KubeCon -published: true -redirect_from: - - /blog/layer5-at-kubecon-na-2020/ ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import kubecon1 from "./kubecon1.webp"; -import kubecon2 from "./kubecon2.webp"; -import kubecon3 from "./kubecon3.webp"; - - - -

    - Thanks to our open source contributors, Layer5 projects are well represented - at KubeCon. Attend our talks to help you get started with managing your own - service mesh! -

    - -

    - KubeCon + CloudNativeCon NA 2020 is here and Layer5 is in the spotlight! -

    - - - Service Mesh Specifications and Why They Matter in your Deployment{" "} - - - -

    November 18, 2020

    -As the ubiquity of service meshes unfolds so does the need for vendor and technology-agnostic -interfaces to interact with them. The following three open specifications solving -the challenge of interoperability, workload and performance management between service -meshes: Service Mesh Performance (SMP) and Service Mesh Interface (SMI), Multi-Vendor -Service Mesh Interoperation (Hamlet). Attend to learn what makes each of these specifications -unique and why they are very much needed. - -
    -
    - - - CNCF SIG Network: Intro and Deep-Dive - - -

    November 20, 2020

    -It’s the network! is the cry of every system administrator, every -developer. With the increased prevalence of - {" "} - -microservice-based distributed systems, it’s true - networking as a discipline -has never been more critical in the efficient operation of cloud native -deployments. Networking primitives, including load balancing, observability, -authentication, authorization, policy, rate limiting, QoS, mesh networks, legacy -infrastructure bridging, and so on are now receiving substantial development and -investment throughout the industry and are the subject of focus of the CNCF SIG -Network. - -See what the CNCF's Service Mesh Working Group has been up to. Join this talk for an intro to the SIG, its charter and a deeper discussion of current cloud native networking topics being advanced in this SIG. Current CNCF projects in-scope: Open Service Mesh, Kuma, Chaos Mesh, Ambassador, CNI, CoreDNS, Envoy, gRPC, Linkerd, NATS, Network Service Mesh. - - - - - -
    - - Meet the Maintainers: Service Mesh Interface - - -

    November 17, 2020

    -Join the Service Mesh Interface (SMI) and Meshery maintainers for a Meet the Maintainers -office hours. Learn all about Service Mesh Interface and how Meshery is the service -mesh manager to determine the conformance of all service meshes in or out of compliance -with the specification. -
    -
    -
    - -

    - We hope to see you at KubeCon + CloudNativeCon NA 2020. Be sure to say hello - in the Layer5 Community! -

    - - -
    +--- +title: "Layer5 at KubeCon NA" +subtitle: "Join us at KubeCon North America 2020" +date: 2020-11-17 11:10:00 +0000 +author: Lee Calcote +thumbnail: ./kubecon-layer5.webp +darkthumbnail: ./kubecon-layer5.webp +category: Announcements +tags: + - KubeCon +published: true +redirect_from: + - /blog/layer5-at-kubecon-na-2020/ +--- + + +import kubecon1 from "./kubecon1.webp"; +import kubecon2 from "./kubecon2.webp"; +import kubecon3 from "./kubecon3.webp"; + + + +

    + Thanks to our open source contributors, Layer5 projects are well represented + at KubeCon. Attend our talks to help you get started with managing your own + service mesh! +

    + +

    + KubeCon + CloudNativeCon NA 2020 is here and Layer5 is in the spotlight! +

    + + + Service Mesh Specifications and Why They Matter in your Deployment{" "} + + + +

    November 18, 2020

    +As the ubiquity of service meshes unfolds so does the need for vendor and technology-agnostic +interfaces to interact with them. The following three open specifications solving +the challenge of interoperability, workload and performance management between service +meshes: Service Mesh Performance (SMP) and Service Mesh Interface (SMI), Multi-Vendor +Service Mesh Interoperation (Hamlet). Attend to learn what makes each of these specifications +unique and why they are very much needed. + +
    +
    + + + CNCF SIG Network: Intro and Deep-Dive + + +

    November 20, 2020

    +It’s the network! is the cry of every system administrator, every +developer. With the increased prevalence of + {" "} +microservice-based distributed systems, it’s true - networking as a discipline +has never been more critical in the efficient operation of cloud native +deployments. Networking primitives, including load balancing, observability, +authentication, authorization, policy, rate limiting, QoS, mesh networks, legacy +infrastructure bridging, and so on are now receiving substantial development and +investment throughout the industry and are the subject of focus of the CNCF SIG +Network. + +See what the CNCF's Service Mesh Working Group has been up to. Join this talk for an intro to the SIG, its charter and a deeper discussion of current cloud native networking topics being advanced in this SIG. Current CNCF projects in-scope: Open Service Mesh, Kuma, Chaos Mesh, Ambassador, CNI, CoreDNS, Envoy, gRPC, Linkerd, NATS, Network Service Mesh. + + + + + +
    + + Meet the Maintainers: Service Mesh Interface + + +

    November 17, 2020

    +Join the Service Mesh Interface (SMI) and Meshery maintainers for a Meet the Maintainers +office hours. Learn all about Service Mesh Interface and how Meshery is the service +mesh manager to determine the conformance of all service meshes in or out of compliance +with the specification. +
    +
    +
    + +

    + We hope to see you at KubeCon + CloudNativeCon NA 2020. Be sure to say hello + in the Layer5 Community! +

    + + +
    diff --git a/src/collections/blog/2020/2020-12-16-functional-testing-with-cypress-in-Meshery-ui/index.mdx b/src/collections/blog/2020/2020-12-16-functional-testing-with-cypress-in-Meshery-ui/index.mdx index e6bc64ffebd4..620a720d6d4f 100644 --- a/src/collections/blog/2020/2020-12-16-functional-testing-with-cypress-in-Meshery-ui/index.mdx +++ b/src/collections/blog/2020/2020-12-16-functional-testing-with-cypress-in-Meshery-ui/index.mdx @@ -1,113 +1,113 @@ ---- -title: "Functional Testing with Cypress in Meshery UI" -subtitle: "" -date: 2020-12-16 11:10:00 +0000 -author: Rodolfo Martinez Vega -thumbnail: ./cypress-logo.webp -darkthumbnail: ./cypress-logo.webp -category: Meshery -tags: - - Testing - - UI -type: Blog -product: Meshery -resource: true -published: true ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import bestPracticesSelectingElementsImg from './best-practices-selecting-elements.webp'; -import cypressTestRunnerImg from './cypress-test-runner.webp'; - - - -Cypress is the functional test tool used in development of Meshery UI. As a reliably test tool, Cypress works with ReactJS, VueJS, AngularJS and so on; it is agnostic of the framework you use. You can write all types of tests: end-to-end, integration, and unit tests. - -Tests allow you to ensure that the new code do not break the current one. They help you to develop and integrate new features faster and ensure everything will work after including your changes. The more tests you have, the more coverage you will have (and less likelihood of issues in production). - -### UI tests in Meshery - -Meshery has two web projects: - -- provider-ui: A ReactJS app that allows you to select the Provider to be used for Meshery -- ui: Also a ReactJS app where you can do everything related with Meshery. It is the cloud native management plane. - -We create UI tests for both projects using Cypress. Also, we write two types of UI tests at the moment: -- Integration: Test a specific functionality without backend communication (mocking requests and responses) -- End-to-end: Test a whole flow like setting up Linkerd Service Mesh or running a SMI Performance Test sending requests and validating the responses from the back-end - -### How to write UI tests for Meshery - -If you are writting your first test, you can read and watch the great getting started from Cypress blog. - -Then, you have to add your test below `"provider-ui/cypress/integration"` or `"ui/cypress/integration"` folders (do not forget adding _spec in the filename). - -Here is a basic example of a test validating that Provider UI component exists: - -```javascript -describe('Provider UI', () => { - it('renders provider component', () => { - cy - .get('[data-cy=root]') - .should('exist') - }) -}) -``` - -Please follow the best practices recommended by Cypress. -One of the most important is to use or add the `"data-cy"` attribute to the element you want to interact to: - -Best Practices selecting elements with Cypress -

    Best Practices Selecting Elements

    - -### Run your test! - -Once you have written your test, it is time to execute it locally: - -1. First, you have to run the back-end executing this command at the root project folder: - -```bash -$ make run-local -``` - -2. Then, run the front-end project (i.e. provider-ui) - -```bash -$ make run-provider-ui-dev -``` - -3. Finally, in `"provider-ui"` folder, run all the tests with: - -```bash -$ npm run cy:run -``` - -If everything went well, you will see "All specs passed!" message. Congrats! - -You can also execute, debug and see in real time your test by executing: - -```bash -$ npm run cy:open -``` - -this will open the Cypress Test Runner: - -Cypress Test Runner -

    Cypress Test Runner

    - -just double-click on your test and a window browser will be opened and you will see your testing running! - -#### What’s next? - -To improve writting better tests, I recommend that you watch: - -- Watch the Meshery Development Meeting (Nov 4th, 2020) where I gave a demo running UI tests on the Meshery project (slides) -- Tutorial Videos from Cypress blog. -- The Brian Mann – I see your point, but… (Part 1) YouTube video where he gives pro tips writting tests in Cypress. - -If you have questions, do not hesitate to ask to the Meshery community on Slack :) - -Happy testing! - - -
    +--- +title: "Functional Testing with Cypress in Meshery UI" +subtitle: "" +date: 2020-12-16 11:10:00 +0000 +author: Rodolfo Martinez Vega +thumbnail: ./cypress-logo.webp +darkthumbnail: ./cypress-logo.webp +category: Meshery +tags: + - Testing + - UI +type: Blog +product: Meshery +resource: true +published: true +--- + + +import bestPracticesSelectingElementsImg from "./best-practices-selecting-elements.webp"; +import cypressTestRunnerImg from "./cypress-test-runner.webp"; + + + +Cypress is the functional test tool used in development of Meshery UI. As a reliably test tool, Cypress works with ReactJS, VueJS, AngularJS and so on; it is agnostic of the framework you use. You can write all types of tests: end-to-end, integration, and unit tests. + +Tests allow you to ensure that the new code do not break the current one. They help you to develop and integrate new features faster and ensure everything will work after including your changes. The more tests you have, the more coverage you will have (and less likelihood of issues in production). + +### UI tests in Meshery + +Meshery has two web projects: + +- provider-ui: A ReactJS app that allows you to select the Provider to be used for Meshery +- ui: Also a ReactJS app where you can do everything related with Meshery. It is the cloud native management plane. + +We create UI tests for both projects using Cypress. Also, we write two types of UI tests at the moment: +- Integration: Test a specific functionality without backend communication (mocking requests and responses) +- End-to-end: Test a whole flow like setting up Linkerd Service Mesh or running a SMI Performance Test sending requests and validating the responses from the back-end + +### How to write UI tests for Meshery + +If you are writting your first test, you can read and watch the great getting started from Cypress blog. + +Then, you have to add your test below `"provider-ui/cypress/integration"` or `"ui/cypress/integration"` folders (do not forget adding _spec in the filename). + +Here is a basic example of a test validating that Provider UI component exists: + +``` +describe('Provider UI', () => { + it('renders provider component', () => { + cy + .get('[data-cy=root]') + .should('exist') + }) +}) +``` + +Please follow the best practices recommended by Cypress. +One of the most important is to use or add the `"data-cy"` attribute to the element you want to interact to: + +Best Practices selecting elements with Cypress +

    Best Practices Selecting Elements

    + +### Run your test! + +Once you have written your test, it is time to execute it locally: + +1. First, you have to run the back-end executing this command at the root project folder: + +```bash +$ make run-local +``` + +2. Then, run the front-end project (i.e. provider-ui) + +```bash +$ make run-provider-ui-dev +``` + +3. Finally, in `"provider-ui"` folder, run all the tests with: + +```bash +$ npm run cy:run +``` + +If everything went well, you will see "All specs passed!" message. Congrats! + +You can also execute, debug and see in real time your test by executing: + +```bash +$ npm run cy:open +``` + +this will open the Cypress Test Runner: + +Cypress Test Runner +

    Cypress Test Runner

    + +just double-click on your test and a window browser will be opened and you will see your testing running! + +#### What’s next? + +To improve writting better tests, I recommend that you watch: + +- Watch the Meshery Development Meeting (Nov 4th, 2020) where I gave a demo running UI tests on the Meshery project (slides) +- Tutorial Videos from Cypress blog. +- The Brian Mann – I see your point, but… (Part 1) YouTube video where he gives pro tips writting tests in Cypress. + +If you have questions, do not hesitate to ask to the Meshery community on Slack :) + +Happy testing! + + +
    diff --git a/src/collections/blog/2021/2021-02-04-meet-the-maintainer-michael-gfeller/index.mdx b/src/collections/blog/2021/2021-02-04-meet-the-maintainer-michael-gfeller/index.mdx index c6d2f838658a..a520c898f8c5 100644 --- a/src/collections/blog/2021/2021-02-04-meet-the-maintainer-michael-gfeller/index.mdx +++ b/src/collections/blog/2021/2021-02-04-meet-the-maintainer-michael-gfeller/index.mdx @@ -1,193 +1,181 @@ ---- -title: "Meet the Maintainer: Michael Gfeller" -subtitle: "An interview series with Layer5 Maintainers" -date: 2021-02-04 10:30:05 -0530 -author: Shriti Chandra -thumbnail: "./michael-gfeller-layer5-maintainer.webp" -darkthumbnail: "./michael-gfeller-layer5-maintainer.webp" -category: "Community" -tags: - - Community -published: true -interviewer: Shriti Chandra -interviewee: Michael Gfeller ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import img from "./michael-gfeller-layer5-maintainer.webp"; -import { MeetTheMaintainer } from "../../MeetTheMaintainer.style"; -import { Link } from "gatsby"; -import ForkLift from "../../../../assets/images/app/hero/forklift.svg"; -import MoireCircles from "./Line Moire.svg"; -import MoireLines from "./Circle Moire.svg"; - - - - - -

    Kicking off Layer5's Meet the Maintainer series, we have Michael Gfeller. Michael is an avid research enthusiast in addition to holding the title of Chief Engineer at his day job. With exhaustive interests ranging from software architecture to systems security, he has been working with cloud architecture for the past four years. -

    - -
    -Shriti:

    -Michael, thank you for joining me today. Many people inside and outside of the Layer5 Community have seen the affects of your contributions, but may not know the backstory as to who Michael is and how you arrived at your maintainer role. Indulge us. How did you come across the Layer5 community? What made you stay? -

    - -
    -Michael:

    -Hey Shriti, thank you for having me. If I remember correctly, I was looking for a professional focus area earlier this year, and landed on service meshes. I had worked with service meshes before, which piqued my initial interest. I had worked with Istio as part of my work for some time, and in the same context I stumbled across Meshery. I wasn’t able to dig deep in Meshery back then, but the concept sounded fascinating to me. Additionally, I had been benefiting from open source, both personally and professionally for a long time, but apart from a few minor contributions, I had never been able to give back to the community. I hoped to correct that. -

    -

    -I re-discovered Meshery and the Layer5 community, listened to a recording of a community meeting, and read a couple of blog posts describing the community and member experience posts. One that stood out for me was a post by MeshMate Nikhil Ladha. Going by his words, it appeared to be a warm, diverse and active community. My suspicions were confirmed when I joined. Layer5 offers a wholesome, interactive community in addition to unbiasedly providing help and guidance around the virtual corner. -

    - -
    -Shriti: -

    -Layer5 projects has a number of active, open source projects. You’ve been consistently contributing to a few of them. Which one(s) are you currently focusing on? - -Psst. Also, which one’s your favorite? I won’t tell. -

    - -
    -Michael: -

    -I’m a technical architect and programmer, which made the backend, especially the adapters, a natural choice for me. It involves both contributing to the management plane, but also looking at and using service meshes from an architectural point of view. The possible implementations of service meshes is an area that has been particularly fascinating for me. -

    -

    -I’d probably continue to work with the Meshery adapters for now before moving on to other areas of the project. Haha, I would probably name the Meshery Adapter Library as my favorite Layer5 project till date. -

    - -
    -Shriti: -

    Have you worked with any other open source project? How does Layer5 compare? -

    - -
    -Michael: -

    -I have worked and collaborated with several open source communities before, including Eclipse Modelling Framework and Apache ServiceMix . I couldn’t possibly make a very accurate comparison, given by limited interaction with other communities, but the Layer5 community stands out based on the unique and extremely inclusive approach it takes towards upholding community values. -

    - -
    -Shriti:

    -What is so fascinating about service meshes? -

    - - - -
    -Michael: -

    -I find meshes intriguing in general. Meshes can look intricate, layered and complicated at a first glance, and yet they are built on the most basic principles. For me, meshes are visual structures, complete with an aesthetic and artistic dimension. -

    -

    Fun Fact: Overlapping meshes resulting in Moiré patterns are an example of this. They appealed to me from a young age, and I learned about their mathematics from my mathematics teacher. -

    - -
    -Shriti:

    -Fascinating. Why did you pick service meshes specifically though? -

    - - -
    -Michael:

    -An increasing number of applications nowadays consist of distributed services, both in the cloud and on-premises, in mixed and hybrid environments. Many legacy applications are in express need of modernisation, consuming and being consumed by cloud native applications. Introducing microservices, also by refactoring monolithic applications, increases the complexity of the service landscape. By delegating cross-cutting infrastructure concerns like security, traffic management, resilience, and observability to the services mesh, some of the complexity is moved from the applications to the service mesh, allowing application developers to focus on business logic. A concern in these distributed, dynamic and scalable systems is that the security also needs to scale. If security doesn’t scale, it becomes very challenging to handle such systems. Services meshes today are already able to support many of these scenarios, and are continuously improving. -

    - -

    -Service meshes are complex but that is something I enjoy attempting as a challenge, to have control and overview and make it appear simple, investing into automating options. Another field that I’m excited to learn about continuously is related to the security of distributed systems, and how service meshes contribute to implementing a zero trust network architecture. -

    - -

    -I actually dreamed about service mesh a while ago. That was almost a bit spooky. -

    -
    - -
    -Shriti:

    -Haha. Leading on that, what should Meshery dream about next? What can we hope to contribute to the service mesh landscape in your opinion?

    -
    - -
    -Michael:

    -Meshery currently does a great job of providing a neutral platform. Continuing in that direction would be a superb base plan. Enabling innovative applications from vendors, supporting all service meshes, integrating best practice methods, and implementing the SMP and SMI abstractions would probably score the top five positions in Meshery’s new year resolutions in 2021. -

    -
    - -
    -Shriti:

    -Interesting. Do expand on that. What do you think Meshery could offer, in addition to what it already does? -

    -
    - -
    -Michael:

    -At the moment, Meshery provides a management plane solution and provides support for the SMI and Service Mesh Performance (SMP) specifications. Helpful additions in the future should be the configuration based best practices, especially with regards to security and to possibly extend to owning up specific routes on security. For instance by verifying that the recommendations outlined in the NIST report “Building Secure Microservices-based Applications Using Service-Mesh Architecture” by Ramaswamy Chandramouli and Zack Butcher. -

    -
    - -
    -Shriti:

    -What are today's challenges when working with service meshes? -

    -
    - -
    -Michael:

    -I can’t claim to have worked with many implementations, and to have a good overview and wide experience. A lot of the complexity is already handled, but there is still enough to decide and implement for each solution. The solution makes for a challenging but highly interesting task. Additionally, there are a variety of different solutions from different vendors, which is excellent but it also makes it hard to know which would be the best fit for a given situation. Here, again, Meshery can be of invaluable help. -

    -
    - -
    -Shriti:

    -That’s good to hear. What do you think we should look forward to with respect to service mesh development? -

    -
    - -
    -Michael:

    -The service mesh promise holds a lot of potential, for instance for modernization and ease of use. A lot appears to be happening these times. It will be interesting to see how serverless solutions will be integrated. Enabling a seamless implementation experience for solutions embracing multi-cloud, on-prem and legacy systems is also something to look forward to. Additionally, service meshes are aimed at making your architecture more secure and stable, which makes security a big concern for any service mesh provider. Improvements along these points will be topics I’ll be watching out for over the next few years. -

    -
    - -
    -Shriti:

    - Ah while I have you here, let me get more reading recommendations lined up. Cloud Native and especially, the field of service meshes evolving exceptionally fast. Keeping up with all the developments can be challenging. Which resources do you use to stay up-to-date? -

    - -
    -Michael:

    -Service mesh implementations consist of many components, and I try to stay up to date in general. Try to follow as much as possible conferences and vendor announcements, blog posts etc. mainly by following related Twitter accounts. Also, trying to find some time to explore various solutions. Lee’s books are of course an excellent source. Another book I can recommend is Zero Trust Networks book by Gilman and Barth. It really helped me to understand how service meshes relate to zero trust network architecture and can help to move towards it. -

    - -
    -Shriti:

    What does being a Meshery maintainer mean to you? How has being a maintainer impacted your full-time role? -

    - -
    -Michael:

    -I take my role as a Meshery maintainer with its benefits and responsibilities. For one, it means to be able to give back to the community. I meet a lot of interesting and friendly people from around the globe, learning about their culture at the same time. Additionally, Open Source allows me to work on and dive into tasks as I like, making it easy to integrate the work with my existing work schedule. It also allows me to learn a lot, expanding on my understanding of service meshes, keeping up with the latest developments in the field, and also giving me the opportunity to witness first-hand how others are using them. This has a quite direct impact on my full-time role, complementing the work I do. -

    - -
    -Shriti:

    Do you have any advice for individuals hopeful to become Layer5 contributors or potentially maintainers? -

    - -
    -Michael:

    -A general love for software development combined with a readiness to help out newcomers and participating in the growing community is the key. -

    -

    -Come and visit, there is something for everyone, be it frontend, backend, CI/CD, website, documentation, standards, interfacing with other communities, and more. The friendly community members and the meshmates will provide support and guidance. Browse the Layer5 and Meshery websites and the repositories on GitHub, where issues suitable for newcomers are especially tagged. -

    - - -

    In his relatively short tenure at Layer5, Michael has already delivered a wave of meshy contributions enhancing the Meshery adapters and improving upon Meshery’s architecture. With a penchant for looking behind the curtain and tightening loose cogs until they run to perfection, Michael's impactful and consistent contributions have him taking his place as Meshery maintainer. The Meshery project moves an impressive pace thanks to maintainers like Michael. -

    - -

    -"Be like Mike". Join the Layer5 Slack and say hi. -

    -
    -
    +--- +title: "Meet the Maintainer: Michael Gfeller" +subtitle: "An interview series with Layer5 Maintainers" +date: 2021-02-04 10:30:05 -0530 +author: Shriti Chandra +thumbnail: "./michael-gfeller-layer5-maintainer.webp" +darkthumbnail: "./michael-gfeller-layer5-maintainer.webp" +category: "Community" +tags: + - Community +published: true +interviewer: Shriti Chandra +interviewee: Michael Gfeller +--- + +import { BlogWrapper } from "../../Blog.style.js"; +import img from "./michael-gfeller-layer5-maintainer.webp"; +import { MeetTheMaintainer } from "../../MeetTheMaintainer.style"; +import { Link } from "gatsby"; +import ForkLift from "../../../../assets/images/app/hero/forklift.svg"; +import MoireCircles from "./Line Moire.svg"; +import MoireLines from "./Circle Moire.svg"; + + + + + +

    Kicking off Layer5's Meet the Maintainer series, we have Michael Gfeller. Michael is an avid research enthusiast in addition to holding the title of Chief Engineer at his day job. With exhaustive interests ranging from software architecture to systems security, he has been working with cloud architecture for the past four years.

    + +
    +Shriti:

    +Michael, thank you for joining me today. Many people inside and outside of the Layer5 Community have seen the affects of your contributions, but may not know the backstory as to who Michael is and how you arrived at your maintainer role. Indulge us. How did you come across the Layer5 community? What made you stay?

    +
    + +
    +Michael:

    +Hey Shriti, thank you for having me. If I remember correctly, I was looking for a professional focus area earlier this year, and landed on service meshes. I had worked with service meshes before, which piqued my initial interest. I had worked with Istio as part of my work for some time, and in the same context I stumbled across Meshery. I wasn’t able to dig deep in Meshery back then, but the concept sounded fascinating to me. Additionally, I had been benefiting from open source, both personally and professionally for a long time, but apart from a few minor contributions, I had never been able to give back to the community. I hoped to correct that.

    +

    +I re-discovered Meshery and the Layer5 community, listened to a recording of a community meeting, and read a couple of blog posts describing the community and member experience posts. One that stood out for me was a post by MeshMate Nikhil Ladha. Going by his words, it appeared to be a warm, diverse and active community. My suspicions were confirmed when I joined. Layer5 offers a wholesome, interactive community in addition to unbiasedly providing help and guidance around the virtual corner. +

    + +
    +Shriti: +

    +Layer5 projects has a number of active, open source projects. You’ve been consistently contributing to a few of them. Which one(s) are you currently focusing on? + +Psst. Also, which one’s your favorite? I won’t tell. +

    + +
    +Michael: +

    +I’m a technical architect and programmer, which made the backend, especially the adapters, a natural choice for me. It involves both contributing to the management plane, but also looking at and using service meshes from an architectural point of view. The possible implementations of service meshes is an area that has been particularly fascinating for me. +

    +

    +I’d probably continue to work with the Meshery adapters for now before moving on to other areas of the project. Haha, I would probably name the Meshery Adapter Library as my favorite Layer5 project till date. +

    + +
    +Shriti: +

    Have you worked with any other open source project? How does Layer5 compare?

    +
    + +
    +Michael: +

    +I have worked and collaborated with several open source communities before, including Eclipse Modelling Framework and Apache ServiceMix . I couldn’t possibly make a very accurate comparison, given by limited interaction with other communities, but the Layer5 community stands out based on the unique and extremely inclusive approach it takes towards upholding community values. +

    + +
    +Shriti:

    +What is so fascinating about service meshes?

    +
    + + + +
    +Michael: +

    +I find meshes intriguing in general. Meshes can look intricate, layered and complicated at a first glance, and yet they are built on the most basic principles. For me, meshes are visual structures, complete with an aesthetic and artistic dimension. +

    +

    Fun Fact: Overlapping meshes resulting in Moiré patterns are an example of this. They appealed to me from a young age, and I learned about their mathematics from my mathematics teacher.

    +
    + +
    +Shriti:

    +Fascinating. Why did you pick service meshes specifically though?

    +
    + + +
    +Michael:

    +An increasing number of applications nowadays consist of distributed services, both in the cloud and on-premises, in mixed and hybrid environments. Many legacy applications are in express need of modernisation, consuming and being consumed by cloud native applications. Introducing microservices, also by refactoring monolithic applications, increases the complexity of the service landscape. By delegating cross-cutting infrastructure concerns like security, traffic management, resilience, and observability to the services mesh, some of the complexity is moved from the applications to the service mesh, allowing application developers to focus on business logic. A concern in these distributed, dynamic and scalable systems is that the security also needs to scale. If security doesn’t scale, it becomes very challenging to handle such systems. Services meshes today are already able to support many of these scenarios, and are continuously improving.

    + +

    +Service meshes are complex but that is something I enjoy attempting as a challenge, to have control and overview and make it appear simple, investing into automating options. Another field that I’m excited to learn about continuously is related to the security of distributed systems, and how service meshes contribute to implementing a zero trust network architecture. +

    + +

    +I actually dreamed about service mesh a while ago. That was almost a bit spooky. +

    +
    + +
    +Shriti:

    +Haha. Leading on that, what should Meshery dream about next? What can we hope to contribute to the service mesh landscape in your opinion?

    +
    + +
    +Michael:

    +Meshery currently does a great job of providing a neutral platform. Continuing in that direction would be a superb base plan. Enabling innovative applications from vendors, supporting all service meshes, integrating best practice methods, and implementing the SMP and SMI abstractions would probably score the top five positions in Meshery’s new year resolutions in 2021.

    +
    + +
    +Shriti:

    +Interesting. Do expand on that. What do you think Meshery could offer, in addition to what it already does?

    +
    + +
    +Michael:

    +At the moment, Meshery provides a management plane solution and provides support for the SMI and Service Mesh Performance (SMP) specifications. Helpful additions in the future should be the configuration based best practices, especially with regards to security and to possibly extend to owning up specific routes on security. For instance by verifying that the recommendations outlined in the NIST report “Building Secure Microservices-based Applications Using Service-Mesh Architecture” by Ramaswamy Chandramouli and Zack Butcher.

    +
    + +
    +Shriti:

    +What are today's challenges when working with service meshes?

    +
    + +
    +Michael:

    +I can’t claim to have worked with many implementations, and to have a good overview and wide experience. A lot of the complexity is already handled, but there is still enough to decide and implement for each solution. The solution makes for a challenging but highly interesting task. Additionally, there are a variety of different solutions from different vendors, which is excellent but it also makes it hard to know which would be the best fit for a given situation. Here, again, Meshery can be of invaluable help.

    +
    + +
    +Shriti:

    +That’s good to hear. What do you think we should look forward to with respect to service mesh development?

    +
    + +
    +Michael:

    +The service mesh promise holds a lot of potential, for instance for modernization and ease of use. A lot appears to be happening these times. It will be interesting to see how serverless solutions will be integrated. Enabling a seamless implementation experience for solutions embracing multi-cloud, on-prem and legacy systems is also something to look forward to. Additionally, service meshes are aimed at making your architecture more secure and stable, which makes security a big concern for any service mesh provider. Improvements along these points will be topics I’ll be watching out for over the next few years.

    +
    + +
    +Shriti:

    + Ah while I have you here, let me get more reading recommendations lined up. Cloud Native and especially, the field of service meshes evolving exceptionally fast. Keeping up with all the developments can be challenging. Which resources do you use to stay up-to-date?

    +
    + +
    +Michael:

    +Service mesh implementations consist of many components, and I try to stay up to date in general. Try to follow as much as possible conferences and vendor announcements, blog posts etc. mainly by following related Twitter accounts. Also, trying to find some time to explore various solutions. Lee’s books are of course an excellent source. Another book I can recommend is Zero Trust Networks book by Gilman and Barth. It really helped me to understand how service meshes relate to zero trust network architecture and can help to move towards it.

    +
    + +
    +Shriti:

    What does being a Meshery maintainer mean to you? How has being a maintainer impacted your full-time role?

    +
    + +
    +Michael:

    +I take my role as a Meshery maintainer with its benefits and responsibilities. For one, it means to be able to give back to the community. I meet a lot of interesting and friendly people from around the globe, learning about their culture at the same time. Additionally, Open Source allows me to work on and dive into tasks as I like, making it easy to integrate the work with my existing work schedule. It also allows me to learn a lot, expanding on my understanding of service meshes, keeping up with the latest developments in the field, and also giving me the opportunity to witness first-hand how others are using them. This has a quite direct impact on my full-time role, complementing the work I do.

    +
    + +
    +Shriti:

    Do you have any advice for individuals hopeful to become Layer5 contributors or potentially maintainers?

    +
    + +
    +Michael:

    +A general love for software development combined with a readiness to help out newcomers and participating in the growing community is the key.

    +

    +Come and visit, there is something for everyone, be it frontend, backend, CI/CD, website, documentation, standards, interfacing with other communities, and more. The friendly community members and the meshmates will provide support and guidance. Browse the Layer5 and Meshery websites and the repositories on GitHub, where issues suitable for newcomers are especially tagged. +

    + + +

    In his relatively short tenure at Layer5, Michael has already delivered a wave of meshy contributions enhancing the Meshery adapters and improving upon Meshery’s architecture. With a penchant for looking behind the curtain and tightening loose cogs until they run to perfection, Michael's impactful and consistent contributions have him taking his place as Meshery maintainer. The Meshery project moves an impressive pace thanks to maintainers like Michael.

    + +

    +"Be like Mike". Join the Layer5 Slack and say hi. +

    +
    +
    diff --git a/src/collections/blog/2021/2021-02-07-meshkit-and-meshery-adapter-library/index.mdx b/src/collections/blog/2021/2021-02-07-meshkit-and-meshery-adapter-library/index.mdx index f5810c35b758..76d2c59cb468 100644 --- a/src/collections/blog/2021/2021-02-07-meshkit-and-meshery-adapter-library/index.mdx +++ b/src/collections/blog/2021/2021-02-07-meshkit-and-meshery-adapter-library/index.mdx @@ -1,6 +1,6 @@ --- title: "Introducing Meshkit and the Meshery Adapter Library" -subtitle: "Making the DX of cloud native infrastructure management easy." +subtitle: "Making the DX of service mesh management easy." date: 2021-02-07 12:12:12 +0002 author: Michael Gfeller thumbnail: ./meshery-adapter-library-overview.webp @@ -16,9 +16,9 @@ resource: true published: true --- -import { BlogWrapper } from "../../Blog.style.js"; + import { MeshkitMesheryAdapterLib } from "./MeshkitMesheryAdapterLib.style"; -import { Link } from "gatsby"; + import mesheryAdapterLibrary from "./meshery-adapter-library.svg"; import malOverview from "./meshery-adapter-library-overview.webp"; @@ -26,20 +26,21 @@ import malOverview from "./meshery-adapter-library-overview.webp"; -

    The Meshery v0.5.0 release includes two new libraries: MeshKit and Meshery Adapter Library. +

    +The Meshery v0.5.0 release includes two new libraries: MeshKit and Meshery Adapter Library. -These two libraries improve contributor experience and development speed by reducing the burden of sustaining the plethora of Meshery adapters, allowing contributors to focus on exposing any given infrastructure component's differentiated value, -instead of having to redundantly implement plumbing for managing cloud native infrastructure. +These two libraries improve contributor experience and development speed by reducing the burden of sustaining the plethora of Meshery adapters, allowing contributors to focus on exposing a service mesh's differentiated value, +instead of having to redundantly implement plumbing for managing service meshes.

    ## MeshKit -MeshKit was formerly named `gokit` and was renamed recently to align with the other Meshery components' names (and avoid confusion with the `go-kit` project). MeshKit can be considered a derivative of `go-kit` with specific focus on cloud native management. +MeshKit was formerly named `gokit` and was renamed recently to align with the other Meshery components' names (and avoid confusion with the `go-kit` project). MeshKit can be considered a derivative of `go-kit` with specific focus on service mesh management. -In the Meshery v0.5.0 release, MeshKit has been enhanced and expanded substantially. Considering that the MeshKit library provides broadly useful functionality, it is used in a growing number of Meshery components. It is intended to be one of the top level libraries in the Meshery ecosystem.
    Meshkit provides functionality useful across all Meshery components.
    +In the Meshery v0.5.0 release, MeshKit has been enhanced and expanded substantially. Considering that the MeshKit library provides broadly useful functionality, it is used in a growing number of Meshery components. It is intended to be one of the top level libraries in the Meshery ecosystem.
    Meshkit provides functionality useful across all Meshery components.
    -MeshKit is a toolkit for Layer5’s microservices, and is positioned to become Layer5’s middleware component for Layer5’s microservices, leveraging other libraries like `go-kit/kit`. In complement to functionality provided by any given cloud native infrastructure component, its purpose is to provide implementations for common cross-cutting concerns like error handling, logging, and tracing. Uniform error handling and logging across all Meshery components helps to implement efficient tooling for observability, monitoring and troubleshooting. The library provides some common data models for Meshery and Meshery's ecosystem of extensions. +MeshKit is a toolkit for Layer5’s microservices, and is positioned to become Layer5’s middleware component for Layer5’s microservices, leveraging other libraries like `go-kit/kit`. In complement to functionality provided by a service mesh, its purpose is to provide implementations for common cross-cutting concerns like error handling, logging, and tracing. Uniform error handling and logging across all Meshery components helps to implement efficient tooling for observability, monitoring and troubleshooting. The library provides some common data models for Meshery, notably for Service Mesh Interface conformance testing, and Kubernetes' `kubeconfig`. Another central component in Meshkit is the `utils` package. @@ -130,7 +131,7 @@ spec: ## Meshery Adapters -Meshery adapters are management plane components and manage the lifecycle of cloud native infra. This includes installation and deletion, configuration, and verification that an installation follows recommended practices. As example use of Meshery adapters is for purposes of compliance verification, actively attesting whether whether infrastructure complies to an open standard, like that of Service Mesh Interface. Meshery adapters support management of multiple versions of their respective capabilites and also come bundled with sample applications that can be deployed for easy and quick exploration of infrastructure (or other) capabilities.
    Meshery adapters extend Meshery's core functionality housed within Meshery Server, often deepening Meshery's ability to manage the lifecycle infratructure, but not limited to those use cases. Adapters have been known to act as engineering workflow facilititors, providing gate reviews, sending emails, and so on.
    +Meshery adapters are management plane components and manage the lifecycle of service meshes. This includes installation and deletion, configuration, and verification that an installation follows recommended practices. In addition, Meshery adapters can assess to what extent a service mesh complies to the Service Mesh Interface standard. Meshery adapters support management of multiple versions of their respective service mesh and also come bundled with sample applications that can be deployed for easy and quick exploration of service mesh capabilities.
    Meshery adapters manage the lifecycle of service meshes.
    A Meshery adapter is a gRPC server that exposes the `MeshServiceServer` interface: @@ -145,15 +146,15 @@ type MeshServiceServer interface { } ``` -- `CreateInstance` sets up the Kubernetes client. It does not, as the name might imply, create an instance of an infrastructure component. -- `Name` returns the name of the infrastructure component, configured in the adapter. -- `SupportedOperations` returns all supported operations, configured in the adapter. An operation is e.g. the installation of any given cloud native infrastructure component or service. +- `CreateMeshInstance` sets up the Kubernetes client. It does not, as the name might imply, create an instance of a service mesh. +- `MeshName` returns the name of the mesh, configured in the adapter. +- `SupportedOperations` returns all supported operations, configured in the adapter. An operation is e.g. the installation of a service mesh. - `ApplyOperation` executes the operation specified in the request. It is one of the supported operations. - `StreamEvents` allows sending events from the server to the client. -This API is one of the extension points of Meshery, making it easy to add support for new cloud native technologies to Meshery. Meshery adapters abstract away differences in installation and configuration of the various technologies. Various cloud native technologies are installed and configured in their own way. For instance, some projects have their own installer, like `istioctl` for Istio, while others use Helm charts, like Consul. One of the purposes of Meshery adapters is to abstract these differences away.
    It's important to note, however, that Meshery Adapters allow Meshery to interface with each managed system uniquely, and not treat those systems uniformly by only offering the lowest common denominator of functionality, but instead by exposing that system's differentiated value to users.
    - +This API is one of the extension points of Meshery, making it easy to add support for new service meshes to Meshery. Meshery adapters abstract away differences in installation and configuration of the various service meshes.
    Adapters allow Meshery to interface with the different service meshes, exposing their differentiated value to users.
    +In general, the various service mesh implementations are installed and configured in their own way. For instance, some service meshes have their own installer, like `istioctl` for Istio, while others use Helm charts, like Consul. One of the purposes of Meshery adapters is to abstract these differences away. ## Meshery Adapter Library @@ -165,10 +166,10 @@ It reduces the amount of boilerplate code in the adapters substantially, making Also, it means new adapters can be implemented quickly, as only configuration and operations that differ between services meshes need to be implemented. -
    +
    The Meshery Adapter Library provides a common and consistent set of functionality that Meshery adapters use for managing the lifecycle of - cloud infrastructure and their workloads. + service meshes and their workloads.
    The initial commit was submitted on October 6th, 2020 based on a refactoring effort in the adapter for the Kuma service mesh. Within a few months, several adapters have been refactored or implemented from scratch based on the Meshery Adapter Library. @@ -209,7 +210,7 @@ The figure below illustrates this and the usage of the library in an adapter. meshery adapter library @@ -224,7 +225,7 @@ The `service` is a struct that holds all the parameters that specify an adapter Extracting common code from adapters to the two new libraries has proven to be a worthwhile investment. It led to cleaner code as well as cleaner application architecture, shortened implementation time for new adapters considerably, and upleveled the quality of Meshery's adapters through consistency of implementation. -

    P.S. If these topics excite you and you want to explore the beautiful realm of cloud native infrastructure, come and say "Hi" on the community Slack and you are sure to be warmly welcomed. 😀

    +

    P.S. If these topics excite you and you want to explore the beautiful realm of service meshes, come and say "Hi" on the community Slack and you are sure to be warmly welcomed. 😀

    diff --git a/src/collections/blog/2021/2021-04-05-meshmate-of-the-year-2020-nikhil-ladha/index.mdx b/src/collections/blog/2021/2021-04-05-meshmate-of-the-year-2020-nikhil-ladha/index.mdx index 34f490cb80bb..b8a07b882fa9 100644 --- a/src/collections/blog/2021/2021-04-05-meshmate-of-the-year-2020-nikhil-ladha/index.mdx +++ b/src/collections/blog/2021/2021-04-05-meshmate-of-the-year-2020-nikhil-ladha/index.mdx @@ -1,203 +1,194 @@ ---- -title: "MeshMate of the Year 2020: Nikhil Ladha" -subtitle: "" -date: 2021-04-05 09:10:00 +0000 -author: Lee Calcote -thumbnail: ./MeshMate-of-the-Year-2020-Nihkil-Ladha.webp -darkthumbnail: ./MeshMate-of-the-Year-2020-Nihkil-Ladha.webp -category: Community -tags: - - Community -published: true ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import MMoY2020 from "./meshmate-of-the-year-2020.webp"; -import Blockquote from "../../../../reusecore/Blockquote"; -import BlockquoteAlt from "../../../../reusecore/Blockquote/Blockquote-alt-style"; -import { Link } from "gatsby"; - -import MeshMate from "../../../../assets/images/meshmate/meshmate-stack.svg"; -import MMOYNikhil from "./MeshMate-of-the-Year-2020-Nihkil-Ladha.webp"; - - - -

    - If you are in the Layer5 Community, no doubt, you've met - - Nikhil Ladha - . If not, I recommend that you join the community and get to know Nikhil. - He's the Layer5 MeshMate of the Year and here's why: Nikhil consistently volunteers - to uplift and support others in the community, freely sharing of his time and knowledge. - His actions embody and espouse the pay-it-forward culture of Layer5. -

    - -
    - -2020 was a noteworthy year in many ways. Nikhil's committment to the people and projects of the Layer5 community will forever be at the top of list of mentionables I and others will recall of last year. It was in 2019, though, that Nikhil's journey in the Layer5 community started and where he first began helping build our healthy, inclusive, and diverse community and our industry-leading, innovate open source projects. Nikhil's natural disposition to mentoring others and his stewardship on various projects make him a successful MeshMate. - -

    What is a Layer5 MeshMate?

    - -Meshmate -

    - - MeshMate - - is a distinction that Layer5 awards select members of the community who innately - align with our culture of helping others, paying it forward, and a commitment to - knowledge sharing. MeshMates are Layer5 mentors and ambassadors (not employees). -

    - -
    - -

    - A Layer5 MeshMate is individual who has consistently demonstrated their - commitment to helping community members. The MeshMate program pairs - experienced Layer5 community members with community newcomers to ensure a - smooth onboarding experience. Helping community members takes all forms from - ensuring the member has access to resources, is introduced to others, - understands the vision and goals of projects, can build and contribute to - projects, can use projects and have their feedback heard. MeshMates aid in - identifying areas of projects and activities within the community to engage - within, which working groups to join, and in help community members grow in - their open source and cloud native knowledge. -

    - -

    - There is a lot going in the Layer5 community. Projects and working groups move - fast. By connecting one-on-one, MeshMates share tips on how to have the best - community experience possible, but also build a relationship with the - community member inevitably leaving a lasting mark as is evident from member - comments about Nikhil. -

    - -

    It's not easy being a MeshMate

    - -

    - With thousands of members in the Layer5 community, many come and go. Many take - and many give. While we hope that each and every individual that joins will - find a fit in the community and/or on a project, this isn't always the case. - - Engaging with and investing in community members can be taxing on mentors in - terms of both their time and their emotional investment in seeing the newcomer - plant roots, grow, and blossom. -

    - -

    - One of the goals MeshMates have is that of enabling the newcomer's passion and - finding their sweetspot in the community and on a project, so that the - newcomer ultimately achieves their goals - goals that are often similar, but - different for each person. To help them acheive their goals, each individual - is engaged 1:1 by their Meshmate, supporting them in becoming a landstanding - Layer5 community member and contributor. MeshMates understand that many - mentees start out with the best of intentions, but that not all overcome their - hurdles in finding an area of the community to call home or aspect of a - project to own. -

    - - - -

    MeshMates are a massive force

    -

    - In just a year's time, with thousands of people in the Layer5 community and - 500+ contributors to our projects, it's clear that Layer5 MeshMates - significantly uplift our collaborative efforts and are steady force in the - community. In process of confirming Nikhil as the winner of the inaugural - MeshMate of the Year award, we looked to the community for validation. Little - did I realize that meant reaching out to nearly a hundred people whom Nikhil - has mentored or supported in the Layer5 community. More than a few of them had - something to say about their time with Nikhil: -

    - -
    -
    - -
    - -
    -
    - -
    -
    - -
    - -
    -
    - -
    -
    - -
    - -
    -
    - -
    -
    - -
    - -
    -
    - -MeshMate of the Year 2020: Nikhil Ladha -

    - In recognition a year's worth of paying it forward, and for the inaugural - award, a new badge identifies our MeshMate of the Year award winner. Only one - person carries this badge today. I can only guess as to who this ribbon may be - awarded to for 2021. In the year and a half that Nikhil has been in the - community, he has touched the lives of many people, including mine. Nikhil is - my friend. He is the Layer5 MeshMate of the Year. -

    - -
    - Meshmate of the year -
    - -

    - The MeshMate badge is a point of pride for individuals participating in the - program and looked upon with admiration and veneration by many within and - external to the Layer5 community. -

    - -

    - Wear your MeshMate of the Year badge proudly, Nikhil. -

    - - +--- +title: "MeshMate of the Year 2020: Nikhil Ladha" +subtitle: "" +date: 2021-04-05 09:10:00 +0000 +author: Lee Calcote +thumbnail: ./MeshMate-of-the-Year-2020-Nihkil-Ladha.webp +darkthumbnail: ./MeshMate-of-the-Year-2020-Nihkil-Ladha.webp +category: Community +tags: + - Community +published: true +--- + +import MMoY2020 from "./meshmate-of-the-year-2020.webp"; +import MeshMate from "../../../../assets/images/meshmate/meshmate-stack.svg"; +import MMOYNikhil from "./MeshMate-of-the-Year-2020-Nihkil-Ladha.webp"; + + + +

    + If you are in the Layer5 Community, no doubt, you've met + Nikhil Ladha. If not, I recommend that you join the community and get to know Nikhil. + He's the Layer5 MeshMate of the Year and here's why: Nikhil consistently volunteers + to uplift and support others in the community, freely sharing of his time and knowledge. + His actions embody and espouse the pay-it-forward culture of Layer5. +

    + +
    + +2020 was a noteworthy year in many ways. Nikhil's committment to the people and projects of the Layer5 community will forever be at the top of list of mentionables I and others will recall of last year. It was in 2019, though, that Nikhil's journey in the Layer5 community started and where he first began helping build our healthy, inclusive, and diverse community and our industry-leading, innovate open source projects. Nikhil's natural disposition to mentoring others and his stewardship on various projects make him a successful MeshMate. + +

    What is a Layer5 MeshMate?

    + +Meshmate +

    + + MeshMate + + is a distinction that Layer5 awards select members of the community who innately + align with our culture of helping others, paying it forward, and a commitment to + knowledge sharing. MeshMates are Layer5 mentors and ambassadors (not employees). +

    + +
    + +

    + A Layer5 MeshMate is individual who has consistently demonstrated their + commitment to helping community members. The MeshMate program pairs + experienced Layer5 community members with community newcomers to ensure a + smooth onboarding experience. Helping community members takes all forms from + ensuring the member has access to resources, is introduced to others, + understands the vision and goals of projects, can build and contribute to + projects, can use projects and have their feedback heard. MeshMates aid in + identifying areas of projects and activities within the community to engage + within, which working groups to join, and in help community members grow in + their open source and cloud native knowledge. +

    + +

    + There is a lot going in the Layer5 community. Projects and working groups move + fast. By connecting one-on-one, MeshMates share tips on how to have the best + community experience possible, but also build a relationship with the + community member inevitably leaving a lasting mark as is evident from member + comments about Nikhil. +

    + +

    It's not easy being a MeshMate

    + +

    + With thousands of members in the Layer5 community, many come and go. Many take + and many give. While we hope that each and every individual that joins will + find a fit in the community and/or on a project, this isn't always the case. + + Engaging with and investing in community members can be taxing on mentors in + terms of both their time and their emotional investment in seeing the newcomer + plant roots, grow, and blossom. +

    + +

    + One of the goals MeshMates have is that of enabling the newcomer's passion and + finding their sweetspot in the community and on a project, so that the + newcomer ultimately achieves their goals - goals that are often similar, but + different for each person. To help them acheive their goals, each individual + is engaged 1:1 by their Meshmate, supporting them in becoming a landstanding + Layer5 community member and contributor. MeshMates understand that many + mentees start out with the best of intentions, but that not all overcome their + hurdles in finding an area of the community to call home or aspect of a + project to own. +

    + + + +

    MeshMates are a massive force

    +

    + In just a year's time, with thousands of people in the Layer5 community and + 500+ contributors to our projects, it's clear that Layer5 MeshMates + significantly uplift our collaborative efforts and are steady force in the + community. In process of confirming Nikhil as the winner of the inaugural + MeshMate of the Year award, we looked to the community for validation. Little + did I realize that meant reaching out to nearly a hundred people whom Nikhil + has mentored or supported in the Layer5 community. More than a few of them had + something to say about their time with Nikhil: +

    + +
    +
    + +
    + +
    +
    + +
    +
    + +
    + +
    +
    + +
    +
    + +
    + +
    +
    + +
    +
    + +
    + +
    +
    + +MeshMate of the Year 2020: Nikhil Ladha +

    + In recognition a year's worth of paying it forward, and for the inaugural + award, a new badge identifies our MeshMate of the Year award winner. Only one + person carries this badge today. I can only guess as to who this ribbon may be + awarded to for 2021. In the year and a half that Nikhil has been in the + community, he has touched the lives of many people, including mine. Nikhil is + my friend. He is the Layer5 MeshMate of the Year. +

    + +
    + Meshmate of the year +
    + +

    + The MeshMate badge is a point of pride for individuals participating in the + program and looked upon with admiration and veneration by many within and + external to the Layer5 community. +

    + +

    + Wear your MeshMate of the Year badge proudly, Nikhil. +

    + + diff --git a/src/collections/blog/2021/2021-04-16-meet-the-maintainer-jash-patel/index.mdx b/src/collections/blog/2021/2021-04-16-meet-the-maintainer-jash-patel/index.mdx index 0c6ec1f462fd..c21c8d2c9059 100644 --- a/src/collections/blog/2021/2021-04-16-meet-the-maintainer-jash-patel/index.mdx +++ b/src/collections/blog/2021/2021-04-16-meet-the-maintainer-jash-patel/index.mdx @@ -9,19 +9,14 @@ category: Community tags: - Community published: true -interviewer: Ruth Ikegah -interviewee: Jash Patel --- -import { BlogWrapper } from "../../Blog.style.js"; import img from "./jash-patel-layer5-maintainer.webp"; -import { MeetTheMaintainer } from "../../MeetTheMaintainer.style.js"; -import { Link } from "gatsby"; -
    +

    Next on Layer5 Meet the Maintainer’s series, we have Jash Patel. Jash is a Computer Science undergraduate at the Indian Institute of Technology and a @@ -29,14 +24,15 @@ import { Link } from "gatsby"; {" "} Service Mesh Performance - {" "} + + {" "} and Service Mesh Landscape. He works with React, Gatsby, Jekyll, and Discourse and loves contributing to Open Source.

    -
    +
    Ruth:

    Jash, thank you for joining me today. Many people inside and outside of the @@ -47,7 +43,7 @@ import { Link } from "gatsby";

    -
    +
    Jash:

    Back in August 2020, I was looking for an open-source organization. I found @@ -62,7 +58,7 @@ import { Link } from "gatsby";

    -
    +
    Ruth:

    I can totally relate to how amazing the Layer5 onboarding process is unique! @@ -72,7 +68,7 @@ import { Link } from "gatsby";

    -
    +
    Jash:

    I started contributing to docs and soon dived into Layer5 websites. While I @@ -85,7 +81,7 @@ import { Link } from "gatsby";

    -
    +
    Ruth:

    Definitely, winks! Have you worked with any other open source project? How @@ -93,7 +89,7 @@ import { Link } from "gatsby";

    -
    +
    Jash:

    I am a part of my college’s open-source organization. I have contributed to @@ -104,7 +100,7 @@ import { Link } from "gatsby";

    -
    +
    Ruth:

    You know for me, coming to The Next Generation Layer5 Website was done in @@ -113,7 +109,7 @@ import { Link } from "gatsby";

    -
    +
    Jash:

    It was a pretty big task. Many people have worked on it(At the time of @@ -129,7 +125,7 @@ import { Link } from "gatsby";

    -
    +
    Ruth:

    It’s amazing you are in school and still actively contribute to Layer5, how @@ -137,7 +133,7 @@ import { Link } from "gatsby";

    -
    +
    Jash:

    I once mentioned that while my exams were going on, I would study the entire @@ -149,7 +145,7 @@ import { Link } from "gatsby";

    -
    +
    Ruth:

    I’m really curious, what does being a Layer5 maintainer mean to you? How has @@ -157,7 +153,7 @@ import { Link } from "gatsby";

    -
    +
    Jash:

    I still remember my first pull request being reviewed. And now I am on the @@ -170,7 +166,7 @@ import { Link } from "gatsby";

    -
    +
    Ruth:

    I really picked a lot of points on that! Do you have any advice for @@ -178,7 +174,7 @@ import { Link } from "gatsby";

    -
    +
    Jash:

    My advice would be to not look for becoming something. I never thought of @@ -193,7 +189,7 @@ import { Link } from "gatsby";

    -
    +
    Ruth:

    That was some great advice there and tips! Thanks, Jash for all you do for @@ -201,7 +197,7 @@ import { Link } from "gatsby";

    -
    +
    Ruth:

    That was some great advice there and tips! Thanks, Jash for all you do for @@ -209,8 +205,8 @@ import { Link } from "gatsby";

    -
    -

    +

    +

    Jash is an impactful contributor and a kind-hearted maintainer. His story is special, but not unique. Take Jash’s advice and engage in our uplifting community. Write your own story. Join the Layer5 Community. Be like Jash, @@ -218,7 +214,7 @@ import { Link } from "gatsby";

    -

    +

    "Be like Jash." Join the Layer5 Slack and say hi.

    diff --git a/src/collections/blog/2021/2021-04-19-announcing-meshery-v0.5/index.mdx b/src/collections/blog/2021/2021-04-19-announcing-meshery-v0.5/index.mdx index fd5281efd41b..a593635ae21f 100644 --- a/src/collections/blog/2021/2021-04-19-announcing-meshery-v0.5/index.mdx +++ b/src/collections/blog/2021/2021-04-19-announcing-meshery-v0.5/index.mdx @@ -1,191 +1,193 @@ ---- -title: "Announcing Meshery v0.5.0" -subtitle: "" -date: 2021-04-19 08:00:00 +0000 -author: Aisuko Li -thumbnail: ./v0.5.0.webp -darkthumbnail: ./v0.5.0.webp -category: Announcements -tags: - - Meshery - - Projects -published: true -resource: true -type: Blog -product: Meshery -redirect_from: - - /blog/meshery/announcing-meshery-v0.5.0/ ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import { Link } from "gatsby"; -import MesheryOperatorShot from "./meshery-operator-v0.5.0.webp"; -import MesheryOperator from "./meshery-operator-dark.svg"; -import MeshSync from "./meshsync.svg"; -import MesheryDB from "./meshery-database.svg"; -import MesheryAdapterLibrary from "./meshery-adapter-library.svg"; -import Traefik from "./traefik-mesh.svg"; -import MesheryExtensibility from "./meshery-extensibility.svg"; -import NGINXSM from "./nginx-service-mesh.svg"; -import layer5Logo from "../../../../assets/images/layer5/layer5-only/svg/layer5-no-trim.svg"; - - - -

    We're pleased to announce the release of Meshery 0.5.0! Consisting of a number of significant architectural enhancements with 8 new capabilities entering alpha, Meshery v0.5.0's feature density is impressive. Previewed in the Using Istio workshop delivered at the inaugural IstioCon 2021 earlier this month, Meshery v0.5.0 provides a strong architectural foundation for cloud native application and service mesh management.

    - - -## Feature Highlights -- New GraphQL API -- Meshery Operator with MeshSync inside -- Meshery Adapter for Traefik Mesh (beta) -- MeshKit and the Meshery Adapter Library -- Meshery Adapter for NGINX Service Mesh (alpha) -- Meshery Remote Provider extensions with dynamic injection -- New Meshery CLI commands to manage mutiple Meshery deployments - -
    - -

    Thank you to the wonderful Layer5 community of open source contributors in making this significant release possible.

    -
    - -## New Service Mesh Support - -

    2 new Meshery service mesh adapters are bundled with this latest version of Meshery: The Meshery Adapter for Traefik Mesh and the Meshery Adapter for NGINX Service Mesh.

    - -

    Meshery Adapter for Traefik Mesh (beta)

    - - -

    Traefik Mesh is a straight-forward, easy to configure, and non-invasive service mesh that allows visibility and management of the traffic flows inside any Kubernetes cluster.

    - -

    Meshery supports the lifecycle and performance management of Traefik Mesh. Along with support for multiple versions of Traefik Mesh, bundled with this adapter are the Book Info and HttpBin sample applications operations to aid you in familiarizing with the functionality of Traefik Mesh. As a Meshery user, you can apply custom configuration to your instances of Traefik Mesh, managing the onboarding of your own applications onto the service mesh and providing the ability for you as a service mesh manager to customize your service mesh deployment.

    - -

    Review the sample application guides to familiarize with their differences and learn more about the beta adapter for Meshery Adapter for Traefik Mesh.

    - - -

    Meshery Adapter for NGINX Service Mesh (alpha)

    - - -

    NGINX Service Mesh (NSM) is a fully integrated, lightweight service mesh that leverages a data plane powered by NGINX Plus to manage container traffic in Kubernetes environments.

    - -

    Meshery supports lifecycle and performance management of NGINX Service Mesh. Bundled with this support are a few sample applications to help users understand the functionality of NGINX Service Mesh. lifecycle management and sample applications operations below:

    - -
      -
    • Book Info
    • -
    • HTTPBin
    • -
    • Emojivoto
    • -
    - -

    Review the sample application guides to familiarize with their differences. Learn more about the alpha adapter for Meshery Adapter for NGINX Service Mesh.

    - -

    Integrating with Meshery: Using extension points

    - -As the cloud native manager, Meshery, is an extensible platform offering user and integrators well-crafted, extension points. Extension points allow you to augment the behavior of Meshery by either adding entirely new capabilities or affecting the behavior of existing functionality, as see in the figure below. - -
    - -
    - -As you can see in the diagram, Meshery offers many types of extension points. - -- Extensible Service Mesh Adapters - bring your own service mesh. -- Extensible APIs - bring your own GraphQL resolvers and expose new, custom endpoints. -- Extensible Load Generators - Meshery supports three types of load generators, however, you can bring your own and plug it in. -- Extensible Providers - the v0.5.0 release delivers dynamic injection of Remote Provider extensions. Providers are a powerful mechanism for integrating Meshery into your existing tooling and systems. - -There are two types of Providers in Meshery: Local - built into Meshery and Remote - implemented by anyone or any organization that wishes to integrate with Meshery. Remote Provider extensibility includes: - - * Pluggable UI functionality - * Pluggable Backend functionality - * Pluggable Authentication and Authorization - * Long-Term Persistence - * Enhanced Visualization - * Historical Reporting - -Learn more about the platform Meshery provides to extend its funcionality by exploring its extension points. If you have or are building your own Remote Provider, let us know! -

    MeshKit and Meshery Adapter Library

    - -As a service mesh toolkit, MeshKit aims to specifically focus on service mesh management and provides broadly useful functionality, it provides a standard policy for error handling and logging across all Meshery components, and implementations for error handling, logging, and tracing. - -
      -
    • MeshKit provides common data models of Service Mesh Interface conformance testing for Meshery.
    • -
    • The low-level API abstract by MeshKit to the high-level functions provides out-of-the-box functions.
    • -
    - -

    Meshery Adapter Library

    - -

    The Meshery Adapter Library provides a common and consistent set of functionality for managing the lifecycle of service meshes and their workloads.

    -
    - -
    - -* The library provides a set of interfaces, some with default implementations like a mini framework implementing the gRPC server that allows plugging in the mesh-specific configuration and operations implemented in the adapters. -* The default configuration provider we use Viper to reads the adapter specific configuration, and the configuration providers are implementations of an interface, this can be flexible if anyone wants to implement it on their own. - -

    Read Maintainer Michael Gfeller's blog post Introduction MeshKit and the Meshery Adapter Library for more details.

    - -With the increasing the number and diversity of service meshes supported by Meshery, you might find the list of [Supported Service Meshes](https://docs.meshery.io/service-meshes) a helpful, complete list. - -

    Meshery Operator

    - -

    -As a Kubernetes custom controller, Meshery Operator provides a Kubernetes-native approach to interfacing with Meshery. Kubernetes is where service meshes have gotten their initial foothold, and therefore, important that Meshery interface to Kubernetes natively.

    Some service meshes support non-containerized workloads outside of the cluster and will grow in this focus over time. While Meshery Operator is Kubernetes only in the v0.5.0 release, Meshery's arichitecture makes considerations for different workload and platform types.

    - -
    -
    - -
    -
      -
    • Meshery Operator is the multi-service mesh operator that runs as a Kubernetes Operator and defines two custom resources: MeshSync and Meshery Broker (NATS)
    • -
    • Meshery Operator is provides abilities includes cluster discovery, service mesh discovery, and data streaming via NATS.
    • -
    -
    - -

    MeshSync

    -

    MeshSync is available as a Kubernetes custom resource that provides tiered discovery and continual synchronization with Meshery Server as to the state of the Kubernetes cluster, service meshes, and their workloads.

    - -
    - -
      - -
    • MeshSync is one of a family of custom controllers within Meshery Operator and is the heartbeat of Meshery, pumping information about service meshes and their workloads throughout Meshery's components.
    • -
    • MeshSync helps Meshery mesh with meshes by helping define a service mesh agnostic object model.
    • -
    • It provides ability to detect service meshes and services deployed on the cluster, and snapshot stored in-memory and refreshed periodically; -maintain the local snapshot of the cluster and refreshed periodically.
    • -
    • MeshSync These abilities above help Meshery operations more resilient.
    • -
    - -
    -

    Relational Database

    - -Meshery's relational database serves as a repository for MeshSync data, user preferences, and system settings. This database should be considered ephemeral and given that it operates as a cache. Meshery relational database offers federated datasets for managing multiple Kubernetes cluster and multiple service meshes. - -
    - -
    - -

    Learn more and consider contributing to MeshSync.

    - -## GraphQL Support - -Meshery now supports GraphQL instances between Meshery UI and Meshery Server offering any GraphQL client the power to ask for exactly what they need from mesh. This new API sets the stage preparing for exciting features in upcoming releases. Extension points are also built into Meshery's GraphQL support allowing integrators to bring their own GraphQL resolvers to the Meshery server runtime. - - -

    Meshery Command Line Interface Enhancements

    -The beloved `mesheryctl` introduces new commands in the v0.5.0 release expands the CLI's support of multiple Meshery deployments with the `context` command and control over when Meshery auto-updates with the `channel` command. - -

    Managing Multiple Meshery Deployments

    -Introduced in this release is the meshconfig - a configuration file that describes Meshery deployments in separate contexts. A Meshery context describes deployments across Docker hosts and Kubernetes clusters. mesheryctl system context enables user to easy manage multiple deployments of Meshery by quickly switching contexts. - -### Subscribing to Meshery Release Channels -`mesheryctl system channel` allows you to easily set and switch between which Meshery release channel (stable or edge) that you want a particilar Meshery deployment (`context`) to use. Meshery deployments subscribe to one of two release channels and can either automatically self-update the deployment or prompt you to update the deployment. Alternatively, you can pin a given Meshery deployment to a specific release should you want tighter control over when Meshery updates. Read more about Meshery's stable and edge release channels. - - -Review the mesheryctl Command Reference for details on all subcommands, flags, and their behavior. - -

    On to v0.6.0

    - -To get a more comprehensive list of the bug fixes and enhancements packaged in the v0.5.0 release, see the [Meshery Documentation](https://docs.meshery.io/). With v0.6.0 planning complete these signal of the Layer5 community's innovation cycle trending upward sharply. See Meshery's roadmap for a prelude of what's yet to come. - -

    If these topics excite you and you want to explore the wonderful world of service meshes, come and say "Hi" on the community Slack and you are sure to be warmly welcomed. 😀

    - -
    +--- +title: "Announcing Meshery v0.5.0" +subtitle: "" +date: 2021-04-19 08:00:00 +0000 +author: Aisuko Li +thumbnail: ./v0.5.0.webp +darkthumbnail: ./v0.5.0.webp +category: Announcements +tags: + - Meshery + - Projects +published: true +resource: true +type: Blog +product: Meshery +redirect_from: + - /blog/meshery/announcing-meshery-v0.5.0/ +--- + + + +import MesheryOperatorShot from "./meshery-operator-v0.5.0.webp"; +import MesheryOperator from "./meshery-operator-dark.svg"; +import MeshSync from "./meshsync.svg"; +import MesheryDB from "./meshery-database.svg"; +import MesheryAdapterLibrary from "./meshery-adapter-library.svg"; +import Traefik from "./traefik-mesh.svg"; +import MesheryExtensibility from "./meshery-extensibility.svg"; +import NGINXSM from "./nginx-service-mesh.svg"; +import layer5Logo from "../../../../assets/images/layer5/layer5-only/svg/layer5-no-trim.svg"; + + + +

    We're pleased to announce the release of Meshery 0.5.0! Consisting of a number of significant architectural enhancements with 8 new capabilities entering alpha, Meshery v0.5.0's feature density is impressive. Previewed in the Using Istio workshop delivered at the inaugural IstioCon 2021 earlier this month, Meshery v0.5.0 provides a strong architectural foundation for cloud native application and service mesh management.

    + + +## Feature Highlights +- New GraphQL API +- Meshery Operator with MeshSync inside +- Meshery Adapter for Traefik Mesh (beta) +- MeshKit and the Meshery Adapter Library +- Meshery Adapter for NGINX Service Mesh (alpha) +- Meshery Remote Provider extensions with dynamic injection +- New Meshery CLI commands to manage mutiple Meshery deployments + +
    + +

    Thank you to the wonderful Layer5 community of open source contributors in making this significant release possible.

    +
    + +## New Service Mesh Support + +

    2 new Meshery service mesh adapters are bundled with this latest version of Meshery: The Meshery Adapter for Traefik Mesh and the Meshery Adapter for NGINX Service Mesh.

    + +

    Meshery Adapter for Traefik Mesh (beta)

    + + +

    Traefik Mesh is a straight-forward, easy to configure, and non-invasive service mesh that allows visibility and management of the traffic flows inside any Kubernetes cluster.

    + +

    Meshery supports the lifecycle and performance management of Traefik Mesh. Along with support for multiple versions of Traefik Mesh, bundled with this adapter are the Book Info and HttpBin sample applications operations to aid you in familiarizing with the functionality of Traefik Mesh. As a Meshery user, you can apply custom configuration to your instances of Traefik Mesh, managing the onboarding of your own applications onto the service mesh and providing the ability for you as a service mesh manager to customize your service mesh deployment.

    + +

    Review the sample application guides to familiarize with their differences and learn more about the beta adapter for Meshery Adapter for Traefik Mesh.

    + + +

    Meshery Adapter for NGINX Service Mesh (alpha)

    + + +

    NGINX Service Mesh (NSM) is a fully integrated, lightweight service mesh that leverages a data plane powered by NGINX Plus to manage container traffic in Kubernetes environments.

    + +

    Meshery supports lifecycle and performance management of NGINX Service Mesh. Bundled with this support are a few sample applications to help users understand the functionality of NGINX Service Mesh. lifecycle management and sample applications operations below:

    + +
      +
    • Book Info
    • +
    • HTTPBin
    • +
    • Emojivoto
    • +
    + +

    Review the sample application guides to familiarize with their differences. Learn more about the alpha adapter for Meshery Adapter for NGINX Service Mesh.

    + +

    Integrating with Meshery: Using extension points

    + +As the cloud native manager, Meshery, is an extensible platform offering user and integrators well-crafted, extension points. Extension points allow you to augment the behavior of Meshery by either adding entirely new capabilities or affecting the behavior of existing functionality, as see in the figure below. + +
    + +
    + +As you can see in the diagram, Meshery offers many types of extension points. + +- Extensible Service Mesh Adapters - bring your own service mesh. +- Extensible APIs - bring your own GraphQL resolvers and expose new, custom endpoints. +- Extensible Load Generators - Meshery supports three types of load generators, however, you can bring your own and plug it in. +- Extensible Providers - the v0.5.0 release delivers dynamic injection of Remote Provider extensions. Providers are a powerful mechanism for integrating Meshery into your existing tooling and systems. + +There are two types of Providers in Meshery: Local - built into Meshery and Remote - implemented by anyone or any organization that wishes to integrate with Meshery. Remote Provider extensibility includes: + + * Pluggable UI functionality + * Pluggable Backend functionality + * Pluggable Authentication and Authorization + * Long-Term Persistence + * Enhanced Visualization + * Historical Reporting + +Learn more about the platform Meshery provides to extend its funcionality by exploring its extension points. If you have or are building your own Remote Provider, let us know! +

    MeshKit and Meshery Adapter Library

    + +As a service mesh toolkit, MeshKit aims to specifically focus on service mesh management and provides broadly useful functionality, it provides a standard policy for error handling and logging across all Meshery components, and implementations for error handling, logging, and tracing. + +
      +
    • MeshKit provides common data models of Service Mesh Interface conformance testing for Meshery.
    • +
    • The low-level API abstract by MeshKit to the high-level functions provides out-of-the-box functions.
    • +
    + +

    Meshery Adapter Library

    + +

    The Meshery Adapter Library provides a common and consistent set of functionality for managing the lifecycle of service meshes and their workloads.

    +
    + +
    + +* The library provides a set of interfaces, some with default implementations like a mini framework implementing the gRPC server that allows plugging in the mesh-specific configuration and operations implemented in the adapters. +* The default configuration provider we use Viper to reads the adapter specific configuration, and the configuration providers are implementations of an interface, this can be flexible if anyone wants to implement it on their own. + +

    Read Maintainer Michael Gfeller's blog post Introduction MeshKit and the Meshery Adapter Library for more details.

    + +With the increasing the number and diversity of service meshes supported by Meshery, you might find the list of [Supported Service Meshes](https://docs.meshery.io/service-meshes) a helpful, complete list. + +

    Meshery Operator

    + +

    +As a Kubernetes custom controller, Meshery Operator provides a Kubernetes-native approach to interfacing with Meshery. Kubernetes is where service meshes have gotten their initial foothold, and therefore, important that Meshery interface to Kubernetes natively. +

    +

    Some service meshes support non-containerized workloads outside of the cluster and will grow in this focus over time. While Meshery Operator is Kubernetes only in the v0.5.0 release, Meshery's arichitecture makes considerations for different workload and platform types.

    + +
    +
    + +
    +
      +
    • Meshery Operator is the multi-service mesh operator that runs as a Kubernetes Operator and defines two custom resources: MeshSync and Meshery Broker (NATS)
    • +
    • Meshery Operator is provides abilities includes cluster discovery, service mesh discovery, and data streaming via NATS.
    • +
    +
    + +

    MeshSync

    +

    MeshSync is available as a Kubernetes custom resource that provides tiered discovery and continual synchronization with Meshery Server as to the state of the Kubernetes cluster, service meshes, and their workloads.

    + +
    + +
      + +
    • MeshSync is one of a family of custom controllers within Meshery Operator and is the heartbeat of Meshery, pumping information about service meshes and their workloads throughout Meshery's components.
    • +
    • MeshSync helps Meshery mesh with meshes by helping define a service mesh agnostic object model.
    • +
    • It provides ability to detect service meshes and services deployed on the cluster, and snapshot stored in-memory and refreshed periodically; +maintain the local snapshot of the cluster and refreshed periodically.
    • +
    • MeshSync These abilities above help Meshery operations more resilient.
    • +
    + +
    +

    Relational Database

    + +Meshery's relational database serves as a repository for MeshSync data, user preferences, and system settings. This database should be considered ephemeral and given that it operates as a cache. Meshery relational database offers federated datasets for managing multiple Kubernetes cluster and multiple service meshes. + +
    + +
    + +

    Learn more and consider contributing to MeshSync.

    + +## GraphQL Support + +Meshery now supports GraphQL instances between Meshery UI and Meshery Server offering any GraphQL client the power to ask for exactly what they need from mesh. This new API sets the stage preparing for exciting features in upcoming releases. Extension points are also built into Meshery's GraphQL support allowing integrators to bring their own GraphQL resolvers to the Meshery server runtime. + + +

    Meshery Command Line Interface Enhancements

    +The beloved `mesheryctl` introduces new commands in the v0.5.0 release expands the CLI's support of multiple Meshery deployments with the `context` command and control over when Meshery auto-updates with the `channel` command. + +

    Managing Multiple Meshery Deployments

    +Introduced in this release is the meshconfig - a configuration file that describes Meshery deployments in separate contexts. A Meshery context describes deployments across Docker hosts and Kubernetes clusters. mesheryctl system context enables user to easy manage multiple deployments of Meshery by quickly switching contexts. + +### Subscribing to Meshery Release Channels +`mesheryctl system channel` allows you to easily set and switch between which Meshery release channel (stable or edge) that you want a particilar Meshery deployment (`context`) to use. Meshery deployments subscribe to one of two release channels and can either automatically self-update the deployment or prompt you to update the deployment. Alternatively, you can pin a given Meshery deployment to a specific release should you want tighter control over when Meshery updates. Read more about Meshery's stable and edge release channels. + + +Review the mesheryctl Command Reference for details on all subcommands, flags, and their behavior. + +

    On to v0.6.0

    + +To get a more comprehensive list of the bug fixes and enhancements packaged in the v0.5.0 release, see the [Meshery Documentation](https://docs.meshery.io/). With v0.6.0 planning complete these signal of the Layer5 community's innovation cycle trending upward sharply. See Meshery's roadmap for a prelude of what's yet to come. + +

    If these topics excite you and you want to explore the wonderful world of service meshes, come and say "Hi" on the community Slack and you are sure to be warmly welcomed. 😀

    + +
    diff --git a/src/collections/blog/2021/2021-04-24-buf-protocols/index.mdx b/src/collections/blog/2021/2021-04-24-buf-protocols/index.mdx index ad1986bbc5af..37cdc9b497d7 100644 --- a/src/collections/blog/2021/2021-04-24-buf-protocols/index.mdx +++ b/src/collections/blog/2021/2021-04-24-buf-protocols/index.mdx @@ -1,84 +1,84 @@ ---- -title: "Rethinking Protocol Buffers with Buf" -subtitle: "Buf makes Protocol Buffer APIs easier to create, maintain, and consume" -date: 2021-05-24 22:19:00 -author: "Adithya Krishna" -thumbnail: ./buf-protocol.webp -darkthumbnail: ./buf-protocol.webp -category: "Cloud Native" -tags: - - gRPC -published: true -resource: true -type: Blog ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import { BufProtocol } from "./BufProtocol.style"; -import { Link } from "gatsby"; -import Problems from "./problems.webp"; - - - - - -

    At Layer5, we are continuously evaluating new technologies and incorporating them into our open source projects. Buf is one of those projects. This post presents an overview of Buf.

    - - -## What is Buf? - -

    A tool to make Protobuf reliable and easy to use for service owners and clients, while keeping it the obvious choice on the technical merits. -Our organization should not have to reinvent the wheel to create, maintain, and consume Protobuf APIs efficiently and effectively. It will handle our Protobuf management strategy for us, so we can focus on what matters.

    - -
    Learn more about Buf Protocol, visit Buf Protocol or their documentation at Buf Protocol Docs
    - - - -## Features - -- Automatic file discovery. -- Selectable configuration - 40 lint checkers and 54 breaking checkers -- Selectable error output - `file:line:col:message` -- Check anything from anywhere - proto files, tar, git, pre-built images or file descriptors. -- [Speed](https://docs.buf.build/tour-8/) - Its internal compiler is super fast (approx. 4x then Protoc) -- Can use buf as a protoc plugin instead of using it as a standalone tool. - -## Buf CLI - -Buf attempts to simplify your Protocol Buffers workflow using the Buf CLI and protoc plugins. The Buf CLI currently provides: - -- A linter that enforces good API design choices and structure. -- A breaking change detector that enforces compatibility at the source code level or wire level. -- A generator that invokes your protoc plugins based on a configurable template. A protoc replacement that uses Buf's newly-developed high performance Protobuf compiler. -- A configurable file builder that produces Images, our extension of FileDescriptorSets. - -## Comparison Between Protobuf and Buf -Layer5 projects currently use protoc as the tool for building their protobuf defintions. The following are some considerations made while determining whether to use Buf. - -- Protobuf is not as widely adopted as JSON. -- API Structure - - No standards enforcement - - Inconsistency can arise across an organization's Protobuf APIs, - - Design decisions can be made that can affect your API's future iterability. -- Backward Compatibility -- Stub distribution -- Tooling - -

    Buf aims to solve the above problems and it's long-term goal is to enable schema-driven development: A future where APIs are defined consistently, in a way that service owners and us can depend on

    - -## Roadmap to Adopting Buf -In consideration of the use of Buf, we would adopt it in phases, starting with the following ares of integration. - -- **API Structure Enforcements** - - Linter solves this issue by enforcing standards. - - Also, we don’t need to use Buf as a standalone tool we can just use linter as plugins. - - -- **Backward Compatibility** - - It will check for different things that can cause breaking change. - - For example, type change. - -

    If these topics excite you and you want to explore more cloud native technolgies, come and say "Hi" on the community Slack and you are sure to be warmly welcomed. 😀

    - -
    +--- +title: "Rethinking Protocol Buffers with Buf" +subtitle: "Buf makes Protocol Buffer APIs easier to create, maintain, and consume" +date: 2021-05-24 22:19:00 +author: "Adithya Krishna" +thumbnail: ./buf-protocol.webp +darkthumbnail: ./buf-protocol.webp +category: "Cloud Native" +tags: + - gRPC +published: true +resource: true +type: Blog +--- + + +import { BufProtocol } from "./BufProtocol.style"; + +import Problems from "./problems.webp"; + + + + + +

    At Layer5, we are continuously evaluating new technologies and incorporating them into our open source projects. Buf is one of those projects. This post presents an overview of Buf.

    + + +## What is Buf? + +

    A tool to make Protobuf reliable and easy to use for service owners and clients, while keeping it the obvious choice on the technical merits. +Our organization should not have to reinvent the wheel to create, maintain, and consume Protobuf APIs efficiently and effectively. It will handle our Protobuf management strategy for us, so we can focus on what matters.

    + +
    Learn more about Buf Protocol, visit Buf Protocol or their documentation at Buf Protocol Docs
    + + + +## Features + +- Automatic file discovery. +- Selectable configuration - 40 lint checkers and 54 breaking checkers +- Selectable error output - `file:line:col:message` +- Check anything from anywhere - proto files, tar, git, pre-built images or file descriptors. +- [Speed](https://docs.buf.build/tour-8/) - Its internal compiler is super fast (approx. 4x then Protoc) +- Can use buf as a protoc plugin instead of using it as a standalone tool. + +## Buf CLI + +Buf attempts to simplify your Protocol Buffers workflow using the Buf CLI and protoc plugins. The Buf CLI currently provides: + +- A linter that enforces good API design choices and structure. +- A breaking change detector that enforces compatibility at the source code level or wire level. +- A generator that invokes your protoc plugins based on a configurable template. A protoc replacement that uses Buf's newly-developed high performance Protobuf compiler. +- A configurable file builder that produces Images, our extension of FileDescriptorSets. + +## Comparison Between Protobuf and Buf +Layer5 projects currently use protoc as the tool for building their protobuf defintions. The following are some considerations made while determining whether to use Buf. + +- Protobuf is not as widely adopted as JSON. +- API Structure + - No standards enforcement + - Inconsistency can arise across an organization's Protobuf APIs, + - Design decisions can be made that can affect your API's future iterability. +- Backward Compatibility +- Stub distribution +- Tooling + +

    Buf aims to solve the above problems and it's long-term goal is to enable schema-driven development: A future where APIs are defined consistently, in a way that service owners and us can depend on

    + +## Roadmap to Adopting Buf +In consideration of the use of Buf, we would adopt it in phases, starting with the following ares of integration. + +- **API Structure Enforcements** + - Linter solves this issue by enforcing standards. + - Also, we don’t need to use Buf as a standalone tool we can just use linter as plugins. + + +- **Backward Compatibility** + - It will check for different things that can cause breaking change. + - For example, type change. + +

    If these topics excite you and you want to explore more cloud native technolgies, come and say "Hi" on the community Slack and you are sure to be warmly welcomed. 😀

    + +
    \ No newline at end of file diff --git a/src/collections/blog/2021/2021-06-25-she-code-africa-contributhon-boot-camp/index.mdx b/src/collections/blog/2021/2021-06-25-she-code-africa-contributhon-boot-camp/index.mdx index eb27584cf045..1f122c3c70f8 100644 --- a/src/collections/blog/2021/2021-06-25-she-code-africa-contributhon-boot-camp/index.mdx +++ b/src/collections/blog/2021/2021-06-25-she-code-africa-contributhon-boot-camp/index.mdx @@ -1,130 +1,131 @@ ---- -title: "She Code Africa Contributhon Boot Camp Report" -date: 2021-06-25 16:00:00 +0000 -author: Anita Charles -thumbnail: ./sca-thumbnail.webp -darkthumbnail: ./sca-thumbnail.webp -category: Community -tags: - - Community - - MeshMate -published: true ---- - -import { Link } from "gatsby"; - -import Sandy from "./sandySCA.webp"; -import Abiola from "./abiolaSCA.webp"; -import Cynthia from "./cynthiaSCA.webp"; -import Elizabeth from "./elizabethSCA.webp"; -import Blossom from "./blossomSCA.webp"; -import Joy from "./joySCA.webp"; -import Naimat from "./naimatSCA.webp"; - -import { BlogWrapper } from "../../Blog.style.js"; - - -

    - Layer5 participated as a suporting organization in the She Code Africa Contributhon which started on April 1, 2021. It was indeed a pleasant and impactful experience for both the mentors and the mentees from She Code Africa. -

    -

    - The She Code Africa hosts their Contributhon as an Africa-wide open source boot camp focused on building more women OSS contributors & creating more diversity in the African open source ecosystem by matching African women in technology with sponsors and mentors from Open Source organizations. During this boot camp, participants work with an open source organisation on a project for 4 weeks with the help of organisation mentors and get rewarded at the end of the boot camp upon successful project completion. -

    - - During the boot camp, Layer5 received a total of 8 mentees - all from Nigeria. These mentees were teamed up to work on the 3 project ideas selected by Layer5. Each project had an average of 2 members of the community who were delegated as mentors to oversee the contributions of the mentees. Often Layer5 MeshMates volunteer to be mentors. - -

    Projects

    -

    Layer5 mentors prepared and organized a few projects in advance of the start of the boot camp, so that mentees might hit the ground running.

    - -

    Layer5 Community Handbook

    - -

    - Layer5 Community Handbook is a curated Document with the ABC's of the community. In this project, mentees were expected to look for repetition pattern across existing docs thereby, creating a structured guide for interaction across all projects. -

    - Mentors: -
      -
    • Ruth Ikegah
    • -
    • Anita Ihuman
    • -
    - Mentee(s): - - - -

    - sandy-testimonial - abiola-testimonial -

    - -

    Layer5 Main Website

    - -

    - This required the contributors to fix existing issues on the GitHub repository, while suggesting ideas to improve the website, which used Gatsbyjs and Reactjs. The layer5.io website is hosted on GitHub Pages and is a collaborative effort of nearly 200 contributors. -

    - Mentors: -
      -
    • Jash Patel
    • -
    • Chinmay Mehta
    • -
    - Mentee(s): - - -

    - cynthia-testimonial - elizabeth-testimonial -

    -

    Meshery CLI

    -

    - mesheryctl is a command-line tool for Meshery, the cloud native management plane. Using Golang, mentees were required to design new CLI commands and attend to existing issues, focusing on enforcing the consistency of user experience with the command line client. -

    - - Mentors: -
      -
    • Navendu Pottekkat
    • -
    • Chinmay Mehta
    • -
    - Mentee(s): -
      -
    • Joy Nwaiwu
    • -
    • Naimat Oyewale
    • -
    - -

    - naimat-testimonial - joy-testimonial -

    - -

    - The mentors were in constant communication with the mentees, taking their questions and rendering help when needed. At the end of the Contribution boot camp, it was heartwarming to see the mentees were able to make noticeable contributions to the projects. During the boot camp wrap up call, mentees gave presentations that revealed how impactful it was for them working on Layer5 projects. -

    - -

    Appreciation

    -

    - In gratitude, we acknowledge the commitment and contributions of the mentees toward the projects and we won't forget our incredible mentors who were devoted to meeting the needs and answering to the mentees during this bootcamp. Also, we would like to appreciate Zainab Abubakar for having facilitated the She Code Africa - Contribution 2021.

    - -
    +--- +title: "She Code Africa Contributhon Boot Camp Report" +date: 2021-06-25 16:00:00 +0000 +author: Anita Charles +thumbnail: ./sca-thumbnail.webp +darkthumbnail: ./sca-thumbnail.webp +category: Community +tags: + - Community + - MeshMate +published: true +--- + + + +import Sandy from "./sandySCA.webp"; +import Abiola from "./abiolaSCA.webp"; +import Cynthia from "./cynthiaSCA.webp"; +import Elizabeth from "./elizabethSCA.webp"; +import Blossom from "./blossomSCA.webp"; +import Joy from "./joySCA.webp"; +import Naimat from "./naimatSCA.webp"; + + + + +

    + Layer5 participated as a suporting organization in the She Code Africa Contributhon which started on April 1, 2021. It was indeed a pleasant and impactful experience for both the mentors and the mentees from She Code Africa. +

    +

    + The She Code Africa hosts their Contributhon as an Africa-wide open source boot camp focused on building more women OSS contributors & creating more diversity in the African open source ecosystem by matching African women in technology with sponsors and mentors from Open Source organizations. During this boot camp, participants work with an open source organisation on a project for 4 weeks with the help of organisation mentors and get rewarded at the end of the boot camp upon successful project completion. +

    + + During the boot camp, Layer5 received a total of 8 mentees - all from Nigeria. These mentees were teamed up to work on the 3 project ideas selected by Layer5. Each project had an average of 2 members of the community who were delegated as mentors to oversee the contributions of the mentees. Often Layer5 MeshMates volunteer to be mentors. + +

    Projects

    +

    Layer5 mentors prepared and organized a few projects in advance of the start of the boot camp, so that mentees might hit the ground running.

    + +

    Layer5 Community Handbook

    + +

    + Layer5 Community Handbook is a curated Document with the ABC's of the community. In this project, mentees were expected to look for repetition pattern across existing docs thereby, creating a structured guide for interaction across all projects. +

    + Mentors: +
      +
    • Ruth Ikegah
    • +
    • Anita Ihuman
    • +
    + Mentee(s): + + + +

    + sandy-testimonial + abiola-testimonial +

    + +

    Layer5 Main Website

    + +

    + This required the contributors to fix existing issues on the GitHub repository, while suggesting ideas to improve the website, which used Gatsbyjs and Reactjs. The layer5.io website is hosted on GitHub Pages and is a collaborative effort of nearly 200 contributors. +

    + Mentors: +
      +
    • Jash Patel
    • +
    • Chinmay Mehta
    • +
    + Mentee(s): + + +

    + cynthia-testimonial + elizabeth-testimonial +

    +

    Meshery CLI

    +

    + mesheryctl is a command-line tool for Meshery, the cloud native management plane. Using Golang, mentees were required to design new CLI commands and attend to existing issues, focusing on enforcing the consistency of user experience with the command line client. +

    + + Mentors: +
      +
    • Navendu Pottekkat
    • +
    • Chinmay Mehta
    • +
    + Mentee(s): +
      +
    • Joy Nwaiwu
    • +
    • Naimat Oyewale
    • +
    + +

    + naimat-testimonial + joy-testimonial +

    + +

    + The mentors were in constant communication with the mentees, taking their questions and rendering help when needed. At the end of the Contribution boot camp, it was heartwarming to see the mentees were able to make noticeable contributions to the projects. During the boot camp wrap up call, mentees gave presentations that revealed how impactful it was for them working on Layer5 projects. +

    + +

    Appreciation

    +

    + In gratitude, we acknowledge the commitment and contributions of the mentees toward the projects and we won't forget our incredible mentors who were devoted to meeting the needs and answering to the mentees during this bootcamp. Also, we would like to appreciate Zainab Abubakar for having facilitated the She Code Africa + Contribution 2021. +

    + +
    diff --git a/src/collections/blog/2021/2021-06-4-announcing-summer-interns/index.mdx b/src/collections/blog/2021/2021-06-4-announcing-summer-interns/index.mdx index 93c306066136..747bd2549824 100644 --- a/src/collections/blog/2021/2021-06-4-announcing-summer-interns/index.mdx +++ b/src/collections/blog/2021/2021-06-4-announcing-summer-interns/index.mdx @@ -1,93 +1,94 @@ ---- -title: "Meet the Summer Interns of 2021" -date: 2021-06-04 08:00:00 +0000 -author: Interns of Summer 2021 -thumbnail: ./summer-intern.webp -darkthumbnail: ./summer-intern.webp -category: "Community" -tags: - - Community -featured: true -published: true ---- - -import { Link } from "gatsby"; - -import Dhruv from "./intern-dhruv-patel.webp"; -import Soham from "./intern-soham-sonawane.webp"; -import Piyush from "./intern-piyush-singariya.webp"; - -import { BlogWrapper } from "../../Blog.style.js"; - - - -
    -

    - Layer5 participates in many - open source internship programs. We seek out existing contributors who - actively reflect the culture and principles of Layer5 to participate in these programs. Here are the Summer of 2021's open source interns.

    -
    - -Hear about their journeys and follow along this summer as they make waves in the Layer5 community. - -

    - - Dhruv Patel - -

    - dhruv-patel -

    - Open source has been intriguing to me ever since I had joined my college's open-source community (DevlupLabs). It was in the middle of the pandemic, though, with my mind trying to find an escape, that I stumbled upon Layer5. Within the first week of joining the Layer5 community, I had a pull request posted, and much to my surprise, found myself demo'ing it in the very next community meeting. In retrospect, it was a minor pull request, making some UI changes for Meshery. The encouragement I received was so welcoming and supportive. After that first week's experience, and so much technology and projects to explore, I was hooked - there was no turning back for me from that point. -

    -

    - I started learning more about the projects in Layer5 and its tech stack. From how Meshery Server was using gRPC and protobufs to communicate with each of its service mesh adaptors to defining how SMI Conformance works and the Service Mesh Performance specification to how Meshery UI leverages some awesome libraries like NextJS, BillboardJS, and Redux. It has been through contributing to each of these areas, that I have learned each of these technologies more deeply and it was all possible because of the continuous influx of awesome support from the community, especially Abishek Kumar and I probably won't stop poking him for support anytime soon. -

    -

    - As I look forward to a structured internship with Layer5 through Google Summer of Code this summer, I do so knowing I will be collaborating with the large Layer5 community, engineers from other technology companies and spending a lot of time with Soham and Piyush. For my part, I'll be working on a visual topology to help service mesh operators map their deployments, model their application performance, and parse their service proxy logs. I am ready to make an impact, learn more, and help other community members ( and watch as they, too, are initiated into the Layer5 community through ritual of giving an awkward first-timer introduction in our Community Meeting 😛). -

    - -

    - - Piyush Singariya - -

    - piyush-singariya -

    - It all started with an idea, the idea of doing open source contributions. And with that after scrolling through many open source communities, I found Layer5, jumped up into our Slack workspace, started learning about Meshery. I raised a PR and was immediately made to feel like a rockstar. I began meeting more of the community members, learning more about Meshery and its command line client, `mesheryctl` with each contribution. And you know, its extrenely gratifying to have your pull request merged, and that feeling is amplified by the feedback and attention you receive as a contributor at Layer5. -

    -

    - I knew that I wanted to engage even more deeply and learn all that I can from the seasoned engineers at Layer5. And so, I applied for internship. Layer5 takes internships seriously and doesn't accept anyone into internship until you have proven your commitment to their awesome projects. - And at the time of writing this, it’s been almost three months of contributing bfore being accepted as GSoC student. I have spent most of my time focusing on Layer5’s Meshery project and it’s command line client, `mesheryctl`. -

    -

    - And so, we reach the beginning of my GSoC 2021 program, which began on the night of May 17th, 2021 when I learned that I had been selected as a GSoC Participant with the Cloud Native Computing Foundation (CNCF). I am hyped up and excited to go ahead with Layer5 for the upcoming months. -

    -

    - My GSoC project is about introducing interesting and important features to Meshery Server and `mesheryctl`. Such as automating Documentation and Interactive playground for Meshery Server’s REST API endpoints, adding commands related to performance testing and enhancing Meshery’s environment health checking, introducing unit testing for `mesheryctl`, and CI/CD and documentation for all the new features. -

    -

    - It has been 2 weeks since I have started my GSoC’21 tenure with the Layer5 community, and from the very beginning (I mean before GSoC), I have learned a lot with my code contributions and the Community here. I began with setting up the performance command under mesheryctl and Open API Specification 2.0 for REST API documentation to the project. I am learning a lot of new things, like Unit Testing, Open API Specification, and much more to include. -

    - -

    - Soham Sonawane -

    - soham-sonaware -

    - I got to know about Layer5 last year in December when one of my batchmates told me that he was contributing to the community. He asked me if I wanted to join Slack and wanted to contribute to a project. So I looked at the projects on Github and some open issues that I could contribute to. Me being a frontend developer I saw an issue related to removing whitespaces and minor frontend changes. I just made a PR and it was merged then I joined the Slack workspace and attended the Newcomers meeting. I was introduced to a lot of things that I could work on. All of them felt amazing and interesting, all I had to do was “signal” and I could work on any one of them. -

    -

    - At first I thought that I should just work on layer5.io or maybe NightHawk, but then I was given an opportunity to work on something that I had never done before. It has been around 4 months that I have been a part of the community and I am actively trying to add to the project attending weekly meetings where everyone shares amazing stuff about what they did. -

    -

    - As I said earlier my project is something that I had never worked on before, very interesting to work on, it adds one of the most important and unique features to Meshery. Meshery's MeshMap enables users to visualize their service meshes, look at important statistics. It also enables users to design their own service meshes by either importing their designs from a yaml file or by dragging and dropping service mesh components into a - canvas, creating edges, grouping components, persisting these designs to see or edit later, realizing these designs by actually deploying them as service meshes and a lot more. -

    -

    - My job is to be the God of CytoscapeJS, who knows every nook and cranny of the library that enables us to create the visual topology. It's been a week since I have started my LFX internship and I have been working on visual topology even before that. These months of contributing code have taught me a lot. The first task that was given to me was to explore the - CytoscapeJS library and demonstrate a proof of concept of animated edges between 2 components. I sat for 3 hours straight right after the community meeting creating the demo and posted a video on our slack. I was never - appreciated better than on that day. I have never looked back since, each time I am given a feature or issue or any request I try my hardest to realize it in the earliest. I am constantly trying to improve myself and add to the project. -

    - - \- Dhruv, Piyush, and Soham +--- +title: "Meet the Summer Interns of 2021" +date: 2021-06-04 08:00:00 +0000 +author: Interns of Summer 2021 +thumbnail: ./summer-intern.webp +darkthumbnail: ./summer-intern.webp +category: "Community" +tags: + - Community +featured: true +published: true +--- + + + +import Dhruv from "./intern-dhruv-patel.webp"; +import Soham from "./intern-soham-sonawane.webp"; +import Piyush from "./intern-piyush-singariya.webp"; + + + + + +
    +

    + Layer5 participates in many + open source internship programs. We seek out existing contributors who + actively reflect the culture and principles of Layer5 to participate in these programs. Here are the Summer of 2021's open source interns. +

    +
    + +Hear about their journeys and follow along this summer as they make waves in the Layer5 community. + +

    + + Dhruv Patel + +

    + dhruv-patel +

    + Open source has been intriguing to me ever since I had joined my college's open-source community (DevlupLabs). It was in the middle of the pandemic, though, with my mind trying to find an escape, that I stumbled upon Layer5. Within the first week of joining the Layer5 community, I had a pull request posted, and much to my surprise, found myself demo'ing it in the very next community meeting. In retrospect, it was a minor pull request, making some UI changes for Meshery. The encouragement I received was so welcoming and supportive. After that first week's experience, and so much technology and projects to explore, I was hooked - there was no turning back for me from that point. +

    +

    + I started learning more about the projects in Layer5 and its tech stack. From how Meshery Server was using gRPC and protobufs to communicate with each of its service mesh adaptors to defining how SMI Conformance works and the Service Mesh Performance specification to how Meshery UI leverages some awesome libraries like NextJS, BillboardJS, and Redux. It has been through contributing to each of these areas, that I have learned each of these technologies more deeply and it was all possible because of the continuous influx of awesome support from the community, especially Abishek Kumar and I probably won't stop poking him for support anytime soon. +

    +

    + As I look forward to a structured internship with Layer5 through Google Summer of Code this summer, I do so knowing I will be collaborating with the large Layer5 community, engineers from other technology companies and spending a lot of time with Soham and Piyush. For my part, I'll be working on a visual topology to help service mesh operators map their deployments, model their application performance, and parse their service proxy logs. I am ready to make an impact, learn more, and help other community members ( and watch as they, too, are initiated into the Layer5 community through ritual of giving an awkward first-timer introduction in our Community Meeting 😛). +

    + +

    + + Piyush Singariya + +

    + piyush-singariya +

    + It all started with an idea, the idea of doing open source contributions. And with that after scrolling through many open source communities, I found Layer5, jumped up into our Slack workspace, started learning about Meshery. I raised a PR and was immediately made to feel like a rockstar. I began meeting more of the community members, learning more about Meshery and its command line client, `mesheryctl` with each contribution. And you know, its extrenely gratifying to have your pull request merged, and that feeling is amplified by the feedback and attention you receive as a contributor at Layer5. +

    +

    + I knew that I wanted to engage even more deeply and learn all that I can from the seasoned engineers at Layer5. And so, I applied for internship. Layer5 takes internships seriously and doesn't accept anyone into internship until you have proven your commitment to their awesome projects. + And at the time of writing this, it’s been almost three months of contributing bfore being accepted as GSoC student. I have spent most of my time focusing on Layer5’s Meshery project and it’s command line client, `mesheryctl`. +

    +

    + And so, we reach the beginning of my GSoC 2021 program, which began on the night of May 17th, 2021 when I learned that I had been selected as a GSoC Participant with the Cloud Native Computing Foundation (CNCF). I am hyped up and excited to go ahead with Layer5 for the upcoming months. +

    +

    + My GSoC project is about introducing interesting and important features to Meshery Server and `mesheryctl`. Such as automating Documentation and Interactive playground for Meshery Server’s REST API endpoints, adding commands related to performance testing and enhancing Meshery’s environment health checking, introducing unit testing for `mesheryctl`, and CI/CD and documentation for all the new features. +

    +

    + It has been 2 weeks since I have started my GSoC’21 tenure with the Layer5 community, and from the very beginning (I mean before GSoC), I have learned a lot with my code contributions and the Community here. I began with setting up the performance command under mesheryctl and Open API Specification 2.0 for REST API documentation to the project. I am learning a lot of new things, like Unit Testing, Open API Specification, and much more to include. +

    + +

    + Soham Sonawane +

    + soham-sonaware +

    + I got to know about Layer5 last year in December when one of my batchmates told me that he was contributing to the community. He asked me if I wanted to join Slack and wanted to contribute to a project. So I looked at the projects on Github and some open issues that I could contribute to. Me being a frontend developer I saw an issue related to removing whitespaces and minor frontend changes. I just made a PR and it was merged then I joined the Slack workspace and attended the Newcomers meeting. I was introduced to a lot of things that I could work on. All of them felt amazing and interesting, all I had to do was “signal” and I could work on any one of them. +

    +

    + At first I thought that I should just work on layer5.io or maybe NightHawk, but then I was given an opportunity to work on something that I had never done before. It has been around 4 months that I have been a part of the community and I am actively trying to add to the project attending weekly meetings where everyone shares amazing stuff about what they did. +

    +

    + As I said earlier my project is something that I had never worked on before, very interesting to work on, it adds one of the most important and unique features to Meshery. Meshery's MeshMap enables users to visualize their service meshes, look at important statistics. It also enables users to design their own service meshes by either importing their designs from a yaml file or by dragging and dropping service mesh components into a + canvas, creating edges, grouping components, persisting these designs to see or edit later, realizing these designs by actually deploying them as service meshes and a lot more. +

    +

    + My job is to be the God of CytoscapeJS, who knows every nook and cranny of the library that enables us to create the visual topology. It's been a week since I have started my LFX internship and I have been working on visual topology even before that. These months of contributing code have taught me a lot. The first task that was given to me was to explore the + CytoscapeJS library and demonstrate a proof of concept of animated edges between 2 components. I sat for 3 hours straight right after the community meeting creating the demo and posted a video on our slack. I was never + appreciated better than on that day. I have never looked back since, each time I am given a feature or issue or any request I try my hardest to realize it in the earliest. I am constantly trying to improve myself and add to the project. +

    + + \- Dhruv, Piyush, and Soham
    \ No newline at end of file diff --git a/src/collections/blog/2021/2021-08-24-experience-gsoc-piyush-singariya/index.mdx b/src/collections/blog/2021/2021-08-24-experience-gsoc-piyush-singariya/index.mdx index c651b3806db2..1373e16f4f37 100644 --- a/src/collections/blog/2021/2021-08-24-experience-gsoc-piyush-singariya/index.mdx +++ b/src/collections/blog/2021/2021-08-24-experience-gsoc-piyush-singariya/index.mdx @@ -1,109 +1,109 @@ ---- -title: GSoC Experience @ Layer5 - Piyush Singariya -subtitle: damn, it was good! -date: 2021-08-25 10:30:05 -0530 -author: Piyush Singariya -thumbnail: ./gsoc-wide.webp -darkthumbnail: ./gsoc-wide.webp -category: Programs -tags: - - GSoC - - Programs - - Meshery - - Internship -published: true ---- - -import { BlogWrapper } from "../../Blog.style.js"; - -import gsocLogo from "./gsoc.webp"; - - -gsoc-image -

    - Hi, I am Piyush Singariya, a short description of me would be “another - software engineer watching anime”, in the longer version I am a 2021 graduate - from IIT Roorkee, who loves to watch anime and play video games all day. I - know both are exactly the same, but it is what it is. -

    -

    - It all started around 22 Feb when I jumped into slack, and after 10 whole days - messing around the project, I started to get a hold of it. I started - contributing to mesheryctl and I thought to apply for the GSoC 2021. -

    -

    Project

    -

    - My project was to introduce multiple net new features and minor enhancements - in Meshery and mesheryctl (Meshery’s CLI). -

    -

    - Meshery is a multi-service mesh management plane that offers lifecycle, - configuration, and performance management of service meshes and applications - running on top of those meshes. Meshery uses the{" "} - Service Mesh Performance specification to - describe and capture performance benchmarks and characterize service mesh - behavior. -

    -

    - I integrated many new features in Meshery Some of them are mentioned here. -

    -

    mesheryctl

    -
      -
    • - Adding a new command to meshery's cli, i.e. mesheryctl for performance - profiles and result management -
    • -
    • - Introduction of Unit Testing and Integration testing for Cobra commands of - cli, mesheryctl. -
        -
      • Reached 28% code-coverage in mesheryctl
      • -
      -
    • -
    • - Introducing health-checks for environment checking of pre/post-deployment of - meshery server -
    • -
    • - Adding a new command to meshery's cli, i.e. mesheryctl for managing - Webssembly filters -
    • -
    -

    Meshery

    -
      -
    • Reworking and consolidation of API endpoint handlers
    • -
    • Swagger Spec definition and automatic publishing of documentation
    • -
    -

    Others

    -
      -
    • - Documentation on writing Unit and Integration Tests and Contributing to - Meshery Server Documentation -
    • -
    • - CI workflow for Swagger Documentation and running Unit and Integration Tests - with calculating Code-coverage with CodeCov -
    • -
    -

    - Refer here for{" "} - GSoC Final Report -

    -

    What did I learn?

    -

    - During the whole season, as my work was mostly focused on Golang so I can say - I learned Golang, learned working around HTTP handlers, writing cobra - commands, setting up golang unit testing for Cobra Commands(damn, it was - tough), writing environment health-checks, writing GitHub-actions, Open-API - specification 2.0, -

    -

    Summary

    -

    - A quick summary of this experience would be that I had a really good time with - Layer5, I learned, I engaged with other folks in the community, and I believe - the environment here is truly best for any student to spend their time here, - to learn and engage with each other. The folks here are crazy for helping new - members get started with Layer5 projects. -

    - -
    +--- +title: GSoC Experience @ Layer5 - Piyush Singariya +subtitle: damn, it was good! +date: 2021-08-25 10:30:05 -0530 +author: Piyush Singariya +thumbnail: ./gsoc-wide.webp +darkthumbnail: ./gsoc-wide.webp +category: Programs +tags: + - GSoC + - Programs + - Meshery + - Internship +published: true +--- + + + +import gsocLogo from "./gsoc.webp"; + + +gsoc-image +

    + Hi, I am Piyush Singariya, a short description of me would be “another + software engineer watching anime”, in the longer version I am a 2021 graduate + from IIT Roorkee, who loves to watch anime and play video games all day. I + know both are exactly the same, but it is what it is. +

    +

    + It all started around 22 Feb when I jumped into slack, and after 10 whole days + messing around the project, I started to get a hold of it. I started + contributing to mesheryctl and I thought to apply for the GSoC 2021. +

    +

    Project

    +

    + My project was to introduce multiple net new features and minor enhancements + in Meshery and mesheryctl (Meshery’s CLI). +

    +

    + Meshery is a multi-service mesh management plane that offers lifecycle, + configuration, and performance management of service meshes and applications + running on top of those meshes. Meshery uses the{" "} + Service Mesh Performance specification to + describe and capture performance benchmarks and characterize service mesh + behavior. +

    +

    + I integrated many new features in Meshery Some of them are mentioned here. +

    +

    mesheryctl

    +
      +
    • + Adding a new command to meshery's cli, i.e. mesheryctl for performance + profiles and result management +
    • +
    • + Introduction of Unit Testing and Integration testing for Cobra commands of + cli, mesheryctl. +
        +
      • Reached 28% code-coverage in mesheryctl
      • +
      +
    • +
    • + Introducing health-checks for environment checking of pre/post-deployment of + meshery server +
    • +
    • + Adding a new command to meshery's cli, i.e. mesheryctl for managing + Webssembly filters +
    • +
    +

    Meshery

    +
      +
    • Reworking and consolidation of API endpoint handlers
    • +
    • Swagger Spec definition and automatic publishing of documentation
    • +
    +

    Others

    +
      +
    • + Documentation on writing Unit and Integration Tests and Contributing to + Meshery Server Documentation +
    • +
    • + CI workflow for Swagger Documentation and running Unit and Integration Tests + with calculating Code-coverage with CodeCov +
    • +
    +

    + Refer here for{" "} + GSoC Final Report +

    +

    What did I learn?

    +

    + During the whole season, as my work was mostly focused on Golang so I can say + I learned Golang, learned working around HTTP handlers, writing cobra + commands, setting up golang unit testing for Cobra Commands(damn, it was + tough), writing environment health-checks, writing GitHub-actions, Open-API + specification 2.0, +

    +

    Summary

    +

    + A quick summary of this experience would be that I had a really good time with + Layer5, I learned, I engaged with other folks in the community, and I believe + the environment here is truly best for any student to spend their time here, + to learn and engage with each other. The folks here are crazy for helping new + members get started with Layer5 projects. +

    + +
    diff --git a/src/collections/blog/2021/2021-09-01-announcing-fall-interns/index.mdx b/src/collections/blog/2021/2021-09-01-announcing-fall-interns/index.mdx index 3eeaadc4289a..a054c0296ca5 100644 --- a/src/collections/blog/2021/2021-09-01-announcing-fall-interns/index.mdx +++ b/src/collections/blog/2021/2021-09-01-announcing-fall-interns/index.mdx @@ -1,138 +1,139 @@ ---- -title: "Meet the Fall Interns of 2021" -date: 2021-09-01 08:00:00 +0000 -author: Interns of Fall 2021 -thumbnail: ./fall-interns.webp -darkthumbnail: ./fall-interns.webp -category: "Community" -tags: - - Community -featured: true -published: true ---- - -import { Link } from "gatsby"; - -import Nithish from "./nithish-karthik.webp"; -import Ashish from "./ashish-tiwari.webp"; -import Rudraksh from "./rudraksh-pareek.webp"; -import Bariq from "./bariq-nurlis.webp"; - -import { BlogWrapper } from "../../Blog.style.js"; - - - - -
    -

    - Layer5 participates in many - - open source internship programs - . We seek out existing contributors who actively reflect the culture and - principles of Layer5 to participate in these programs. Here are the Fall of 2021's - open source interns. -

    -
    - -Hear about their journeys and follow along this fall as they make waves in the Layer5 community. - -

    - - Bariq Nurlis - -

    - bariq-nurlis -
    -

    - The idea of contributing to an open source has been on the back of my mind since I enrolled in college back in 2019. Like how most people formulate what and how they will do in the uni, I also came from normalcy. In Singapore, students are aiming to get the best mark in every possible lesson in college as our grades hold a very high importance in the culture. Going back and forth between classes, planning a startup with my peers, volunteering in community clubs, I had a spectacular two years in uni. -

    -

    -However, during the last summer break, I started asking myself questions. How should I be better? What should I do? When should I do it? As I got more familiar with the Uni and all my messes (like clubs and tech-stacks that I used), I was in my comfort zone. From my experience, once you know that you’re in a comfort zone, that is exactly when you should start taking actions. Then, I found out the concept of open source. I know that I could hone my skills even further in the community, plus I could learn from the very best from all over the world. I took the initiative to join some Discord channels for open source communities and try to contribute to an open source which then somewhat went begrudgingly bad. Frankly, the experience wasn’t as good as I expected. Trying to pinch my way in a Google Summer of Code project, I am overwhelmed by numerous people trying to do the same. -

    -

    -I thought open source would be like this all the time and it failed me. But then, I took my second chance and joined Layer5. First two weeks, I tried to familiarize myself with the project and joined in the community calls. I remember sharing my screen the first time in the community call, and it was thrilling, my hands can't stop shaking. I was very excited to share my tiny bit of change in the UI which then welcomed wholeheartedly by the people inside. Overall, I met with a lot of wonderful people that don't mind extending their hands if I am in difficulty. My thoughts on open source were wrong and I realize that it's just a little badness from the overall goodness. Just like Yin Yang. Layer5 has been a supportive community that not only develops your technical side, it nurtures your thinking and reasoning. -

    - -

    - - Rudraksh Pareek - -

    - rudraksh-pareek -
    -

    -My journey with open source started when I got into college and fell into the company of some geeky open source evangelists. They were the folks from my local open source communities, OSDC and JODC. I learnt there what it means to be a good open source citizen. The fact that I could learn by contributing to a real world project albeit being a student, novice in programming, intrigued me the most and thus I had this goal clear in my mind to make an impact by working on open source software. -However, it was easier said than done. I started making small contributions to some projects that I came across but couldn't do much past that. Me being a shy kid and the lack of a welcoming community always came into my way. But this all changed when I approached Lee in the CNCF slack for a GSoC internship. I was invited to Layer5. Since day one, I could feel there was something much different about how the community is treated here. Just as I joined, I received a ton of welcome messages and resources to get started. With the course of time and some great advice I moved on from that internship. I decided to become a good contributor first. Though I started with small contributions here too, this time I was able to scale up with time with help and guidance from the community. Whenever I was assigned something, I tried to get my teeth into it as deep as I could before reaching out for help. This helped me learn a lot in a healthy way. -

    -

    - There was so much happening around and I wanted to be a part of it all. So I started attending all the meetings and was able to put my finger into many pies. I soon became better at expressing my thoughts and pretty soon, I developed an interest in CI/CD practices. Starting with small workflows, I went on to write GitHub actions for performing SMI conformance and SMP tests in CI pipelines. At the same time, I also found myself working on mesheryctl and the adapters as I came across bugs while working on the actions. Fast forward a few months and I was nominated a Meshery CI maintainer. I couldn't be much happier than this but little did I know there was more coming. -I learnt about how internships worked at Layer5 during the time I spent and agreed with it in the best sense. Generally, open source projects tend to get more welcoming and open around the months of internship program applications. However, this short span often leads to unjust outcomes. -

    -

    - Thus, I believe paying back for what you give to the project is a philosophy in the best faith of everyone in the long term. I kept my patience until I was asked to apply for an internship and I eventually got selected. I finally knew that I had started to make that impact I always wanted to. -During the course of my internship, I'll be working under the mentorship of Utkarsh Srivastava on improving Layer5 Cloud, the remote provider, and making it securely distributable and usable in "on premise environments". I'll also be collaborating with Ashish Tiwari on integrating a workflow engine with Meshery introducing best practices to be followed by management software. -Looking forward to learning and growing during this time while continuing to try my best to help others in the community. - -

    -

    -Thank you. -

    - -

    - Nithish Karthik -

    - nithish-karthik -
    -

    - I knew exactly what I wanted to do ever since my childhood, I wanted to become a programmer. Technology related stuff always intrigued me. But I had to prepare for an entrance examination IITJEE which required enormous dedication and focus to succeed. And so, I had to put my coding dreams on hold till I joined college. -

    -

    - -But after I joined college, I felt a sense of freedom within me, in the sense that I could now pursue my passion wholeheartedly. So, the next question was, "Where do I start ?". -There were a lot of buzz words going around in my college among my peers like CP, Dev, AI and ML etc. I also noticed that people were forcing themselves to do them even when they had no sense of passion or appreciation towards the field. But for me, I always had more joy in the process of doing something than the outcome I get from it. So, I started exploring various fields to find what I loved the most. And I found that I wanted to do development. - -

    -

    -So, I started working on myself. After I got the fundamentals clear, I wanted to have some practical experience to have an idea of how production grade products are being made. So, I worked on a couple of startups to get an exposure to real world development. And I learned a lot during that period. But then, I felt I needed to switch my gear. The idea of open source has always intrigued me the most but my efforts towards open source contribution has not been a success because, - -1. I always got intimidated by the size of codebase -2. I didn't have people guiding me - -Some of my seniors, who had the best interest in me, encouraged me to get into open source, but I did not take it seriously because I felt intimidated by the idea. I instead thought I would look for some open source internships that way I would have someone mentoring me and that would help me in starting my open source journey. I went through many programs but most of them were closed at that time, except, Meshery in LFX. I thought, this is the only choice I have, let's do it, I had nothing to lose. I applied for that program and as a prerequisite, I had to engage with the community. I looked at the community calendar and I saw that there was a newcomer's call that day and I attended it. I have never had such a warm welcome in any other communities. - - -

    -

    -On that day, I knew that this community is special and I should spend more time with it. I explored the projects and as usual, I felt intimidated, but this time, I had people, wonderful people to help me. I landed my first open source PR, which was a single line style change. But the encouragement and support I got from the community for that was so wonderful . I realised that this community is not just about building best quality products but also about building best quality human beings. It has been a roller coaster ride with Layer5 since then. I got so involved with the process that I had stopped caring about getting that internship. - -

    -

    - The community has really wonderful people who taught me not only about coding, but also about "How to be". I am really grateful that I found this community and I hope that everyone has a chance to experience this. -I started engaging more in the community projects, especially Meshery UI and always kept coming up with ways to improve it. -

    -

    - And fast forward to September 2021, I was told to enroll for the LFX fall term mentorship program and here I am. But, this has never been the goal for me, there is more to me and Layer5 than this internship. I will be engaged with this community as long as I can and will try to give back as much as I can. -

    -

    - Thank you -

    -

    - Ashish Tiwari -

    - ashish-tiwari -
    -

    -I started my programming career in 2020 when my classmates were bagging internships.I started late because the first two years of my college I never thought that I was a "programming guy" as I always was more of a Physics/Mathematics guy. But in 2020, when the pandemic hit I started programming from "hello world". I thought I was too late to the party and often felt overwhelmed. After 1 year of getting a taste of everything from data structures, web development, databases and everything in between that a CS undergraduate comes across; I thought to call myself a Backend dev. But I still was dissatisfied and finding something interesting when I came across the concept of containerization which looked magic to me. From there it was a roller coaster ride to kubernetes and then understanding service meshes. I immediately was drawn into the entire CNCF ecosystem. -

    -

    -After procrastinating for a while, I learnt golang one night, made a side project to feel confident in it and dove back into watching CNCF talks explaining some exciting technology in Golang code.During all this my friend and also my current mentor, Utkarsh helped me through and through. He explained to me what Meshery is and I was immediately drawn in because Meshery is a good vantage point to the entire CNCF ecosystem. Believe me, while working on meshery at one point or another you will run into almost all major projects under CNCF. -Like for any other beginner, it was all too overwhelming but exciting at the same time. Man it's such a rush when you realize that you don't know so much stuff because then there is an open window for absorbing all that stuff. I started going through docs, blogs and CNCF talks(shit that rhymed). I still binge CNCF talks. There is a plethora of good talks for you, if you are a beginner. I always prefer those over any "youtube tutorials". Anyways, back to my journey. -

    -

    -So two months ago, I found an open issue in mesheryctl. I solved the issue/enhancement, showed the code in a community meeting and got the PR merged. This was my first ever open source contribution. From there it just took off. I wrote a new command in mesheryctl then wrote unit tests. All this while trying to get an opportunity to write code for any core component like meshery server or adapters. Then one day I accidentally got into a WASM filter meeting(believe me,joined accidentally), got asked to add one feature and I said - "yes". And this is how it starts for most people. You get out of your comfort zone and say "yes", start learning new stuff, make mistakes, get corrected and the cycle continues. Fast forward two months, I was offered an internship.From what I have learnt as a person who started late is that you only need two things- "Curiosity" to ask questions out of your comfort zone and "Resilience" to absorb answers when they are thrown at you. Layer5 is an amazing community. -

    -

    -I guarantee you will not find such a warm and welcoming community so easily. If you come here for internships, you won't be here for long (or anywhere else to be honest). When your goals are solely to gain knowledge, experience while contributing to a niche, new and exciting tech- the opportunities will be waiting for you. I still have a long way to go and so much to learn. My journey with this project is certainly going to be longer than the span of this internship. -

    - \- Nithish, Ashish, Rudraksh and Bariq -
    +--- +title: "Meet the Fall Interns of 2021" +date: 2021-09-01 08:00:00 +0000 +author: Interns of Fall 2021 +thumbnail: ./fall-interns.webp +darkthumbnail: ./fall-interns.webp +category: "Community" +tags: + - Community +featured: true +published: true +--- + + + +import Nithish from "./nithish-karthik.webp"; +import Ashish from "./ashish-tiwari.webp"; +import Rudraksh from "./rudraksh-pareek.webp"; +import Bariq from "./bariq-nurlis.webp"; + + + + + + +
    +

    + Layer5 participates in many + + open source internship programs + + . We seek out existing contributors who actively reflect the culture and + principles of Layer5 to participate in these programs. Here are the Fall of 2021's + open source interns. +

    +
    + +Hear about their journeys and follow along this fall as they make waves in the Layer5 community. + +

    + + Bariq Nurlis + +

    + bariq-nurlis +
    +

    + The idea of contributing to an open source has been on the back of my mind since I enrolled in college back in 2019. Like how most people formulate what and how they will do in the uni, I also came from normalcy. In Singapore, students are aiming to get the best mark in every possible lesson in college as our grades hold a very high importance in the culture. Going back and forth between classes, planning a startup with my peers, volunteering in community clubs, I had a spectacular two years in uni. +

    +

    +However, during the last summer break, I started asking myself questions. How should I be better? What should I do? When should I do it? As I got more familiar with the Uni and all my messes (like clubs and tech-stacks that I used), I was in my comfort zone. From my experience, once you know that you’re in a comfort zone, that is exactly when you should start taking actions. Then, I found out the concept of open source. I know that I could hone my skills even further in the community, plus I could learn from the very best from all over the world. I took the initiative to join some Discord channels for open source communities and try to contribute to an open source which then somewhat went begrudgingly bad. Frankly, the experience wasn’t as good as I expected. Trying to pinch my way in a Google Summer of Code project, I am overwhelmed by numerous people trying to do the same. +

    +

    +I thought open source would be like this all the time and it failed me. But then, I took my second chance and joined Layer5. First two weeks, I tried to familiarize myself with the project and joined in the community calls. I remember sharing my screen the first time in the community call, and it was thrilling, my hands can't stop shaking. I was very excited to share my tiny bit of change in the UI which then welcomed wholeheartedly by the people inside. Overall, I met with a lot of wonderful people that don't mind extending their hands if I am in difficulty. My thoughts on open source were wrong and I realize that it's just a little badness from the overall goodness. Just like Yin Yang. Layer5 has been a supportive community that not only develops your technical side, it nurtures your thinking and reasoning. +

    + +

    + + Rudraksh Pareek + +

    + rudraksh-pareek +
    +

    +My journey with open source started when I got into college and fell into the company of some geeky open source evangelists. They were the folks from my local open source communities, OSDC and JODC. I learnt there what it means to be a good open source citizen. The fact that I could learn by contributing to a real world project albeit being a student, novice in programming, intrigued me the most and thus I had this goal clear in my mind to make an impact by working on open source software. +However, it was easier said than done. I started making small contributions to some projects that I came across but couldn't do much past that. Me being a shy kid and the lack of a welcoming community always came into my way. But this all changed when I approached Lee in the CNCF slack for a GSoC internship. I was invited to Layer5. Since day one, I could feel there was something much different about how the community is treated here. Just as I joined, I received a ton of welcome messages and resources to get started. With the course of time and some great advice I moved on from that internship. I decided to become a good contributor first. Though I started with small contributions here too, this time I was able to scale up with time with help and guidance from the community. Whenever I was assigned something, I tried to get my teeth into it as deep as I could before reaching out for help. This helped me learn a lot in a healthy way. +

    +

    + There was so much happening around and I wanted to be a part of it all. So I started attending all the meetings and was able to put my finger into many pies. I soon became better at expressing my thoughts and pretty soon, I developed an interest in CI/CD practices. Starting with small workflows, I went on to write GitHub actions for performing SMI conformance and SMP tests in CI pipelines. At the same time, I also found myself working on mesheryctl and the adapters as I came across bugs while working on the actions. Fast forward a few months and I was nominated a Meshery CI maintainer. I couldn't be much happier than this but little did I know there was more coming. +I learnt about how internships worked at Layer5 during the time I spent and agreed with it in the best sense. Generally, open source projects tend to get more welcoming and open around the months of internship program applications. However, this short span often leads to unjust outcomes. +

    +

    + Thus, I believe paying back for what you give to the project is a philosophy in the best faith of everyone in the long term. I kept my patience until I was asked to apply for an internship and I eventually got selected. I finally knew that I had started to make that impact I always wanted to. +During the course of my internship, I'll be working under the mentorship of Utkarsh Srivastava on improving Layer5 Cloud, the remote provider, and making it securely distributable and usable in "on premise environments". I'll also be collaborating with Ashish Tiwari on integrating a workflow engine with Meshery introducing best practices to be followed by management software. +Looking forward to learning and growing during this time while continuing to try my best to help others in the community. + +

    +

    +Thank you. +

    + +

    + Nithish Karthik +

    + nithish-karthik +
    +

    + I knew exactly what I wanted to do ever since my childhood, I wanted to become a programmer. Technology related stuff always intrigued me. But I had to prepare for an entrance examination IITJEE which required enormous dedication and focus to succeed. And so, I had to put my coding dreams on hold till I joined college. +

    +

    + +But after I joined college, I felt a sense of freedom within me, in the sense that I could now pursue my passion wholeheartedly. So, the next question was, "Where do I start ?". +There were a lot of buzz words going around in my college among my peers like CP, Dev, AI and ML etc. I also noticed that people were forcing themselves to do them even when they had no sense of passion or appreciation towards the field. But for me, I always had more joy in the process of doing something than the outcome I get from it. So, I started exploring various fields to find what I loved the most. And I found that I wanted to do development. + +

    +

    +So, I started working on myself. After I got the fundamentals clear, I wanted to have some practical experience to have an idea of how production grade products are being made. So, I worked on a couple of startups to get an exposure to real world development. And I learned a lot during that period. But then, I felt I needed to switch my gear. The idea of open source has always intrigued me the most but my efforts towards open source contribution has not been a success because, + +1. I always got intimidated by the size of codebase +2. I didn't have people guiding me + +Some of my seniors, who had the best interest in me, encouraged me to get into open source, but I did not take it seriously because I felt intimidated by the idea. I instead thought I would look for some open source internships that way I would have someone mentoring me and that would help me in starting my open source journey. I went through many programs but most of them were closed at that time, except, Meshery in LFX. I thought, this is the only choice I have, let's do it, I had nothing to lose. I applied for that program and as a prerequisite, I had to engage with the community. I looked at the community calendar and I saw that there was a newcomer's call that day and I attended it. I have never had such a warm welcome in any other communities. + + +

    +

    +On that day, I knew that this community is special and I should spend more time with it. I explored the projects and as usual, I felt intimidated, but this time, I had people, wonderful people to help me. I landed my first open source PR, which was a single line style change. But the encouragement and support I got from the community for that was so wonderful . I realised that this community is not just about building best quality products but also about building best quality human beings. It has been a roller coaster ride with Layer5 since then. I got so involved with the process that I had stopped caring about getting that internship. + +

    +

    + The community has really wonderful people who taught me not only about coding, but also about "How to be". I am really grateful that I found this community and I hope that everyone has a chance to experience this. +I started engaging more in the community projects, especially Meshery UI and always kept coming up with ways to improve it. +

    +

    + And fast forward to September 2021, I was told to enroll for the LFX fall term mentorship program and here I am. But, this has never been the goal for me, there is more to me and Layer5 than this internship. I will be engaged with this community as long as I can and will try to give back as much as I can. +

    +

    + Thank you +

    +

    + Ashish Tiwari +

    + ashish-tiwari +
    +

    +I started my programming career in 2020 when my classmates were bagging internships.I started late because the first two years of my college I never thought that I was a "programming guy" as I always was more of a Physics/Mathematics guy. But in 2020, when the pandemic hit I started programming from "hello world". I thought I was too late to the party and often felt overwhelmed. After 1 year of getting a taste of everything from data structures, web development, databases and everything in between that a CS undergraduate comes across; I thought to call myself a Backend dev. But I still was dissatisfied and finding something interesting when I came across the concept of containerization which looked magic to me. From there it was a roller coaster ride to kubernetes and then understanding service meshes. I immediately was drawn into the entire CNCF ecosystem. +

    +

    +After procrastinating for a while, I learnt golang one night, made a side project to feel confident in it and dove back into watching CNCF talks explaining some exciting technology in Golang code.During all this my friend and also my current mentor, Utkarsh helped me through and through. He explained to me what Meshery is and I was immediately drawn in because Meshery is a good vantage point to the entire CNCF ecosystem. Believe me, while working on meshery at one point or another you will run into almost all major projects under CNCF. +Like for any other beginner, it was all too overwhelming but exciting at the same time. Man it's such a rush when you realize that you don't know so much stuff because then there is an open window for absorbing all that stuff. I started going through docs, blogs and CNCF talks(shit that rhymed). I still binge CNCF talks. There is a plethora of good talks for you, if you are a beginner. I always prefer those over any "youtube tutorials". Anyways, back to my journey. +

    +

    +So two months ago, I found an open issue in mesheryctl. I solved the issue/enhancement, showed the code in a community meeting and got the PR merged. This was my first ever open source contribution. From there it just took off. I wrote a new command in mesheryctl then wrote unit tests. All this while trying to get an opportunity to write code for any core component like meshery server or adapters. Then one day I accidentally got into a WASM filter meeting(believe me,joined accidentally), got asked to add one feature and I said - "yes". And this is how it starts for most people. You get out of your comfort zone and say "yes", start learning new stuff, make mistakes, get corrected and the cycle continues. Fast forward two months, I was offered an internship.From what I have learnt as a person who started late is that you only need two things- "Curiosity" to ask questions out of your comfort zone and "Resilience" to absorb answers when they are thrown at you. Layer5 is an amazing community. +

    +

    +I guarantee you will not find such a warm and welcoming community so easily. If you come here for internships, you won't be here for long (or anywhere else to be honest). When your goals are solely to gain knowledge, experience while contributing to a niche, new and exciting tech- the opportunities will be waiting for you. I still have a long way to go and so much to learn. My journey with this project is certainly going to be longer than the span of this internship. +

    + \- Nithish, Ashish, Rudraksh and Bariq +
    diff --git a/src/collections/blog/2021/2021-09-20-service-mesh-specifications-and-why-they-matter/index.mdx b/src/collections/blog/2021/2021-09-20-service-mesh-specifications-and-why-they-matter/index.mdx index ac39a5a4b275..e800aefcfcb1 100644 --- a/src/collections/blog/2021/2021-09-20-service-mesh-specifications-and-why-they-matter/index.mdx +++ b/src/collections/blog/2021/2021-09-20-service-mesh-specifications-and-why-they-matter/index.mdx @@ -1,145 +1,146 @@ ---- -title: "Service Mesh Specifications and Why They Matter" -date: 2021-09-20 10:30:05 -0530 -author: Debopriya Bhattacharjee -thumbnail: ./Cover-image.webp -darkthumbnail: ./Cover-image.webp -category: "Service Mesh" -tags: - - Projects - - Service Mesh Interface - - Service Mesh Performance -published: true -resource: true -type: Blog -product: Service Mesh Performance ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import Blockquote from "../../../../reusecore/Blockquote"; - -import Hamlet from "./Hamlet.webp"; -import Graph from "./Graph1.webp"; -import Bucket from "./Graph2.webp"; -import SMI from "./SMI-demo.webp"; -import SMP from "./SMP.webp"; -import Abstractions from "./abstractions.webp"; -import Journey from "./cloud-native-journey.webp"; -import Flowchart from "./flowchart.webp"; -import { Link } from "gatsby"; - - - - -
    -

    - Lee Calcote is an innovator, product and technology leader, active in the community as a Docker Captain, Cloud Native Ambassador and GSoC, GSoD, and Community Bridge Mentor. In this talk, he walked through service mesh specifications and why they matter in your deployment. - How many service mesh specifications do you know? He went through all of them. So, no worries if you're unfamiliar. -

    -
    - -### Service Mesh Specifications: -abstractions - -As the ubiquity of service meshes unfolds and they become a commonplace for any cloud native or edge environment, so does the need for vendor and technology-agnostic interfaces to interact with them. The Service Mesh Interface (SMI), the Service Mesh Performance (SMP), and Multi-Vendor Service Mesh Interoperation (Hamlet) are three open specifications solving the challenge of interoperability, workload and performance management between service meshes. - -Learn what makes each of them unique and why they are much needed. See each of these three specifications in action as we use Meshery, the open-source service mesh management plane to demonstrate the value and functionality of each service mesh abstraction, and the adherence of these specifications by Istio, Linkerd, Consul and other popular service meshes. - -### Cloud native Journey to service meshes: - -journey-image - -The advent of cloud native was the popularization of containers. Thank you Docker! From there, containers took off like wildfire. Turns out you need an orchestrator to wrangle that sprawl. We saw a number of orchestrators come and we still have a number of orchestrators around. - -Service meshes have become a hot topic in the last few years. They still continue to be, rightfully so, a very powerful piece of technology. “A lot of the power is yet to come from my perspective. For my part, I believe that there is a tomorrow in which data plane intelligence really matters. And matters about how people write cloud native applications.”, Lee emphasized. Not everyone quite understands the capabilities of meshes as they are promoted and spoken about today. So come along into the journey of service mesh. - -There are a number of service meshes out there. One of the community projects is to track the landscape of all of the meshes there are. There’s a lot to say about each of them, their architecture, and their working. Why are they made? Who are they focused on? What do they do? When did they come about? Why are some of them not here anymore? Why are we still seeing new ones? A lot of things to go through. You might be interested in any number of the details that the landscape tracks. -
    Be Aware, It's Meshy Out There!
    - -### Service Mesh Interface -smi-image -
      -
    • Its goal and genesis were born inside of Kubernetes.
    • -
    • Being a specification that is native to Kubernetes, its focus is on lowest common denominator functionality.
    • -
    • The focus on bringing forth APIs that highlight and reinforce the most common use cases that service meshes are being used for currently
    • -
    • Leaves space and provides extensibility room for additional APIs to address other service mesh functionality as more people adopt and make use cases well known.
    • -
    • There are seven service meshes that claim compatibility with SMI. There's been a community effort, open-source effort to create service mesh conformance tests to assert whether or not a given service mesh is compatible with SMI
    • -
    • In order to facilitate those types of tests, you need to have a tool to provision a sample application on those services which will generate load and test whether traffic splitting behaves as expected or works with that service mesh implementation properly.
    • -
    • Then you need to be able to collect the results, guarantee the provenance of those results and publish them.
    • -
    • As a community, we turned to Meshery as the tool to implement SMI conformance and we have been working with the individual service meshes to validate their conformance.
    • -
    -Meshery -
      -
    • We work on an open-source project called Meshery.
    • -
    • Meshery, the cloud native management plane, is the canonical implementation of the service mesh performance.
    • -
    • The management planes can do a number of things to help bridge the divide between other back-end systems and service meshes. They also help performance management, configuration management, making sure you are following best practices in your implementations by taking common patterns and applying them to your environment
    • -
    -Let's take a moment to demo what it looks like to validate conformance in SMI using Meshery. - -graph -
      -
    • We need to spin up Meshery locally
    • -
    • We use mesheryctl as the command line interface to work with Meshery.
    • -
    • We can interact with a number of different service mesh. The service mesh we’re going to work with today is an Open service mesh (one of those 7 that is compatible with SMI). Let’s put it to the test.
    • -
    • We'll initiate SMI conformance
    • -
    • These tests go and do assertions across these different specifications. We’re looking at traffic access, traffic splitting, traffic specification. Meshery then collects these results and will eventually be publishing them in combination with the SMI project.
    • -
    - -### Service Mesh Performance -smp-image -
      -
    • Focused on describing and capturing the performance of a service mesh.
    • -
    • The overhead of the value is another way of looking at it and characterizing it.
    • -
    • Trying to characterize the performance of the infrastructure of a service mesh can be really difficult.
    • -
    • Considering the number of variables that you would have to track, how difficult it can be to have repeatable tests, and benchmark your environment, to track your history based on your environment, compare performance between other meshes people need.
    • -
    • SMP creates a standard way of capturing the performance of the mesh to help with these issues.
    • -
    • It's also the way in which you're configuring your control plan of your service mesh.
    • -
    - -You might be using a client library to do some service mesh functionality. Maybe you're using those in combination with the service mesh. What costs more? What's more efficient? What's more powerful? Maybe you're using web assembly and filters there. -These are all open questions that SMP assists in answering in your environment. You’d be surprised by some of the results of some tests that we have done and that the community has done in combination with a couple of universities and graduate students. - -Performance Test - -Demonstration of the implementation of service mesh Performance: - -flowchart -
      -
    • On the terminal, we have a local deployment of Meshery running. You can also deploy on Kubernetes as well as the vendor Kubernetes platforms like AKS, EKS and GCP or you can use a dockerized container to run Meshery. You can also have your Kubernetes on Docker desktop.
    • -
    • We have the Open service mesh deployed.
    • -
    • The Meshery UI is exposed at 9081 port. This is the UI which is used to instantiate a Load test.
    • -
    • Over here you can see we have 3 load generators fortio, wrk2, nighthawk.
    • -
    • All of these load generators have their own set of attributes which they record correctly and each of its attributes have their own significance. We begin with fortio.
    • - graph - -
    • You can actually download the test results or you can just browse into the Results Tab and see all of the tests which you have run until now.
    • -
    • Next, we used nighthawk to generate the load and benchmark the service for the same. Nighthawk is a load generator which is maintained by the Envoy community and is relatively new. It still hasn't got its 1.0 release but right now Nighthawk has sufficient features to compete with different generators which are still in the play. It can generate a gRPC service on its own and it has some more attributes which you can expose using their CLI tools.
    • -
    • You can also see that Meshery has the capability to search your environment, see what specifications are being used and what's the load on your Kubernetes.
    • -
    • Jump into the results Tab and see how we compare with these results.
    • -
    • You can click on the download. You will see that a yaml gets downloaded in which you can browse and see that the start time, load time, the performance latencies, the metrics are being captured.
    • -
    - -### Hamlet or Multi-vendor Service Mesh Interoperation -hamlet-image -
      -
    • Focus on service mesh federation
    • -
    • Specifies a set of API standards for enabling service mesh federation
    • -
    • Hamlet takes on a client-server architecture in which resources and services of one service mesh are discovered, registered and using a common format, information about them is exchanged between different service mesh.
    • -
    • Rules around authentication and authorization rules around which Services get exposed and to whom and who can communicate with them and whether or not they can do it securely. These are things that Hamlet addresses.
    • -
    • The specification currently consists of two APIs: -
        -
      • The Federated Resource Discovery API: API to authenticate and securely distribute resources between federated service meshes.
      • -
      • The Federated Service Discovery API: API to discover, reach, authenticate and securely communicate with federated services.
      • -
      -
    • -
    • Part of the real power is the ability to overcome what are likely to be separate administrative domains. The intention here is to marry up connect two disparate service mesh deployments, those deployments might be of the same type, they might be of two different types.
    • -
    - -In addition to SMI, SMP and Hamlet there has been an emergence of service mesh patterns, by which people are running and operating service meshes. There is a service mesh working group under CNCFs network that is helping identify those patterns of which there's a list right now unbeknownst to you. Reach out, join it, help us work through the 60 patterns that are defined right now. 30 of those are going into an O’Reilly book called Service Mesh Patterns. - -Something that isn’t always obvious to folks is this piece of value that people get from a service mesh and actually from the specifications that we were just mentioning. It is the fact that teams are decoupled when you’re running a mesh. Developers get to iterate a bit independently of operators, and so do operators get to make changes to implement infrastructure to the way that applications behave independent of developers in the presence of a mesh. Both of these teams are significantly empowered. Everybody gets a piece of power when they deploy a mesh. - - -_**P.S.: If these topics excite come and say "Hi" on our [Slack Channel](http://slack.layer5.io) and one of us will reach out to you!**_ - -
    +--- +title: "Service Mesh Specifications and Why They Matter" +date: 2021-09-20 10:30:05 -0530 +author: Debopriya Bhattacharjee +thumbnail: ./Cover-image.webp +darkthumbnail: ./Cover-image.webp +category: "Service Mesh" +tags: + - Projects + - Service Mesh Interface + - Service Mesh Performance +published: true +resource: true +type: Blog +product: Service Mesh Performance +--- + + + + +import Hamlet from "./Hamlet.webp"; +import Graph from "./Graph1.webp"; +import Bucket from "./Graph2.webp"; +import SMI from "./SMI-demo.webp"; +import SMP from "./SMP.webp"; +import Abstractions from "./abstractions.webp"; +import Journey from "./cloud-native-journey.webp"; +import Flowchart from "./flowchart.webp"; + + + + + +
    +

    + Lee Calcote is an innovator, product and technology leader, active in the community as a Docker Captain, Cloud Native Ambassador and GSoC, GSoD, and Community Bridge Mentor. In this talk, he walked through service mesh specifications and why they matter in your deployment. + How many service mesh specifications do you know? He went through all of them. So, no worries if you're unfamiliar. +

    +
    + +### Service Mesh Specifications: +abstractions + +As the ubiquity of service meshes unfolds and they become a commonplace for any cloud native or edge environment, so does the need for vendor and technology-agnostic interfaces to interact with them. The Service Mesh Interface (SMI), the Service Mesh Performance (SMP), and Multi-Vendor Service Mesh Interoperation (Hamlet) are three open specifications solving the challenge of interoperability, workload and performance management between service meshes. + +Learn what makes each of them unique and why they are much needed. See each of these three specifications in action as we use Meshery, the open-source service mesh management plane to demonstrate the value and functionality of each service mesh abstraction, and the adherence of these specifications by Istio, Linkerd, Consul and other popular service meshes. + +### Cloud native Journey to service meshes: + +journey-image + +The advent of cloud native was the popularization of containers. Thank you Docker! From there, containers took off like wildfire. Turns out you need an orchestrator to wrangle that sprawl. We saw a number of orchestrators come and we still have a number of orchestrators around. + +Service meshes have become a hot topic in the last few years. They still continue to be, rightfully so, a very powerful piece of technology. “A lot of the power is yet to come from my perspective. For my part, I believe that there is a tomorrow in which data plane intelligence really matters. And matters about how people write cloud native applications.”, Lee emphasized. Not everyone quite understands the capabilities of meshes as they are promoted and spoken about today. So come along into the journey of service mesh. + +There are a number of service meshes out there. One of the community projects is to track the landscape of all of the meshes there are. There’s a lot to say about each of them, their architecture, and their working. Why are they made? Who are they focused on? What do they do? When did they come about? Why are some of them not here anymore? Why are we still seeing new ones? A lot of things to go through. You might be interested in any number of the details that the landscape tracks. +
    Be Aware, It's Meshy Out There!
    + +### Service Mesh Interface +smi-image +
      +
    • Its goal and genesis were born inside of Kubernetes.
    • +
    • Being a specification that is native to Kubernetes, its focus is on lowest common denominator functionality.
    • +
    • The focus on bringing forth APIs that highlight and reinforce the most common use cases that service meshes are being used for currently
    • +
    • Leaves space and provides extensibility room for additional APIs to address other service mesh functionality as more people adopt and make use cases well known.
    • +
    • There are seven service meshes that claim compatibility with SMI. There's been a community effort, open-source effort to create service mesh conformance tests to assert whether or not a given service mesh is compatible with SMI
    • +
    • In order to facilitate those types of tests, you need to have a tool to provision a sample application on those services which will generate load and test whether traffic splitting behaves as expected or works with that service mesh implementation properly.
    • +
    • Then you need to be able to collect the results, guarantee the provenance of those results and publish them.
    • +
    • As a community, we turned to Meshery as the tool to implement SMI conformance and we have been working with the individual service meshes to validate their conformance.
    • +
    +Meshery +
      +
    • We work on an open-source project called Meshery.
    • +
    • Meshery, the cloud native management plane, is the canonical implementation of the service mesh performance.
    • +
    • The management planes can do a number of things to help bridge the divide between other back-end systems and service meshes. They also help performance management, configuration management, making sure you are following best practices in your implementations by taking common patterns and applying them to your environment
    • +
    +Let's take a moment to demo what it looks like to validate conformance in SMI using Meshery. + +graph +
      +
    • We need to spin up Meshery locally
    • +
    • We use mesheryctl as the command line interface to work with Meshery.
    • +
    • We can interact with a number of different service mesh. The service mesh we’re going to work with today is an Open service mesh (one of those 7 that is compatible with SMI). Let’s put it to the test.
    • +
    • We'll initiate SMI conformance
    • +
    • These tests go and do assertions across these different specifications. We’re looking at traffic access, traffic splitting, traffic specification. Meshery then collects these results and will eventually be publishing them in combination with the SMI project.
    • +
    + +### Service Mesh Performance +smp-image +
      +
    • Focused on describing and capturing the performance of a service mesh.
    • +
    • The overhead of the value is another way of looking at it and characterizing it.
    • +
    • Trying to characterize the performance of the infrastructure of a service mesh can be really difficult.
    • +
    • Considering the number of variables that you would have to track, how difficult it can be to have repeatable tests, and benchmark your environment, to track your history based on your environment, compare performance between other meshes people need.
    • +
    • SMP creates a standard way of capturing the performance of the mesh to help with these issues.
    • +
    • It's also the way in which you're configuring your control plan of your service mesh.
    • +
    + +You might be using a client library to do some service mesh functionality. Maybe you're using those in combination with the service mesh. What costs more? What's more efficient? What's more powerful? Maybe you're using web assembly and filters there. +These are all open questions that SMP assists in answering in your environment. You’d be surprised by some of the results of some tests that we have done and that the community has done in combination with a couple of universities and graduate students. + +Performance Test + +Demonstration of the implementation of service mesh Performance: + +flowchart +
      +
    • On the terminal, we have a local deployment of Meshery running. You can also deploy on Kubernetes as well as the vendor Kubernetes platforms like AKS, EKS and GCP or you can use a dockerized container to run Meshery. You can also have your Kubernetes on Docker desktop.
    • +
    • We have the Open service mesh deployed.
    • +
    • The Meshery UI is exposed at 9081 port. This is the UI which is used to instantiate a Load test.
    • +
    • Over here you can see we have 3 load generators fortio, wrk2, nighthawk.
    • +
    • All of these load generators have their own set of attributes which they record correctly and each of its attributes have their own significance. We begin with fortio.
    • + graph + +
    • You can actually download the test results or you can just browse into the Results Tab and see all of the tests which you have run until now.
    • +
    • Next, we used nighthawk to generate the load and benchmark the service for the same. Nighthawk is a load generator which is maintained by the Envoy community and is relatively new. It still hasn't got its 1.0 release but right now Nighthawk has sufficient features to compete with different generators which are still in the play. It can generate a gRPC service on its own and it has some more attributes which you can expose using their CLI tools.
    • +
    • You can also see that Meshery has the capability to search your environment, see what specifications are being used and what's the load on your Kubernetes.
    • +
    • Jump into the results Tab and see how we compare with these results.
    • +
    • You can click on the download. You will see that a yaml gets downloaded in which you can browse and see that the start time, load time, the performance latencies, the metrics are being captured.
    • +
    + +### Hamlet or Multi-vendor Service Mesh Interoperation +hamlet-image +
      +
    • Focus on service mesh federation
    • +
    • Specifies a set of API standards for enabling service mesh federation
    • +
    • Hamlet takes on a client-server architecture in which resources and services of one service mesh are discovered, registered and using a common format, information about them is exchanged between different service mesh.
    • +
    • Rules around authentication and authorization rules around which Services get exposed and to whom and who can communicate with them and whether or not they can do it securely. These are things that Hamlet addresses.
    • +
    • + The specification currently consists of two APIs: +
        +
      • The Federated Resource Discovery API: API to authenticate and securely distribute resources between federated service meshes.
      • +
      • The Federated Service Discovery API: API to discover, reach, authenticate and securely communicate with federated services.
      • +
      +
    • +
    • Part of the real power is the ability to overcome what are likely to be separate administrative domains. The intention here is to marry up connect two disparate service mesh deployments, those deployments might be of the same type, they might be of two different types.
    • +
    + +In addition to SMI, SMP and Hamlet there has been an emergence of service mesh patterns, by which people are running and operating service meshes. There is a service mesh working group under CNCFs network that is helping identify those patterns of which there's a list right now unbeknownst to you. Reach out, join it, help us work through the 60 patterns that are defined right now. 30 of those are going into an O’Reilly book called Service Mesh Patterns. + +Something that isn’t always obvious to folks is this piece of value that people get from a service mesh and actually from the specifications that we were just mentioning. It is the fact that teams are decoupled when you’re running a mesh. Developers get to iterate a bit independently of operators, and so do operators get to make changes to implement infrastructure to the way that applications behave independent of developers in the presence of a mesh. Both of these teams are significantly empowered. Everybody gets a piece of power when they deploy a mesh. + + +_**P.S.: If these topics excite come and say "Hi" on our [Slack Channel](http://slack.layer5.io) and one of us will reach out to you!**_ + +
    diff --git a/src/collections/blog/2021/2021-10-01-pipelining-service-mesh-specifications/index.mdx b/src/collections/blog/2021/2021-10-01-pipelining-service-mesh-specifications/index.mdx index 1307e932942c..5107ffe83c99 100644 --- a/src/collections/blog/2021/2021-10-01-pipelining-service-mesh-specifications/index.mdx +++ b/src/collections/blog/2021/2021-10-01-pipelining-service-mesh-specifications/index.mdx @@ -1,191 +1,193 @@ ---- -title: "Pipelining Service Mesh Specifications" -subtitle: "Using SMI and SMP specs on your CI/CD pipelines with Meshery's GitHub Actions" -date: 2021-11-09 10:30:05 -0530 -author: Layer5 Team -thumbnail: ./service-mesh-specifications.webp -darkthumbnail: ./service-mesh-specifications.webp -category: "Service Mesh" -tags: - - Service Mesh Interface - - Service Mesh Performance - - Meshery -published: true -resource: true -type: Blog -product: Service Mesh Performance ---- - -import { Link } from "gatsby"; -import { BlogWrapper } from "../../Blog.style.js"; -import Blockquote from "../../../../reusecore/Blockquote"; -import token from "./download-token.webp"; -import perfdashboard from "./service-mesh-performance-profile-test-results.webp" -import smidashboard from "./smi-conformance-result.webp"; -import smpLogo from "../../../../assets/images/service-mesh-performance/horizontal/smp-dark-text-side.svg"; -import smiLogo from "../../../../assets/images/service-mesh-icons/service-mesh-interface/horizontal-stackedtext/color/servicemeshinterface-horizontal-stackedtext-color.svg"; -import githubBlack from "../../../../assets/images/socialIcons/github_black.svg"; - - - -

    With growing adoption of service meshes in cloud native environments, service mesh abstractions - service mesh-neutral specifications - have emerged. Service Mesh Performance and Service Mesh Interface are two open specifications that address the need for universal interfaces for interacting with and managing any type of service mesh. Let’s examine what each specification provides.

    - -service mesh performance logo

    Service Mesh Performance standardizes service mesh value measurement, characterizing any deployment's performance by capturing the details of infrastructure capacity, service mesh configuration and workload metadata.

    - -service mesh interface logo

    Service Mesh Interface provides a standard interface for service meshes on Kubernetes. These (currently) four specfications offer a common denominator set of interfaces to support most common service mesh use cases and the flexibility to evolve to support new service mesh capabilities over time.

    - -

    As a service mesh agnostic tool that provides lifecycle and performance management of a large number of (10+) service meshes, Kubernetes applications, service mesh patterns and WebAssembly filters, Meshery is the ideal tool for the job when it comes to implementing these specifications.

    - -

    Meshery also comes with two new GitHub Actions that do exactly this. The Meshery SMI Conformance Action which validates SMI conformance in your pipeline and the Meshery SMP Action which runs SMP compatible performance benchmarks.

    -

    But how do we use these actions? What do they offer? Let’s find out!

    - -

    Service Mesh Interface Conformance GitHub Action

    - -

    Conformance of SMI specifications is defined as a series of test assertions. These test assertions are categorised by SMI specification (of which, there are currently four specifications) and comprise the complete suite of SMI conformance tests. Conformance requirements will change appropriately as each new version of the SMI spec is released. Refer to Meshery's documentation for details of how Meshery performs SMI conformance.

    - - - -

    Using Meshery's SMI Conformance GitHub Action

    - -

    The Service Mesh Interface Conformance GitHub Action is available in the GitHub Marketplace. You can configure this action to trigger with each of your releases, on every pull request. or any GitHub workflow trigger event.

    -

    An example of the action configuration which runs on every release is shown below. The action handles setting up a Kubernetes environment, deploying the service mesh (see supported service meshes), running the conformance tests and reporting back the results to the SMI Conformance dashboard in Meshery.

    - -```yaml -name: SMI Conformance with Meshery -on: - push: - tags: - - 'v*' - -jobs: - smi-conformance: - name: SMI Conformance - runs-on: ubuntu-latest - steps: - - - name: SMI conformance tests - uses: layer5io/mesheryctl-smi-conformance-action@master - with: - provider_token: ${{ secrets.MESHERY_PROVIDER_TOKEN }} - service_mesh: open_service_mesh - mesh_deployed: false -``` - -

    You can also bring in their own cluster with specific capabilities and with a service mesh already installed.

    - -```yaml -name: SMI Conformance with Meshery -on: - push: - branches: - - 'master' - -jobs: - smi-conformance: - name: SMI Conformance tests on master - runs-on: ubuntu-latest - steps: - - - name: Deploy k8s-minikube - uses: manusa/actions-setup-minikube@v2.4.1 - with: - minikube version: 'v1.21.0' - kubernetes version: 'v1.20.7' - driver: docker - - - name: Install OSM - run: | - curl -LO https://github.com/openservicemesh/osm/releases/download/v0.9.1/osm-v0.9.1-linux-amd64.tar.gz - tar -xzf osm-v0.9.1-linux-amd64.tar.gz - mkdir -p ~/osm/bin - mv ./linux-amd64/osm ~/osm/bin/osm-bin - PATH="$PATH:$HOME/osm/bin/" - osm-bin install --osm-namespace default - - - name: SMI conformance tests - uses: layer5io/mesheryctl-smi-conformance-action@master - with: - provider_token: ${{ secrets.MESHERY_PROVIDER_TOKEN }} - service_mesh: open_service_mesh - mesh_deployed: true -``` - -

    You can download a token from Meshery and add it as a GitHub secret (in the example above, the secret is MESHERY_PROVIDER_TOKEN). After the test is run, you can view the results from the Service Mesh Interface dashboard in Meshery UI.

    - -

    smi conformance dashboard
    -Meshery's Service Mesh Interface Conformance Results

    - -

    Participating service mesh projects can also automatically report their conformance test results to the SMI Conformance dashboard

    - -

    Service Mesh Performance GitHub Action

    - -

    Measuring and managing the performance of a service mesh is key to efficient operation of any service mesh. Meshery is the canonical implementation of the Service Mesh Performance specification. You can choose from multiple load generators and use a highly configurable set of load profiles with variable tunable facets to run a performance test. Meshery packages all these features into an easy-to-use GitHub Action.

    - - - -

    Using Meshery's Service Mesh Performance GitHub Action

    - -

    The Service Mesh Performance GitHub Action is available in the GitHub Marketplace.You can create your own performance profiles to run repeatable tests with Meshery. You can configure this action to trigger with each of your releases, on every pull request. or any GitHub workflow trigger event. A sample configuration of the action is shown below.

    - -```yaml -name: Meshery SMP Action -on: - push: - branches: - 'master' - -jobs: - performance-test: - name: Performance Test - runs-on: ubuntu-latest - steps: - - name: checkout - uses: actions/checkout@v2 - with: - ref: 'perf' - - - name: Deploy k8s-minikube - uses: manusa/actions-setup-minikube@v2.4.1 - with: - minikube version: 'v1.21.0' - kubernetes version: 'v1.20.7' - driver: docker - - - name: Run Performance Test - uses: layer5io/meshery-smp-action@master - with: - provider_token: ${{ secrets.PROVIDER_TOKEN }} - platform: docker - profile_name: soak-test -``` - -

    You can also define your test configuration in an SMP compatible configuration file as shown below.

    - -```yaml -smp_version: v0.0.1 -id: -name: Istio Performance Test -labels: {} -clients: -- internal: false - load_generator: fortio - protocol: 1 - connections: 2 - rps: 10 - headers: {} - cookies: {} - body: "" - content_type: "" - endpoint_urls: - - http://localhost:2323/productpage -duration: "30m" -``` - -

    See this sample GitHub workflow (action.yml) for more configuration details.

    - -performance management dashboard - -

    The results from the tests are updated on the Performance Management dashboard in Meshery. To learn more about interpreting the test results, check out this guide. You can always checkout the Meshery User Guides to dive deep into these features.

    - -Stay meshy! -
    +--- +title: "Pipelining Service Mesh Specifications" +subtitle: "Using SMI and SMP specs on your CI/CD pipelines with Meshery's GitHub Actions" +date: 2021-11-09 10:30:05 -0530 +author: Layer5 Team +thumbnail: ./service-mesh-specifications.webp +darkthumbnail: ./service-mesh-specifications.webp +category: "Service Mesh" +tags: + - Service Mesh Interface + - Service Mesh Performance + - Meshery +published: true +resource: true +type: Blog +product: Service Mesh Performance +--- + + + + +import token from "./download-token.webp"; +import perfdashboard from "./service-mesh-performance-profile-test-results.webp" +import smidashboard from "./smi-conformance-result.webp"; +import smpLogo from "../../../../assets/images/service-mesh-performance/horizontal/smp-dark-text-side.svg"; +import smiLogo from "../../../../assets/images/service-mesh-icons/service-mesh-interface/horizontal-stackedtext/color/servicemeshinterface-horizontal-stackedtext-color.svg"; +import githubBlack from "../../../../assets/images/socialIcons/github_black.svg"; + + + +

    With growing adoption of service meshes in cloud native environments, service mesh abstractions - service mesh-neutral specifications - have emerged. Service Mesh Performance and Service Mesh Interface are two open specifications that address the need for universal interfaces for interacting with and managing any type of service mesh. Let’s examine what each specification provides.

    + +service mesh performance logo

    Service Mesh Performance standardizes service mesh value measurement, characterizing any deployment's performance by capturing the details of infrastructure capacity, service mesh configuration and workload metadata.

    + +service mesh interface logo

    Service Mesh Interface provides a standard interface for service meshes on Kubernetes. These (currently) four specfications offer a common denominator set of interfaces to support most common service mesh use cases and the flexibility to evolve to support new service mesh capabilities over time.

    + +

    As a service mesh agnostic tool that provides lifecycle and performance management of a large number of (10+) service meshes, Kubernetes applications, service mesh patterns and WebAssembly filters, Meshery is the ideal tool for the job when it comes to implementing these specifications.

    + +

    Meshery also comes with two new GitHub Actions that do exactly this. The Meshery SMI Conformance Action which validates SMI conformance in your pipeline and the Meshery SMP Action which runs SMP compatible performance benchmarks.

    +

    But how do we use these actions? What do they offer? Let’s find out!

    + +

    Service Mesh Interface Conformance GitHub Action

    + +

    Conformance of SMI specifications is defined as a series of test assertions. These test assertions are categorised by SMI specification (of which, there are currently four specifications) and comprise the complete suite of SMI conformance tests. Conformance requirements will change appropriately as each new version of the SMI spec is released. Refer to Meshery's documentation for details of how Meshery performs SMI conformance.

    + + + +

    Using Meshery's SMI Conformance GitHub Action

    + +

    The Service Mesh Interface Conformance GitHub Action is available in the GitHub Marketplace. You can configure this action to trigger with each of your releases, on every pull request. or any GitHub workflow trigger event.

    +

    An example of the action configuration which runs on every release is shown below. The action handles setting up a Kubernetes environment, deploying the service mesh (see supported service meshes), running the conformance tests and reporting back the results to the SMI Conformance dashboard in Meshery.

    + +```yaml +name: SMI Conformance with Meshery +on: + push: + tags: + - 'v*' + +jobs: + smi-conformance: + name: SMI Conformance + runs-on: ubuntu-latest + steps: + + - name: SMI conformance tests + uses: layer5io/mesheryctl-smi-conformance-action@master + with: + provider_token: ${{ secrets.MESHERY_PROVIDER_TOKEN }} + service_mesh: open_service_mesh + mesh_deployed: false +``` + +

    You can also bring in their own cluster with specific capabilities and with a service mesh already installed.

    + +```yaml +name: SMI Conformance with Meshery +on: + push: + branches: + - 'master' + +jobs: + smi-conformance: + name: SMI Conformance tests on master + runs-on: ubuntu-latest + steps: + + - name: Deploy k8s-minikube + uses: manusa/actions-setup-minikube@v2.4.1 + with: + minikube version: 'v1.21.0' + kubernetes version: 'v1.20.7' + driver: docker + + - name: Install OSM + run: | + curl -LO https://github.com/openservicemesh/osm/releases/download/v0.9.1/osm-v0.9.1-linux-amd64.tar.gz + tar -xzf osm-v0.9.1-linux-amd64.tar.gz + mkdir -p ~/osm/bin + mv ./linux-amd64/osm ~/osm/bin/osm-bin + PATH="$PATH:$HOME/osm/bin/" + osm-bin install --osm-namespace default + + - name: SMI conformance tests + uses: layer5io/mesheryctl-smi-conformance-action@master + with: + provider_token: ${{ secrets.MESHERY_PROVIDER_TOKEN }} + service_mesh: open_service_mesh + mesh_deployed: true +``` + +

    You can download a token from Meshery and add it as a GitHub secret (in the example above, the secret is MESHERY_PROVIDER_TOKEN). After the test is run, you can view the results from the Service Mesh Interface dashboard in Meshery UI.

    + +

    +smi conformance dashboard
    +Meshery's Service Mesh Interface Conformance Results +

    + +

    Participating service mesh projects can also automatically report their conformance test results to the SMI Conformance dashboard

    + +

    Service Mesh Performance GitHub Action

    + +

    Measuring and managing the performance of a service mesh is key to efficient operation of any service mesh. Meshery is the canonical implementation of the Service Mesh Performance specification. You can choose from multiple load generators and use a highly configurable set of load profiles with variable tunable facets to run a performance test. Meshery packages all these features into an easy-to-use GitHub Action.

    + + + +

    Using Meshery's Service Mesh Performance GitHub Action

    + +

    The Service Mesh Performance GitHub Action is available in the GitHub Marketplace.You can create your own performance profiles to run repeatable tests with Meshery. You can configure this action to trigger with each of your releases, on every pull request. or any GitHub workflow trigger event. A sample configuration of the action is shown below.

    + +```yaml +name: Meshery SMP Action +on: + push: + branches: + 'master' + +jobs: + performance-test: + name: Performance Test + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v2 + with: + ref: 'perf' + + - name: Deploy k8s-minikube + uses: manusa/actions-setup-minikube@v2.4.1 + with: + minikube version: 'v1.21.0' + kubernetes version: 'v1.20.7' + driver: docker + + - name: Run Performance Test + uses: layer5io/meshery-smp-action@master + with: + provider_token: ${{ secrets.PROVIDER_TOKEN }} + platform: docker + profile_name: soak-test +``` + +

    You can also define your test configuration in an SMP compatible configuration file as shown below.

    + +```yaml +smp_version: v0.0.1 +id: +name: Istio Performance Test +labels: {} +clients: +- internal: false + load_generator: fortio + protocol: 1 + connections: 2 + rps: 10 + headers: {} + cookies: {} + body: "" + content_type: "" + endpoint_urls: + - http://localhost:2323/productpage +duration: "30m" +``` + +

    See this sample GitHub workflow (action.yml) for more configuration details.

    + +performance management dashboard + +

    The results from the tests are updated on the Performance Management dashboard in Meshery. To learn more about interpreting the test results, check out this guide. You can always checkout the Meshery User Guides to dive deep into these features.

    + +Stay meshy! +
    diff --git a/src/collections/blog/2021/2021-10-04-ccoss-meshery-event/index.mdx b/src/collections/blog/2021/2021-10-04-ccoss-meshery-event/index.mdx index e091d65ce816..2318a813b511 100644 --- a/src/collections/blog/2021/2021-10-04-ccoss-meshery-event/index.mdx +++ b/src/collections/blog/2021/2021-10-04-ccoss-meshery-event/index.mdx @@ -1,34 +1,34 @@ ---- -title: "Meshery Workshop at CCOSS 2021" -subtitle: "Announcing the participation of the Meshery project in CCOSS 2021 event" -date: 2021-10-04 11:10:00 +0000 -author: Rodolfo Martinez Vega -thumbnail: ./ccoss-open-source.webp -darkthumbnail: ./ccoss-open-source.webp -category: Events -tags: - - Events - - Meshery -published: true ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import { Link } from "gatsby"; -import meshery from "./meshery-logo-light-text.webp"; - - -

    October 04 to 09, 2021

    - -

    CCOSS is an Open Source Software Contributor Summit that focuses on promoting and increasing the contributions from people and organizations to Open Source in Latin America. This event will happen online from October 4th to 9th.

    - -

    Meshery will be participating as a project in a workshop where attendees will contribute to Documentation, Tests, and more. It’s a good opportunity to learn how to contribute to Open Source supported by the community. To participate you can register here.

    -

    Speakers:

    -
  • Rodolfo Martinez Vega
  • -
  • Alonso López Romo
  • - - -

    - We hope to see you at CCOSS Meshery contribution workshop 2021. Be sure to say hello - in the Layer5 Community! -

    +--- +title: "Meshery Workshop at CCOSS 2021" +subtitle: "Announcing the participation of the Meshery project in CCOSS 2021 event" +date: 2021-10-04 11:10:00 +0000 +author: Rodolfo Martinez Vega +thumbnail: ./ccoss-open-source.webp +darkthumbnail: ./ccoss-open-source.webp +category: Events +tags: + - Events + - Meshery +published: true +--- + + + +import meshery from "./meshery-logo-light-text.webp"; + + +

    October 04 to 09, 2021

    + +

    CCOSS is an Open Source Software Contributor Summit that focuses on promoting and increasing the contributions from people and organizations to Open Source in Latin America. This event will happen online from October 4th to 9th.

    + +

    Meshery will be participating as a project in a workshop where attendees will contribute to Documentation, Tests, and more. It’s a good opportunity to learn how to contribute to Open Source supported by the community. To participate you can register here.

    +

    Speakers:

    +
  • Rodolfo Martinez Vega
  • +
  • Alonso López Romo
  • + + +

    + We hope to see you at CCOSS Meshery contribution workshop 2021. Be sure to say hello + in the Layer5 Community! +

    \ No newline at end of file diff --git a/src/collections/blog/2021/2021-10-09-an-introduction-to-meshery/index.mdx b/src/collections/blog/2021/2021-10-09-an-introduction-to-meshery/index.mdx index 2e1290aef0d2..f5ebd4e8f320 100644 --- a/src/collections/blog/2021/2021-10-09-an-introduction-to-meshery/index.mdx +++ b/src/collections/blog/2021/2021-10-09-an-introduction-to-meshery/index.mdx @@ -1,393 +1,395 @@ ---- -title: "An Introduction to Meshery (Webinar-on-Demand) " -date: 2021-10-09 10:30:05 -0530 -author: Debopriya Bhattacharjee -thumbnail: ./meshery-webinar.webp -darkthumbnail: ./meshery-webinar.webp -category: "Meshery" -tags: - - Projects - - Meshery -published: true -resource: true -type: Blog -product: Meshery ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import Blockquote from "../../../../reusecore/Blockquote"; - -import MeshManager from "./mesh-manager.webp"; -import MesheryClients from "./meshery-clients.webp"; -import Mesheryfeatures from "./meshery-features.webp"; -import MesheryDeployments from "./meshery-deployment.webp"; -import Nighthawk from "./nighthawk.webp"; -import Patterns from "./patterns.webp"; -import ServiceMeshPatterns from "./service-mesh-patterns.webp"; -import Planes from "./planes.webp"; -import Mesheryoperatoricon from "../../../../assets/images/meshery-operator/meshery-operator.svg"; -import MesheryLogo from "../../../../assets/images/meshery/icon-only/meshery-logo-light.svg"; -import NighthawkIcon from "../../../../assets/images/nighthawk/icon-only/SVG/nighthawk-logo.svg"; -import PatternsLogo from "./patterns-logo.webp"; -import { Link } from "gatsby"; - - - -
    -

    - Meshery is the open-source, collaborative cloud native manager that can - configure 230+ Kuberentes infrasturcture operators different service meshes, onboard your applications, manage WebAssembly filters, apply cloud native patterns, validate against best practices, and benchmarks the performance of your cloud native deployments. Let’s learn how to manage cloud native infrastructure with confidence with Meshery.{" "} -

    -
    - -

    Network Planes

    -network-planes -

    - As we unfold what a management plane is, it would serve us well to talk about - network planes in this regard. Architecturally, a service mesh consists of two - planes. One of those is the data plane, while the other one is the control - plane. A service mesh data plane is the collection of intelligent proxies that - operate in unison under the coordination of the control plane. The control - plane performs configuration management of these intelligent proxies. -

    -

    - A management plane can do many things. Essentially, a management plane helps - you integrate service meshes into your backend systems. A robust management - plane allows you to take full advantage of the power of the network while - integrating your service delivery processes seamlessly. Your management plane - might federate different types of service meshes, help you instigate chaos - through controlled experiments, or offer automated traffic splitting in order - to execute different styles of canarying of your applications. Your management - plane might offer deep insights into the performance of your applications and - to the performance of your infrastructure or might deliver a change in - management framework. -

    - -

    - meshery-logo{" "} - Meshery -

    - -mesh-manager -

    - Meshery manages the - lifecycle of service meshes. Meshery does workload management, helps you - onboard or offboard your applications onto the mesh. It also lets you do - performance management.{" "} - MeshSync, - a custom controller within{" "} - - Meshery operator - - , performs discovery of existing service meshes and deep fingerprinting of the - specific functions that version of your service mesh is capable of performing. - Through MeshSync, Meshery supports brownfield deployments of your service meshes - (Meshery discovers your existing service mesh deployment that is already running - inside your cluster(s) whether those service meshes were deployed by Meshery or - not){" "} -

    -

    - In order to facilitate such a deep level of understanding of each type of - service mesh, Meshery has - adapters that are specific to each service mesh (given that each service mesh - has its own set of features). Consequently, in order to leverage the maximum - functionality of each service mesh, Meshery has separate, dedicated adapter - for each of the{" "} - - supported service meshes - - :{" "} -

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    Service MeshStatus
    - - Meshery Adapter for Consul - - stable
    - - Meshery Adapter for Istio - - stable
    - - Meshery Adapter for Kuma - - stable
    - - Meshery Adapter for Linkerd - {" "} - stable
    - - Meshery Adapter for Network Service Mesh - - stable
    - - Meshery Adapter for Open Service Mesh - - stable
    - - Meshery Adapter for Traefik Mesh - - stable
    - - Meshery Adapter for Citrix Service Mesh - - beta
    - - Meshery Adapter for NGINX Service Mesh - - beta
    - - Meshery Adapter for App Mesh - - alpha
    - - Meshery Adapter for Tanzu Service Mesh - - alpha
    - -

    - Meshery also lets you - integrate your Prometheus and Grafana add-ons so you can import your existing - Grafana dashboards to Meshery. When you first start Meshery, we also have a - configuration wizard, which basically walks you through the entire setup to - get Meshery up and running. By the end of this, it will make sure that you - have Meshery running on your cluster. -

    -meshery-deployment -

    - If you want a more finer configuration, you can configure your environment - through settings and you can configure service meshes, and you can configure - the metrics, you can define your performance tests to be reused. -

    -

    - For configuration management,{" "} - Meshery will analyze your - runtime environment for certain service meshes and tell you if you're doing - things right or not. What you can do is you can upload your applications - directly into Meshery, edit them in the Meshery UI itself and actually apply - these applications or onboard these applications on your service mesh. -

    - -

    - meshery-operator-logo{" "} - Meshery Operator -

    -Meshery-features -

    - - Meshery operator - {" "} - is a custom controller called MeshSync. MeshSync helps keep Meshery apprised - of the various changes that are going on to the service meshes and various - changes that are happening within Kubernetes itself. In this way Meshery - supports not only greenfield deployments like deploying service meshes itself, - it also supports connecting to existing service mesh deployments, that is, - brownfield deployment. So it will discover your existing deployments as well. -

    -

    - There's an extensible concept in Meshery called a{" "} - provider. - Providers can typically offer a layer of persistence so to the extent that - users are running performance tests intensely or to the extent that users want - to have a particular type of directory integrated to bring their own identity - to Meshery and have a multi-user experience. The other area of extensibility - is the notion that Meshery has a couple of APIs both – rest API and graphql - API. It comes with a command-line interface as well as a user interface.{" "} -

    - -

    Layer5 MeshMap

    -

    - Another capability of Meshery that is going to be released in the upcoming - version is visually configuring your service mesh using MeshMap. You can add - filters, applications as well as make other configurations visually here and - you can export it as patterns to make it reusable quite easily. It - automatically figures out the sample application we have deployed, then - generates a visual representation. It provides users the ability to design - service meshes, service mesh configuration, and the applications that run on - it. -

    - -Patterns -

    - patterns-logo{" "} - Patterns -

    -

    - {" "} - A pattern is capable of describing the deployment of any of the meshes that Meshery - supports as well as the configuration of the mesh. It also notes ongoing behavior - so if you wanted to run a canary you can describe that in a pattern. So, patterns - are like a template, they're customizable and ingestible into Meshery itself. -

    -Service-Mesh-Patterns -

    - Meshery will take action based on what you've described in the pattern, things - like generating or running a performance test, generating load, and then doing - statistical analysis on that set of results. In the future, if you want to - deploy a web assembly filter, you can describe that in a pattern as well and - have Meshery apply it. The patterns are service mesh agnostic, they're - reusable and the initial set of them is being stored in a public-facing - repository. There are almost 60 patterns that have been identified. - Ultimately, it will allow you to ingest these and measure then orchestrate and - apply them to your infrastructure. You can also use Meshery to visually - represent them and to visually design. -

    - -

    - nighthawk-logo{" "} - Nighthawk -

    -

    - There’s a project called Nighthawk that - helps advance the existing integration of nighthawk and Meshery. Nighthawk is - a load generator that is an envoy project. It's written in c plus plus and has - a couple of intriguing capabilities that are the ongoing study within - Nighthawk. There is an ongoing effort to take advantage of nighthawk’s - adaptive load controllers, add a couple of those in and expose them through - Meshery to let people recursively evaluate what is ultimately an optimal - configuration in your environment and the service mesh. -

    -Nighthawk - -

    - If you consider that you've got a certain SLO or a certain minimum latency - requirement that you need to stick to that but you also want to at the same - time maximize resiliency characteristics of your deployment, that can be a - difficult thing to figure out particularly if any of your infrastructure - changes: -

    -
      -
    • if you add another node to your environment, your clusters,
    • -
    • if you upgrade your service mesh,
    • -
    • if you change the configuration of your service mesh,
    • -
    • - if you add another service to your set of workloads that you're running. -
    • -
    -

    - If these factors change, so does the ability to run optimization routines. To - help you identify the optimal configuration of your mesh but in accordance - with your own constraints is again the study of{" "} - Nighthawk.{" "} -

    - -

    - Check out the CNCF On-Demand Webinar:{" "} - Meshery - The Cloud Native - Manager to learn more! -

    -
    - -
    - -
    +--- +title: "An Introduction to Meshery (Webinar-on-Demand) " +date: 2021-10-09 10:30:05 -0530 +author: Debopriya Bhattacharjee +thumbnail: ./meshery-webinar.webp +darkthumbnail: ./meshery-webinar.webp +category: "Meshery" +tags: + - Projects + - Meshery +published: true +resource: true +type: Blog +product: Meshery +--- + + + + +import MeshManager from "./mesh-manager.webp"; +import MesheryClients from "./meshery-clients.webp"; +import Mesheryfeatures from "./meshery-features.webp"; +import MesheryDeployments from "./meshery-deployment.webp"; +import Nighthawk from "./nighthawk.webp"; +import Patterns from "./patterns.webp"; +import ServiceMeshPatterns from "./service-mesh-patterns.webp"; +import Planes from "./planes.webp"; +import Mesheryoperatoricon from "../../../../assets/images/meshery-operator/meshery-operator.svg"; +import MesheryLogo from "../../../../assets/images/meshery/icon-only/meshery-logo-light.svg"; +import NighthawkIcon from "../../../../assets/images/nighthawk/icon-only/SVG/nighthawk-logo.svg"; +import PatternsLogo from "./patterns-logo.webp"; + + + + +
    +

    + Meshery is the open-source, collaborative cloud native manager that can + configure 230+ Kuberentes infrasturcture operators different service meshes, onboard your applications, manage WebAssembly filters, apply cloud native patterns, validate against best practices, and benchmarks the performance of your cloud native deployments. Let’s learn how to manage cloud native infrastructure with confidence with Meshery.{" "} +

    +
    + +

    Network Planes

    +network-planes +

    + As we unfold what a management plane is, it would serve us well to talk about + network planes in this regard. Architecturally, a service mesh consists of two + planes. One of those is the data plane, while the other one is the control + plane. A service mesh data plane is the collection of intelligent proxies that + operate in unison under the coordination of the control plane. The control + plane performs configuration management of these intelligent proxies. +

    +

    + A management plane can do many things. Essentially, a management plane helps + you integrate service meshes into your backend systems. A robust management + plane allows you to take full advantage of the power of the network while + integrating your service delivery processes seamlessly. Your management plane + might federate different types of service meshes, help you instigate chaos + through controlled experiments, or offer automated traffic splitting in order + to execute different styles of canarying of your applications. Your management + plane might offer deep insights into the performance of your applications and + to the performance of your infrastructure or might deliver a change in + management framework. +

    + +

    + meshery-logo{" "} + Meshery +

    + +mesh-manager +

    + Meshery manages the + lifecycle of service meshes. Meshery does workload management, helps you + onboard or offboard your applications onto the mesh. It also lets you do + performance management.{" "} + MeshSync, + a custom controller within{" "} + + Meshery operator + + , performs discovery of existing service meshes and deep fingerprinting of the + specific functions that version of your service mesh is capable of performing. + Through MeshSync, Meshery supports brownfield deployments of your service meshes + (Meshery discovers your existing service mesh deployment that is already running + inside your cluster(s) whether those service meshes were deployed by Meshery or + not){" "} +

    +

    + In order to facilitate such a deep level of understanding of each type of + service mesh, Meshery has + adapters that are specific to each service mesh (given that each service mesh + has its own set of features). Consequently, in order to leverage the maximum + functionality of each service mesh, Meshery has separate, dedicated adapter + for each of the{" "} + + supported service meshes + + :{" "} +

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Service MeshStatus
    + + Meshery Adapter for Consul + + stable
    + + Meshery Adapter for Istio + + stable
    + + Meshery Adapter for Kuma + + stable
    + + Meshery Adapter for Linkerd + +{" "} + stable
    + + Meshery Adapter for Network Service Mesh + + stable
    + + Meshery Adapter for Open Service Mesh + + stable
    + + Meshery Adapter for Traefik Mesh + + stable
    + + Meshery Adapter for Citrix Service Mesh + + beta
    + + Meshery Adapter for NGINX Service Mesh + + beta
    + + Meshery Adapter for App Mesh + + alpha
    + + Meshery Adapter for Tanzu Service Mesh + + alpha
    + +

    + Meshery also lets you + integrate your Prometheus and Grafana add-ons so you can import your existing + Grafana dashboards to Meshery. When you first start Meshery, we also have a + configuration wizard, which basically walks you through the entire setup to + get Meshery up and running. By the end of this, it will make sure that you + have Meshery running on your cluster. +

    +meshery-deployment +

    + If you want a more finer configuration, you can configure your environment + through settings and you can configure service meshes, and you can configure + the metrics, you can define your performance tests to be reused. +

    +

    + For configuration management,{" "} + Meshery will analyze your + runtime environment for certain service meshes and tell you if you're doing + things right or not. What you can do is you can upload your applications + directly into Meshery, edit them in the Meshery UI itself and actually apply + these applications or onboard these applications on your service mesh. +

    + +

    + meshery-operator-logo{" "} + Meshery Operator +

    +Meshery-features +

    + + Meshery operator + + {" "} + is a custom controller called MeshSync. MeshSync helps keep Meshery apprised + of the various changes that are going on to the service meshes and various + changes that are happening within Kubernetes itself. In this way Meshery + supports not only greenfield deployments like deploying service meshes itself, + it also supports connecting to existing service mesh deployments, that is, + brownfield deployment. So it will discover your existing deployments as well. +

    +

    + There's an extensible concept in Meshery called a{" "} + provider. + Providers can typically offer a layer of persistence so to the extent that + users are running performance tests intensely or to the extent that users want + to have a particular type of directory integrated to bring their own identity + to Meshery and have a multi-user experience. The other area of extensibility + is the notion that Meshery has a couple of APIs both – rest API and graphql + API. It comes with a command-line interface as well as a user interface.{" "} +

    + +

    Layer5 MeshMap

    +

    + Another capability of Meshery that is going to be released in the upcoming + version is visually configuring your service mesh using MeshMap. You can add + filters, applications as well as make other configurations visually here and + you can export it as patterns to make it reusable quite easily. It + automatically figures out the sample application we have deployed, then + generates a visual representation. It provides users the ability to design + service meshes, service mesh configuration, and the applications that run on + it. +

    + +Patterns +

    + patterns-logo{" "} + Patterns +

    +

    + {" "} + A pattern is capable of describing the deployment of any of the meshes that Meshery + supports as well as the configuration of the mesh. It also notes ongoing behavior + so if you wanted to run a canary you can describe that in a pattern. So, patterns + are like a template, they're customizable and ingestible into Meshery itself. +

    +Service-Mesh-Patterns +

    + Meshery will take action based on what you've described in the pattern, things + like generating or running a performance test, generating load, and then doing + statistical analysis on that set of results. In the future, if you want to + deploy a web assembly filter, you can describe that in a pattern as well and + have Meshery apply it. The patterns are service mesh agnostic, they're + reusable and the initial set of them is being stored in a public-facing + repository. There are almost 60 patterns that have been identified. + Ultimately, it will allow you to ingest these and measure then orchestrate and + apply them to your infrastructure. You can also use Meshery to visually + represent them and to visually design. +

    + +

    + nighthawk-logo{" "} + Nighthawk +

    +

    + There’s a project called Nighthawk that + helps advance the existing integration of nighthawk and Meshery. Nighthawk is + a load generator that is an envoy project. It's written in c plus plus and has + a couple of intriguing capabilities that are the ongoing study within + Nighthawk. There is an ongoing effort to take advantage of nighthawk’s + adaptive load controllers, add a couple of those in and expose them through + Meshery to let people recursively evaluate what is ultimately an optimal + configuration in your environment and the service mesh. +

    +Nighthawk + +

    + If you consider that you've got a certain SLO or a certain minimum latency + requirement that you need to stick to that but you also want to at the same + time maximize resiliency characteristics of your deployment, that can be a + difficult thing to figure out particularly if any of your infrastructure + changes: +

    +
      +
    • if you add another node to your environment, your clusters,
    • +
    • if you upgrade your service mesh,
    • +
    • if you change the configuration of your service mesh,
    • +
    • + if you add another service to your set of workloads that you're running. +
    • +
    +

    + If these factors change, so does the ability to run optimization routines. To + help you identify the optimal configuration of your mesh but in accordance + with your own constraints is again the study of{" "} + Nighthawk.{" "} +

    + +

    + Check out the CNCF On-Demand Webinar:{" "} + Meshery - The Cloud Native + Manager to learn more! +

    +
    + +
    + +
    diff --git a/src/collections/blog/2022/2022-01-05-how-to-write-unit-and-integeration-tests-for-mesheryctl/index.mdx b/src/collections/blog/2022/2022-01-05-how-to-write-unit-and-integeration-tests-for-mesheryctl/index.mdx index 8ca4ea7b4d43..bc4502475cdc 100644 --- a/src/collections/blog/2022/2022-01-05-how-to-write-unit-and-integeration-tests-for-mesheryctl/index.mdx +++ b/src/collections/blog/2022/2022-01-05-how-to-write-unit-and-integeration-tests-for-mesheryctl/index.mdx @@ -1,110 +1,109 @@ ---- -title: "How to write unit and integration tests for mesheryctl" -date: 2022-01-05 19:32:05 -0530 -author: Piyush Singariya -description: Unit and integration tests bolster and roll up into broader end-to-end, functional testing performed across Meshery and the rest of its components. -thumbnail: ./integration-test.webp -darkthumbnail: ./integration-test.webp -category: "Meshery" -tags: - - Projects - - Meshery - - mesheryctl -published: true -resource: true -type: Blog -product: Meshery ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import Blockquote from "../../../../reusecore/Blockquote"; - -import UnitTest from "./unit-test.webp"; -import IntegrationTest from "./integration-test.webp"; -import TreeGraph from "./tree-graph.webp"; - - - -
    -

    Delivering a high quality user experience is our pinnacle goal in the design of Meshery's CLI: mesheryctl. Delivering a high quality user experience means testing both qualitatively and quantatively. As a concept, quality - whether you're talking about software or anything else - can be directly measured by consistency. A quality user experience is consistent and consistency of mesheryctl is reinforced by its many unit tests.

    -
    - -

    mesheryctl is written in Golang. In the Meshery project, we use CodeCov to calculate the code coverage across mesheryctl's line of code. And there are plenty of lines of code. Achieving high percentages of code coverage in Meshery's CLI with grows in criticality as we bring more features into mesheryctl as a robust and sophisticated command line client of Meshery. Unit and integration tests bolster and roll up into broader end-to-end, functional testing performed across Meshery and the rest of its components.

    - -

    High levels of code coverage makes it easier for each project contributor to be confident that their code changes aren’t breaking any preexisting mesheryctl commands, side-swiping their functionality unknowingly, and consequently, unwittingly lowering the quality of Meshery's overall user experience. -

    - -

    mesheryctl lines of code

    - - -```yaml - - 270 text files. - 106 unique files. - 166 files ignored. - - cloc v 1.92 T=0.15 s (692.3 files/s, 110063.3 lines/s) - ------------------------------------------------------------------ - Language files blank comment code - ------------------------------------------------------------------ - Go 88 2128 1330 13045 - YAML 12 0 0 215 - JSON 4 0 0 42 - make 1 10 2 31 - Markdown 1 23 0 27 - ------------------------------------------------------------------ - SUM: 106 2161 1332 13360 - ------------------------------------------------------------------ -``` - -

    Unit Tests can be written in two ways:

    - -
      -
    1. - Test mesheryctl subcommand -
        -
      1. Mock Meshery(backend) response if needed
      2. -
      3. Grab console output
      4. -
      5. Store standard/verified mesheryctl output in a golden file(a text file)
      6. -
      7. Match the stored/expected output with what we grab from the console
      8. -
      9. Cover as many scenarios as possible, test the situations where errors must be thrown
      10. -
      11. This is a standard format, changes can be made accordingly
      12. -
      -
    2. -
    3. - Test mesheryctl functions -
        -
      1. This is the standard testing you may have come across in every project
      2. -
      3. You write one test dedicated to one function covering all possible test-cases, matching expected outputs
      4. -
      -
    4. -
    - -

    Example tree graph

    -

    This example of a tree graph (from meshery/meshery/pull/4823) shows the impact given changes make on the level of code coverage.

    - - - -

    Integration Tests

    - -

    Integrations tests come into view when you cannot mock something easily and when a given behavior is cross-functional / cross-component. Integration tests put more, but not all of the focus validating system behavior and that the system completes all the necessary actions. Take mesheryctl system start for example. This command deploys Meshery, its adapters, and Kubernetes Operator; it starts Meshery. So, you run the command to start Meshery in a GitHub workflow and after running the mesheryctl subcommand through the tests and make sure that Meshery actually started. And if the workflow successfully runs the test, then boom!, you aced your integration writing test... errr... test writing.

    - -

    The integration test writing exam can initially be challenging, but... that’s the fun in it. :) Running tests and making sure a command that is otherwise hard to verify, hard to test, and making it automatic through GH workflows.

    - -

    How you can make an impact

    - -

    Writing tests and making them work is in itself a tough task to do, so writing one test for a single function counts and makes a big difference over the long term. Don't hesitate. Start writing tests now. A single, new test is worthy of raising a pull request and will get you well on your way to learning much more about Golang, Docker, Kubernetes, and service meshes.

    - -
      -
    • Codecov is used to check code coverage in mesheryctl (login with GitHub to get an in-depth idea of lines-of-code being covered in code coverage).
    • -
    • You can check the files on CodeCov’s website to figure out which mesheryctl commands haven’t been covered by existing tests.
    • -
    • Guide: Writing tests for mesheryctl. This guide will briefly introduce how tests are supposed to be written for mesheryctl.
    • -
    • Contributing to Tests doesn’t always mean writing new tests, It also means improving the effectiveness of already written-ones.
    • -
    • Search for Issues marked with area/tests in GitHub - meshery/meshery: Meshery, the cloud native management plane.
    • -
    - -

    The impact that you make with by writing even a single test is quite high. Your tests will be executed and used time-and-time again. I can’t explain in words (I don’t have that good of a vocabulary). Your Tests are going to run in each pull request raised against the Meshery project, in each commit someone pushes to a pull request, in every nightly regression test suite, in every release. Just think: if another contributor incidently introduces a defect or doesn't consider for an edge case, and fails to uphold the intended behavior of the code, your tests are going to catch them redhanded. How cool is that?

    - -

    So, what are you waiting for? Jump in and write a few tests today! When you raise your pull request, label it with area/tests and component/mesheryctl and I'll be there to review! Let’s get mesheryctl 100% code coverage badge.

    - +--- +title: "How to write unit and integration tests for mesheryctl" +date: 2022-01-05 19:32:05 -0530 +author: Piyush Singariya +description: Unit and integration tests bolster and roll up into broader end-to-end, functional testing performed across Meshery and the rest of its components. +thumbnail: ./integration-test.webp +darkthumbnail: ./integration-test.webp +category: "Meshery" +tags: + - Projects + - Meshery + - mesheryctl +published: true +resource: true +type: Blog +product: Meshery +--- + + + + +import UnitTest from "./unit-test.webp"; +import IntegrationTest from "./integration-test.webp"; +import TreeGraph from "./tree-graph.webp"; + + + +
    +

    Delivering a high quality user experience is our pinnacle goal in the design of Meshery's CLI: mesheryctl. Delivering a high quality user experience means testing both qualitatively and quantatively. As a concept, quality - whether you're talking about software or anything else - can be directly measured by consistency. A quality user experience is consistent and consistency of mesheryctl is reinforced by its many unit tests.

    +
    + +

    mesheryctl is written in Golang. In the Meshery project, we use CodeCov to calculate the code coverage across mesheryctl's line of code. And there are plenty of lines of code. Achieving high percentages of code coverage in Meshery's CLI with grows in criticality as we bring more features into mesheryctl as a robust and sophisticated command line client of Meshery. Unit and integration tests bolster and roll up into broader end-to-end, functional testing performed across Meshery and the rest of its components.

    + +

    High levels of code coverage makes it easier for each project contributor to be confident that their code changes aren’t breaking any preexisting mesheryctl commands, side-swiping their functionality unknowingly, and consequently, unwittingly lowering the quality of Meshery's overall user experience.

    + +

    mesheryctl lines of code

    + + +```yaml + + 270 text files. + 106 unique files. + 166 files ignored. + + cloc v 1.92 T=0.15 s (692.3 files/s, 110063.3 lines/s) + ------------------------------------------------------------------ + Language files blank comment code + ------------------------------------------------------------------ + Go 88 2128 1330 13045 + YAML 12 0 0 215 + JSON 4 0 0 42 + make 1 10 2 31 + Markdown 1 23 0 27 + ------------------------------------------------------------------ + SUM: 106 2161 1332 13360 + ------------------------------------------------------------------ +``` + +

    Unit Tests can be written in two ways:

    + +
      +
    1. + Test mesheryctl subcommand +
        +
      1. Mock Meshery(backend) response if needed
      2. +
      3. Grab console output
      4. +
      5. Store standard/verified mesheryctl output in a golden file(a text file)
      6. +
      7. Match the stored/expected output with what we grab from the console
      8. +
      9. Cover as many scenarios as possible, test the situations where errors must be thrown
      10. +
      11. This is a standard format, changes can be made accordingly
      12. +
      +
    2. +
    3. + Test mesheryctl functions +
        +
      1. This is the standard testing you may have come across in every project
      2. +
      3. You write one test dedicated to one function covering all possible test-cases, matching expected outputs
      4. +
      +
    4. +
    + +

    Example tree graph

    +

    This example of a tree graph (from meshery/meshery/pull/4823) shows the impact given changes make on the level of code coverage.

    + + + +

    Integration Tests

    + +

    Integrations tests come into view when you cannot mock something easily and when a given behavior is cross-functional / cross-component. Integration tests put more, but not all of the focus validating system behavior and that the system completes all the necessary actions. Take mesheryctl system start for example. This command deploys Meshery, its adapters, and Kubernetes Operator; it starts Meshery. So, you run the command to start Meshery in a GitHub workflow and after running the mesheryctl subcommand through the tests and make sure that Meshery actually started. And if the workflow successfully runs the test, then boom!, you aced your integration writing test... errr... test writing.

    + +

    The integration test writing exam can initially be challenging, but... that’s the fun in it. :) Running tests and making sure a command that is otherwise hard to verify, hard to test, and making it automatic through GH workflows.

    + +

    How you can make an impact

    + +

    Writing tests and making them work is in itself a tough task to do, so writing one test for a single function counts and makes a big difference over the long term. Don't hesitate. Start writing tests now. A single, new test is worthy of raising a pull request and will get you well on your way to learning much more about Golang, Docker, Kubernetes, and service meshes.

    + +
      +
    • Codecov is used to check code coverage in mesheryctl (login with GitHub to get an in-depth idea of lines-of-code being covered in code coverage).
    • +
    • You can check the files on CodeCov’s website to figure out which mesheryctl commands haven’t been covered by existing tests.
    • +
    • Guide: Writing tests for mesheryctl. This guide will briefly introduce how tests are supposed to be written for mesheryctl.
    • +
    • Contributing to Tests doesn’t always mean writing new tests, It also means improving the effectiveness of already written-ones.
    • +
    • Search for Issues marked with area/tests in GitHub - meshery/meshery: Meshery, the cloud native management plane.
    • +
    + +

    The impact that you make with by writing even a single test is quite high. Your tests will be executed and used time-and-time again. I can’t explain in words (I don’t have that good of a vocabulary). Your Tests are going to run in each pull request raised against the Meshery project, in each commit someone pushes to a pull request, in every nightly regression test suite, in every release. Just think: if another contributor incidently introduces a defect or doesn't consider for an edge case, and fails to uphold the intended behavior of the code, your tests are going to catch them redhanded. How cool is that?

    + +

    So, what are you waiting for? Jump in and write a few tests today! When you raise your pull request, label it with area/tests and component/mesheryctl and I'll be there to review! Let’s get mesheryctl 100% code coverage badge.

    +
    \ No newline at end of file diff --git a/src/collections/blog/2022/2022-01-07-Recap-KubeCon-China-TAG-Network-talk/index.mdx b/src/collections/blog/2022/2022-01-07-Recap-KubeCon-China-TAG-Network-talk/index.mdx index 968fdfe1541c..322ca50535c1 100644 --- a/src/collections/blog/2022/2022-01-07-Recap-KubeCon-China-TAG-Network-talk/index.mdx +++ b/src/collections/blog/2022/2022-01-07-Recap-KubeCon-China-TAG-Network-talk/index.mdx @@ -28,7 +28,7 @@ import { Link } from "gatsby"; -
    +

    The CNCF Technical Advisory Group for Network Co-Chairs Lee Calcote and Ken Owens gave a presentation entitled Intro and Deep Dive into CNCF TAG Network and CNCF Service Mesh Working Group at KubeCon China 2021.

    @@ -91,14 +91,14 @@ The majority of the more detailed activities occur in the CNCF Service Mesh Work
  • Service Mesh Performance (SMP): SMP tries to make it uniform and succinct the way you characterize the performance of cloud native infrastructure with a focus on service meshes.
  • -SMI -SMP +SMI +SMP

    Owens and Calcote also discuss Service Mesh Patterns and Service Mesh Catalog. These patterns promote the reuse of best practices, are service mesh agnostic, and also help in behavior analysis. A circuit breaker test is a good example. If something goes wrong in your network be it a node failure, router failure, etc., then it helps you identify the point of failure as well as gets your network running quickly.

    -Service Mesh Catalog +Service Mesh Catalog

    @@ -112,12 +112,15 @@ The majority of the more detailed activities occur in the CNCF Service Mesh Work

    This brings us to Nighthawk and Meshery. Together they help produce robust, distributed and scalable services. Distributed load testing offers insight into system behaviors that accurately represent real world behaviors of services under load as that load comes from any number of sources.

    -GetNighthawk +GetNighthawk -

    Calcote and Owens packed a great deal of information in this talk. If you are passionate about Cloud Native Networking and Service Meshes, then this talk is definitely worth your time. Find the recording below. The presentation slides are available here. +

    + + Calcote and Owens packed a great deal of information in this talk. If you are passionate about Cloud Native Networking and Service Meshes, then this talk is definitely worth your time. Find the recording below. The presentation slides are available here. +

    -
    - +
    +
    diff --git a/src/collections/blog/2022/2022-01-14-open-source-journey-gaurav-chadha/index.mdx b/src/collections/blog/2022/2022-01-14-open-source-journey-gaurav-chadha/index.mdx index 93f7bb14ab52..5c4a9ddb76e1 100644 --- a/src/collections/blog/2022/2022-01-14-open-source-journey-gaurav-chadha/index.mdx +++ b/src/collections/blog/2022/2022-01-14-open-source-journey-gaurav-chadha/index.mdx @@ -1,81 +1,81 @@ ---- -title: My Open Source Journey @Layer5 -subtitle: From Contributor to SWE Intern -date: 2022-01-14 10:30:05 -0530 -author: Gaurav Chadha -thumbnail: ./Gaurav Chadha - Layer5 Intern.webp -darkthumbnail: ./Gaurav Chadha - Layer5 Intern.webp -description: "My journey as an Open Source contributor at Layer5. How I started from scratch, got involved in this community -and gained many new experiences." -type: Blog -category: Community -tags: - - Open Source - - Internship -published: true ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import Profile from "./Intern-profile.webp"; - - -

    - Hey👋, I am Gaurav Chadha, a student from New Delhi, India with lots of dreams, ambitions, and zeal to learn and grow more each and every day. -

    -

    How did it all begin?

    -

    -My journey in open source started with late-night surfing on LinkedIn. -I saw a post about the Layer5 organization and open source which drove me to their website and{" "}Slack workspace. And then, 💥 a single-click was all it took to kickstart my journey in Open Source and set in-motion a new chapter in my career development and relationships with new colleagues. -I would say this was my best ever decision in life till now. -

    -

    Getting started in the community

    -

    -Despite the warm welcome that I receive upon joining Layer5's Slack workspace, I was a bit shy to introduce myself in the{" "}#newcomers channel, but then I saw so many other folks introducing themselves. My inner voice asked, "If they can do it, why can't I?", so I went ahead and introduced myself to the community. -The best part for newcomers in Layer5 is that not only is each individual warmly welcomed, but that -Layer5 {" "} MeshMates and Community Managers host a weekly meeting (see the{" "}community calendar) dedicated to the success of newcomers, helping each person find a foothold in the community. The overview provided in each weekly Newcomers meeting gives you the leg up that you need to get started with any of{" "} Layer5's projects and orients you to the how the community works (the{" "} community handbook is an excellent resource in this regard) and who to contact in your areas of interest. -

    -

    - I highly recommend all newcomers to engage as much as possible in the community. You will gradually start seeing a change in yourself. -

    - -

    Way to my First Pull Request 🏁

    -

    -I still remember at that time I was just a beginner with Git, HTML, CSS, and JavaScript and most of the issues on the repository were going over my head. -So I started with a very beginner-friendly issue about changing a background of a component and who would have thought this changing background issue will eventually change my life in open source. -Then I made my first ever pull request in Layer5 and that got merged! -

    -

    -Try out some good first issues here{""} Layer5 {""} ,Meshery💻 -

    -

    From 1 Pull Request to 90+ Pull Requests Merged 🚀

    -

    - After my first pull request got merged I really got pumped up with joy and told myself that I can do more. This journey of learning and pull requests was not at all easy for me, it took almost 9 months of continuous dedication and effort. There are many great folks I met here in the community, who helped me and taught me new interesting concepts. - A big thanks to all of them, this was not possible without their guidance and support. -

    -

    Things I learned at Layer5

    -

    - There are a variety of things I learned at Layer5 and a lot I'm learning currently. I gained much technical knowledge as well as soft skills in these 9 months. I spend most of my time working on the UI of Meshery and its various projects. - In terms of technical items I learned React, Docker, Kubernetes, new JavaScript concepts, etc. -

    -

    - I would say Layer5 is the best in terms of work ethics, community management, a healthy work environment, and a lot more. - You can gain real-life working experience on such big projects and guidance related to your career. -

    -

    How I landed an internship at Layer5?

    -

    - I gradually started learning about the project and made myself choose one area to start with and continued to explore further. I kept pushing myself with patience until I feel strong and capable enough to - take responsibilities and give my best to the community, Then I asked and applied for an internship and eventually, I got selected. -

    -

    Now I can make more impact and grow more under the right guidance.😃

    -

    Apart from coding

    -

    - Besides coding at Layer5, I made many new friends, great experiences, and memories. -

    -

    - At last, I would say, join this amazing community and experience the change in yourself. This will open the doors for opportunities for you. Just be tenacious and push yourself, that's all that I did. -

    -

    - Thank you -

    - -
    +--- +title: My Open Source Journey @Layer5 +subtitle: From Contributor to SWE Intern +date: 2022-01-14 10:30:05 -0530 +author: Gaurav Chadha +thumbnail: ./Gaurav Chadha - Layer5 Intern.webp +darkthumbnail: ./Gaurav Chadha - Layer5 Intern.webp +description: "My journey as an Open Source contributor at Layer5. How I started from scratch, got involved in this community +and gained many new experiences." +type: Blog +category: Community +tags: + - Open Source + - Internship +published: true +--- + + +import Profile from "./Intern-profile.webp"; + + +

    + Hey👋, I am Gaurav Chadha, a student from New Delhi, India with lots of dreams, ambitions, and zeal to learn and grow more each and every day. +

    +

    How did it all begin?

    +

    +My journey in open source started with late-night surfing on LinkedIn. +I saw a post about the Layer5 organization and open source which drove me to their website and{" "}Slack workspace. And then, 💥 a single-click was all it took to kickstart my journey in Open Source and set in-motion a new chapter in my career development and relationships with new colleagues. +I would say this was my best ever decision in life till now. +

    +

    Getting started in the community

    +

    +Despite the warm welcome that I receive upon joining Layer5's Slack workspace, I was a bit shy to introduce myself in the{" "}#newcomers channel, but then I saw so many other folks introducing themselves. My inner voice asked, "If they can do it, why can't I?", so I went ahead and introduced myself to the community. +The best part for newcomers in Layer5 is that not only is each individual warmly welcomed, but that +Layer5 {" "} MeshMates and Community Managers host a weekly meeting (see the{" "}community calendar) dedicated to the success of newcomers, helping each person find a foothold in the community. The overview provided in each weekly Newcomers meeting gives you the leg up that you need to get started with any of{" "} Layer5's projects and orients you to the how the community works (the{" "} community handbook is an excellent resource in this regard) and who to contact in your areas of interest. +

    +

    + I highly recommend all newcomers to engage as much as possible in the community. You will gradually start seeing a change in yourself. +

    + +

    Way to my First Pull Request 🏁

    +

    +I still remember at that time I was just a beginner with Git, HTML, CSS, and JavaScript and most of the issues on the repository were going over my head. +So I started with a very beginner-friendly issue about changing a background of a component and who would have thought this changing background issue will eventually change my life in open source. +Then I made my first ever pull request in Layer5 and that got merged! +

    +

    +Try out some good first issues here{""} Layer5 {""} ,Meshery💻 +

    +

    From 1 Pull Request to 90+ Pull Requests Merged 🚀

    +

    + After my first pull request got merged I really got pumped up with joy and told myself that I can do more. This journey of learning and pull requests was not at all easy for me, it took almost 9 months of continuous dedication and effort. There are many great folks I met here in the community, who helped me and taught me new interesting concepts. + A big thanks to all of them, this was not possible without their guidance and support. +

    +

    Things I learned at Layer5

    +

    + There are a variety of things I learned at Layer5 and a lot I'm learning currently. I gained much technical knowledge as well as soft skills in these 9 months. I spend most of my time working on the UI of Meshery and its various projects. + In terms of technical items I learned React, Docker, Kubernetes, new JavaScript concepts, etc. +

    +

    + I would say Layer5 is the best in terms of work ethics, community management, a healthy work environment, and a lot more. + You can gain real-life working experience on such big projects and guidance related to your career. +

    +

    How I landed an internship at Layer5?

    +

    + I gradually started learning about the project and made myself choose one area to start with and continued to explore further. I kept pushing myself with patience until I feel strong and capable enough to + take responsibilities and give my best to the community, Then I asked and applied for an internship and eventually, I got selected. +

    +

    Now I can make more impact and grow more under the right guidance.😃

    +

    Apart from coding

    +

    + Besides coding at Layer5, I made many new friends, great experiences, and memories. +

    +

    + At last, I would say, join this amazing community and experience the change in yourself. This will open the doors for opportunities for you. Just be tenacious and push yourself, that's all that I did. +

    +

    + Thank you +

    + +
    diff --git a/src/collections/blog/2022/2022-01-22-the-story-of-meshery-1000-stars/index.mdx b/src/collections/blog/2022/2022-01-22-the-story-of-meshery-1000-stars/index.mdx index e7e5391866a7..807c3835ed65 100644 --- a/src/collections/blog/2022/2022-01-22-the-story-of-meshery-1000-stars/index.mdx +++ b/src/collections/blog/2022/2022-01-22-the-story-of-meshery-1000-stars/index.mdx @@ -1,159 +1,160 @@ ---- -title: "The Story of Meshery's 1,000 Stars" -subtitle: "A story about growing together as a community and building a project that matters" -date: 2022-01-26 10:30:05 -0530 -author: Debopriya Bhattacharjee -thumbnail: ./Meshery-Stars-cover.webp -darkthumbnail: ./Meshery-Stars-cover.webp -category: "Announcements" -description: "Meshery has achieved yet another milestone! Our GitHub repository has surpassed a 1,000 stars." -tags: - - Meshery -type: Blog -published: true -featured: true ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import Blockquote from "../../../../reusecore/Blockquote"; -import BlockquoteAlt from "../../../../reusecore/Blockquote/Blockquote-alt-style"; -import { Link } from "gatsby"; -import Stars from "./stars-forks.webp"; -import Slack from "./meshery-star-notifications.webp"; - - -

    - Meshery took its first steps into the cloud native world in July of 2019 with the goal to ease the adoption and operation of cloud native infrastructure with a focus on service meshes as ubiquitous a layer within and outside of Kubernetes deployments. Since then, Meshery as a project and Layer5 as an open source community have Slack notification of GitHub stars applied to Meshery and Service Mesh Performance grown by leaps and bounds. Now, we are bursting with pride in announcing that Meshery has reached yet another milestone: 1,000 stars on the Meshery repository on GitHub. -

    - -

    - As a project, Meshery is comprised of about 30 repositories, and so, in total, - the project has many more than a thousand stars. The rate by which Meshery is - accumulating stars only continues to accelerate and is a small moment of pride - recognized in the community Slack each time a star is added. As we hit the - 1,000+ stars milestone, let's pause to reflect on the project's incredible - journey since its inception. -

    - -

    Why was Meshery created?

    - -

    - Meshery is an open source, vendor-neutral, extensible management plane that - enables service mesh users to overcome the challenges of complex virtual - networking,{" "} -

    {" "} - empowers them to design and apply patterns containing tried and true best - practices, and enables developers, operators, and product managers to - understand and manage their cloud native services with confidence. Meshery is - the only openly-governed service mesh manager. Given its ability to deeply - manage Kubernetes, its workloads, and any service mesh, and the highly - configurable way in which users can load a variety of plugins, the project has - certainly earned its title as the extensible service mesh manager. -

    - -
    -

    - Within just a year of its creation,{" "} - - Meshery lands in the CNCF Landscape - - . -

    -
    -
    -

    - Not long after, Meshery was{" "} - - adopted by the CNCF - {" "} - in October 2021. With its natural step into the Cloud Native Computing - Foundation, the contributor community and Meshery's functionality maintains - steadfast in their rate of growth and use. With continuous improvements in the - architecture, user experience and in other features regulated by inclusive - monitoring, the project is gaining traction very quickly. -

    - -

    Engagement in the community is on the rise!

    -

    - It isn't just the number of stars that has grown. We've seen a surge of new - contributors, maintainers, new features, commits, PRs, releases, and so much - more! How do we assess the impact of Meshery? Here are some statistics on how - we track our engagement: -

    - -
      -
    • - Stargazers: 105.4795% annual growth from 584 to 1200 -
    • -
    • - Forks: 103.2491% annual growth from 277 to 563 -
    • -
    • - Code Commits: 250% annual growth from 3.25k to 11.375k -
    • -
    • In the last 12 months, we had 341 contributors with 291 new.
    • -
    • - Number of PR's merged in the last 12 months is 2108. Our count of PR’s - merged is more than that of 106 CNCF hosted projects. -
    • -
    - -Meshery Stars and Forks Graph -

    - Note: These metrics and reports were obtained from DevStats, a CNCF-created - tool for analyzing and graphing developer contributions. -

    - -
    - -

    Latest Meshery Features

    -

    - Meshery v0.6.0 will release soon, jam-packed full of major new features. Final - release candidate, Meshery v0.6.0-rc-4, available today, so you can take - advantage of Meshery's new functionality now: -

    - -
      -
    • Manage Kubernetes Workloads (Applications)
    • -
    • Manage WASM filters
    • -
    • - Manage{" "} - - Service Mesh Patterns - -
    • -
    • - MeshMap: Visualize - service mesh deployments -
    • -
    • - Enhanced service mesh discovery in{" "} - - Meshery Operator and Meshsync - -
    • -
    - -

    - Last, but not least is the announcement of MeshMap's beta release! The waiting - list is filling up fast, so I recommend{" "} - signing up for access now! -

    - - +--- +title: "The Story of Meshery's 1,000 Stars" +subtitle: "A story about growing together as a community and building a project that matters" +date: 2022-01-26 10:30:05 -0530 +author: Debopriya Bhattacharjee +thumbnail: ./Meshery-Stars-cover.webp +darkthumbnail: ./Meshery-Stars-cover.webp +category: "Announcements" +description: "Meshery has achieved yet another milestone! Our GitHub repository has surpassed a 1,000 stars." +tags: + - Meshery +type: Blog +published: true +featured: true +--- + + + + + +import Stars from "./stars-forks.webp"; +import Slack from "./meshery-star-notifications.webp"; + + +

    + Meshery took its first steps into the cloud native world in July of 2019 with the goal to ease the adoption and operation of cloud native infrastructure with a focus on service meshes as ubiquitous a layer within and outside of Kubernetes deployments. Since then, Meshery as a project and Layer5 as an open source community have Slack notification of GitHub stars applied to Meshery and Service Mesh Performance grown by leaps and bounds. Now, we are bursting with pride in announcing that Meshery has reached yet another milestone: 1,000 stars on the Meshery repository on GitHub. +

    + +

    + As a project, Meshery is comprised of about 30 repositories, and so, in total, + the project has many more than a thousand stars. The rate by which Meshery is + accumulating stars only continues to accelerate and is a small moment of pride + recognized in the community Slack each time a star is added. As we hit the + 1,000+ stars milestone, let's pause to reflect on the project's incredible + journey since its inception. +

    + +

    Why was Meshery created?

    + +

    + Meshery is an open source, vendor-neutral, extensible management plane that + enables service mesh users to overcome the challenges of complex virtual + networking,{" "} +

    {" "} + empowers them to design and apply patterns containing tried and true best + practices, and enables developers, operators, and product managers to + understand and manage their cloud native services with confidence. Meshery is + the only openly-governed service mesh manager. Given its ability to deeply + manage Kubernetes, its workloads, and any service mesh, and the highly + configurable way in which users can load a variety of plugins, the project has + certainly earned its title as the extensible service mesh manager. +

    + +
    +

    + Within just a year of its creation,{" "} + + Meshery lands in the CNCF Landscape + + . +

    +
    +
    +

    + Not long after, Meshery was{" "} + + adopted by the CNCF + + {" "} + in October 2021. With its natural step into the Cloud Native Computing + Foundation, the contributor community and Meshery's functionality maintains + steadfast in their rate of growth and use. With continuous improvements in the + architecture, user experience and in other features regulated by inclusive + monitoring, the project is gaining traction very quickly. +

    + +

    Engagement in the community is on the rise!

    +

    + It isn't just the number of stars that has grown. We've seen a surge of new + contributors, maintainers, new features, commits, PRs, releases, and so much + more! How do we assess the impact of Meshery? Here are some statistics on how + we track our engagement: +

    + +
      +
    • + Stargazers: 105.4795% annual growth from 584 to 1200 +
    • +
    • + Forks: 103.2491% annual growth from 277 to 563 +
    • +
    • + Code Commits: 250% annual growth from 3.25k to 11.375k +
    • +
    • In the last 12 months, we had 341 contributors with 291 new.
    • +
    • + Number of PR's merged in the last 12 months is 2108. Our count of PR’s + merged is more than that of 106 CNCF hosted projects. +
    • +
    + +Meshery Stars and Forks Graph +

    + Note: These metrics and reports were obtained from DevStats, a CNCF-created + tool for analyzing and graphing developer contributions. +

    + +
    + +

    Latest Meshery Features

    +

    + Meshery v0.6.0 will release soon, jam-packed full of major new features. Final + release candidate, Meshery v0.6.0-rc-4, available today, so you can take + advantage of Meshery's new functionality now: +

    + +
      +
    • Manage Kubernetes Workloads (Applications)
    • +
    • Manage WASM filters
    • +
    • + Manage{" "} + + Service Mesh Patterns + +
    • +
    • + MeshMap: Visualize + service mesh deployments +
    • +
    • + Enhanced service mesh discovery in{" "} + + Meshery Operator and Meshsync + +
    • +
    + +

    + Last, but not least is the announcement of MeshMap's beta release! The waiting + list is filling up fast, so I recommend{" "} + signing up for access now! +

    + + diff --git a/src/collections/blog/2022/2022-02-25-layer5-collab-with-openforce/index.mdx b/src/collections/blog/2022/2022-02-25-layer5-collab-with-openforce/index.mdx index 2b7a682d53f0..ce7496ba56b5 100644 --- a/src/collections/blog/2022/2022-02-25-layer5-collab-with-openforce/index.mdx +++ b/src/collections/blog/2022/2022-02-25-layer5-collab-with-openforce/index.mdx @@ -1,40 +1,40 @@ ---- -title: "Layer5 collaboration with OpenForce 2022" -date: 2022-02-25 -author: Shebeul Inyang -thumbnail: ./thumbnail.webp -darkthumbnail: ./thumbnail.webp -category: "Community" -tags: - - Community - - Events - - Open Source -published: true ---- -import { BlogWrapper } from "../../Blog.style.js"; -import Profile from "./thumbnail.webp"; - - -profile-img - -

    Layer5 collaboration with OpenForce 2022

    -

    -Great News!🎉🎉 -OpenForce2022 by CodeFlow is here! And Layer5 is joining forces with other open source organizations to make it an unforgettable experience. -OpenForce 2022 is a place where contributors can meet mentors from open source organizations and contribute to projects under guidance, network with project maintainers, and “bring the open source culture” with great enthusiasm. -

    -

    What Layer5 will do?

    -

    -During the program, Layer5 as an open source organization will provide OpenForce specific issues which participants can resolve during the contribution period. In addition, there will be a panel of mentors assigned to assist contributors to overcome any challenges they might face. -Beyond the direct support offered by Layer5 mentors, program participants will have an amazing networking opportunity to connect with the broader set of community members at Layer5. This event will kick-off virtually from March 3rd to March 28th, 2022. -

    -

    CodeFlow

    -

    -The program is organized by CodeFlow, an organization whose main motive is to empower the student community by organizing webinars, hackathons, and open source events, providing them with the best learning environment and helping them gain the principal knowledge about the fast-paced, open source ecosystem. What a great learning opportunity this would prove to be as ‘open source meets its contributor force’ at OpenForce 2022! Come be a part of this amazing initiative. -

    -

    -Layer5 is an amazing and welcoming community. -

    - -
    - +--- +title: "Layer5 collaboration with OpenForce 2022" +date: 2022-02-25 +author: Shebeul Inyang +thumbnail: ./thumbnail.webp +darkthumbnail: ./thumbnail.webp +category: "Community" +tags: + - Community + - Events + - Open Source +published: true +--- + +import Profile from "./thumbnail.webp"; + + +profile-img + +

    Layer5 collaboration with OpenForce 2022

    +

    +Great News!🎉🎉 +OpenForce2022 by CodeFlow is here! And Layer5 is joining forces with other open source organizations to make it an unforgettable experience. +OpenForce 2022 is a place where contributors can meet mentors from open source organizations and contribute to projects under guidance, network with project maintainers, and “bring the open source culture” with great enthusiasm. +

    +

    What Layer5 will do?

    +

    +During the program, Layer5 as an open source organization will provide OpenForce specific issues which participants can resolve during the contribution period. In addition, there will be a panel of mentors assigned to assist contributors to overcome any challenges they might face. +Beyond the direct support offered by Layer5 mentors, program participants will have an amazing networking opportunity to connect with the broader set of community members at Layer5. This event will kick-off virtually from March 3rd to March 28th, 2022. +

    +

    CodeFlow

    +

    +The program is organized by CodeFlow, an organization whose main motive is to empower the student community by organizing webinars, hackathons, and open source events, providing them with the best learning environment and helping them gain the principal knowledge about the fast-paced, open source ecosystem. What a great learning opportunity this would prove to be as ‘open source meets its contributor force’ at OpenForce 2022! Come be a part of this amazing initiative. +

    +

    +Layer5 is an amazing and welcoming community. +

    + +
    + diff --git a/src/collections/blog/2022/2022-04-01-she-code-africa-contributhon/index.mdx b/src/collections/blog/2022/2022-04-01-she-code-africa-contributhon/index.mdx index 59b9dc96b0cf..08c9da3bebad 100644 --- a/src/collections/blog/2022/2022-04-01-she-code-africa-contributhon/index.mdx +++ b/src/collections/blog/2022/2022-04-01-she-code-africa-contributhon/index.mdx @@ -1,54 +1,54 @@ ---- -title: "Layer5 participates in She Code Africa's Contributhon Program 2022" -date: 2022-04-01 21:00:00 +0000 -author: Shebuel Inyang -thumbnail: ./layer5-contributhon-banner.webp -darkthumbnail: ./layer5-contributhon-banner.webp -category: Community -tags: - - Community - - Events - - MeshMate -published: true ---- - -import { Link } from "gatsby"; - - -import { BlogWrapper } from "../../Blog.style.js"; - - - -

    - The Contributhon Program is organized by She Code Africa, a non-profit organization focused on celebrating and empowering young Girls and Women in Technology across Africa. They provide support through diverse offline and online communities, resources, mentorship, and organize amazing programs and initiatives to always keep members or participants engaged. -

    - -

    - The Contributhon Program is a virtual open-source Bootcamp focused on building more women open-source contributors & creating more diversity in the African open source ecosystem. During this Bootcamp, participants work with an open-source organization on a project for the period of 8 weeks with the help of organization mentors. -

    - -

    - At the end of the Bootcamp, participants get rewarded a stipend of $500 upon successful project completion. -

    - -

    - Layer5 is participating as a mentoring organization and will be working directly with the program participants during the Bootcamp to help ensure that the project is completed successfully. -

    - -

    - At Layer5 we use Layer5 Community Forum for discussions in the community, this platform is active and it is easy to miss out on questions answered or important information. For this project, we want to create a leaderboard to show the most active participants based on helpful answers, questions asked, and more. -

    - -

    - Our selected mentors, Ekene Leonard Nwobodo, Yash Kamboj, Etiene James, Raj Gaurav Maurya and Kunal Verma who are trusted, capable, and qualified will guide participants Oyindamola Dawodu and Ednah Akoth throughout the duration of this Bootcamp, help them become a part of the community, teach them how to stay motivated and productive, show them how to solve technical problems, and also give constructive feedback as they keep track of the participants progress -

    - -

    - The She Code Africa hosts their Contributhon as an Africa-wide open source boot camp focused on building more women OSS contributors & creating more diversity in the African open source ecosystem by matching African women in technology with sponsors and mentors from Open Source organizations. During this boot camp, participants work with an open source organisation on a project for 4 weeks with the help of organisation mentors and get rewarded at the end of the boot camp upon successful project completion. -

    - -

    - This program kicks off virtually from April 1, 2022, to May 28, 2022. -

    - -
    +--- +title: "Layer5 participates in She Code Africa's Contributhon Program 2022" +date: 2022-04-01 21:00:00 +0000 +author: Shebuel Inyang +thumbnail: ./layer5-contributhon-banner.webp +darkthumbnail: ./layer5-contributhon-banner.webp +category: Community +tags: + - Community + - Events + - MeshMate +published: true +--- + + + + + + + + +

    + The Contributhon Program is organized by She Code Africa, a non-profit organization focused on celebrating and empowering young Girls and Women in Technology across Africa. They provide support through diverse offline and online communities, resources, mentorship, and organize amazing programs and initiatives to always keep members or participants engaged. +

    + +

    + The Contributhon Program is a virtual open-source Bootcamp focused on building more women open-source contributors & creating more diversity in the African open source ecosystem. During this Bootcamp, participants work with an open-source organization on a project for the period of 8 weeks with the help of organization mentors. +

    + +

    + At the end of the Bootcamp, participants get rewarded a stipend of $500 upon successful project completion. +

    + +

    + Layer5 is participating as a mentoring organization and will be working directly with the program participants during the Bootcamp to help ensure that the project is completed successfully. +

    + +

    + At Layer5 we use Layer5 Community Forum for discussions in the community, this platform is active and it is easy to miss out on questions answered or important information. For this project, we want to create a leaderboard to show the most active participants based on helpful answers, questions asked, and more. +

    + +

    + Our selected mentors, Ekene Leonard Nwobodo, Yash Kamboj, Etiene James, Raj Gaurav Maurya and Kunal Verma who are trusted, capable, and qualified will guide participants Oyindamola Dawodu and Ednah Akoth throughout the duration of this Bootcamp, help them become a part of the community, teach them how to stay motivated and productive, show them how to solve technical problems, and also give constructive feedback as they keep track of the participants progress +

    + +

    + The She Code Africa hosts their Contributhon as an Africa-wide open source boot camp focused on building more women OSS contributors & creating more diversity in the African open source ecosystem by matching African women in technology with sponsors and mentors from Open Source organizations. During this boot camp, participants work with an open source organisation on a project for 4 weeks with the help of organisation mentors and get rewarded at the end of the boot camp upon successful project completion. +

    + +

    + This program kicks off virtually from April 1, 2022, to May 28, 2022. +

    + +
    diff --git a/src/collections/blog/2022/2022-05-10-dockercon-22-hashicorp-talk/index.mdx b/src/collections/blog/2022/2022-05-10-dockercon-22-hashicorp-talk/index.mdx index c49344c466e1..49f0f2898641 100644 --- a/src/collections/blog/2022/2022-05-10-dockercon-22-hashicorp-talk/index.mdx +++ b/src/collections/blog/2022/2022-05-10-dockercon-22-hashicorp-talk/index.mdx @@ -21,15 +21,15 @@ import { BlogWrapper } from "../../Blog.style.js"; import Blockquote from "../../../../reusecore/Blockquote"; import slidesTAG from "../../../events/2021/kubecon-china-2021/cncf-tag-network-and-service-mesh-working-group-kubecon-china-2021-lee-calcote-ken-owens.pdf"; import { Link } from "gatsby"; -import DDE from './docker-extension-meshery.webp'; -import developer from './developers-need.webp'; -import dashboard from './dashboard.webp'; -import designer from './designer-1.webp'; -import visualizer from './viz-1.webp'; +import DDE from "./docker-extension-meshery.webp"; +import developer from "./developers-need.webp"; +import dashboard from "./dashboard.webp"; +import designer from "./designer-1.webp"; +import visualizer from "./viz-1.webp"; -
    +

    Lee Calcote and Nic Jackson gave a presentation entitled Extending the Docker Compose Experience to Service Mesh at DockerCon 2022.

    @@ -111,13 +111,17 @@ MeshMap is the world's only visual designer for Kubernetes and all cloud native These Docker Extensions are so powerful that it allows you to do multiple tasks without leaving Docker Desktop.

    -
    - +
    +

    -Lee Calcote and Nic Jackson packed a great deal of information in this talk. Find the recording below. The Meshery Extension is now out! Try now, and Share your Experience -Apply for MeshMap Beta Program + + Lee Calcote and Nic Jackson packed a great deal of information in this talk. Find the recording below. The Meshery Extension is now out! Try now, and Share your Experience + + + Apply for MeshMap Beta Program +

    diff --git a/src/collections/blog/2022/2022-05-10-dockercon-22-hpe-talk/index.mdx b/src/collections/blog/2022/2022-05-10-dockercon-22-hpe-talk/index.mdx index 05363de9f1f2..e78b67f4aabe 100644 --- a/src/collections/blog/2022/2022-05-10-dockercon-22-hpe-talk/index.mdx +++ b/src/collections/blog/2022/2022-05-10-dockercon-22-hpe-talk/index.mdx @@ -1,131 +1,125 @@ ---- -title: "Extending Docker with Meshery, SPIRE, and Istio" -date: 2022-05-10 10:30:05 -0530 -author: Gaurav Chadha -thumbnail: ./dc22-hpe-talk.webp -darkthumbnail: ./dc22-hpe-talk.webp -description: "DockerCon 2022 talk with HPE and Meshery Docker Extension Demo" -category: "Docker" -tags: - - Docker - - Meshery -published: true -resource: true -type: Blog -technology: Docker -product: Docker Extension -featured: true ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import Blockquote from "../../../../reusecore/Blockquote"; -import { Link } from "gatsby"; -import CloudNative from './cloud-native-management.webp'; -import CloudNativeIdentity from './cloud-native-identity.webp'; -import dde from './dde.webp'; -import designer from './Designer.webp'; -import visualizer from './Visualizer.webp'; -import meshmapInDocker from './meshmap-docker-extension-for-meshery.webp'; - - - -
    -

    - Lee Calcote and Maximiliano Churichi gave a presentation entitled Extending Docker with Meshery, SPIRE, and Istio at DockerCon 2022. -

    -
    - -

    - Lee Calcote is an innovative product and technology leader, passionate about empowering engineers and enabling organizations. As the founder and CEO of Layer5, he is at the forefront of the cloud native movement. -

    - -

    - Maximiliano Churichi is a Software Engineer at Hewlett Packard Enterprise, working in the Security Engineering team, and fully engaged in open source technologies, passionate about service mesh and cloud-native security. -

    - -
    -

    - Cloud Native Management - Meshery Docker Extension -

    -

    - Lee Calcote introduces Meshery as a Cloud Native Management Plane, stating, "Meshery does Lifecycle and Performance Management of 10 different service meshes more than that it helps with configuration management with Kubernetes and with the Meshery Docker Extension it does same for the Docker Compose application." -

    -
    - -

    - "As a Docker Captain, Lee have always been a proponent of Docker, and in particular its enablement of developer workflows", "Now, Docker Extensions bring an integrated experience with ecosystem tooling, like Meshery - a critical tool for developers, who are configuring and managing cloud native applications." -

    - -
    -

    - Cloud Native Identity -

    -

    - Maximiliano Churichi briefly explains about Cloud Native Identity and HPE's open source Project Mithril, "SPIFFE (Secure Production Identity Framework For Everyone) is a CNCF-incubated project that defines a set of standards for identifying and securing communications between application services. The SPIRE project (another CNCF project), the SPIFFE Runtime Environment, is a production-ready reference implementation of the SPIFFE principles, and additionally it also implements a set of APIs for controlling attestation policies, and coordinate certificate issuance and rotation." -

    - Meshery Docker Extension -

    - Maximiliano also tells how HPE's Project Mithril integrates SPIRE and Istio to strengthen service identity in the data plane. Project Mithril leverages the service management capabilities of Istio and the strong identity by attestation principles of SPIFFE and SPIRE to deliver robust and flexible attestation beyond Kubernetes namespaces and service accounts, and provide end-to-end secure attestation of workloads based on zero trust principles regardless of the location of such workloads. The improvements introduced by Project Mithril were already upstreamed into Istio, and are expected to be released in the upcoming Istio 1.14. Starting from this release, Istio users will be able to leverage SPIRE for SPIFFE identities management, and stronger identity attestation mechanisms. -

    -
    - -

    -

    How "Docker Extension for Meshery" helps to deploy with the click of a button?

    -

    - Meshery Extension Meshery - The new Meshery Docker Extension brings Layer5 MeshMap, the world's only visual designer for Kubernetes and service mesh deployments, to the desktop of millions of developers. Developers and operators alike can visually configure and operate their cloud native infrastructure and applications using MeshMap's low code visual designer. -

    -

    -

    - Maximiliano Churichi, Software Engineer at HPE says how conveniently Meshery integrates different services into Docker. -

    -
      -
    • Kubernetes and service mesh support for your Docker Compose apps - Import your Docker Compose apps. Configure and deploy them to Kubernetes and any service mesh.
    • - -
    • Visual design of Kubernetes applications - Using MeshMap as a visual topology for designing Docker Compose applications, operating Kubernetes, all Kubernetes operators, workloads, and custom resources.
    • - -
    • Single-click deployment of your infrastructure - Support of 250+ different Kubernetes operators and 60+ cloud services at the fingertips of developers in connection with Docker Desktop’s ability to deliver Kubernetes locally.
    • - -
    • Detection of Kubernetes environments - Scan your kubeconfigs and select your current Kubernetes environment. Switch from one environment to another or manage all clusters concurrently.
    • -
    - -

    -

    Maximiliano demonstrates MeshMap

    -

    - -Layer5 MeshMap in Meshery Docker Extension - -
    -
    -

    -

    Designer Mode
    - Design a service mesh deployment with application and Envoy filter from scratch. Customize a service mesh deployment with application and Envoy filter from pattern. -

    - Meshery Docker Extension - -
    -
    -

    -

    Visualizer Mode
    - Examine a visual topology of Kubernetes cluster and its services. View and search log streams from your pod's containers. Connect an interactive terminal to instances of your containers. -

    - Meshery Docker Extension -
    -
    - - -
    - -
    - -

    Lee Calcote and Maximiliano Churichi packed a great deal of information in this talk. Find the recording below. The Meshery Extension is now out! Try now, and Share your Experience -Apply for MeshMap Beta Program -

    - - +--- +title: "Extending Docker with Meshery, SPIRE, and Istio" +date: 2022-05-10 10:30:05 -0530 +author: Gaurav Chadha +thumbnail: ./dc22-hpe-talk.webp +darkthumbnail: ./dc22-hpe-talk.webp +description: "DockerCon 2022 talk with HPE and Meshery Docker Extension Demo" +category: "Docker" +tags: + - Docker + - Meshery +published: true +resource: true +type: Blog +technology: Docker +product: Docker Extension +featured: true +--- + + + + +import CloudNative from "./cloud-native-management.webp"; +import CloudNativeIdentity from "./cloud-native-identity.webp"; +import dde from "./dde.webp"; +import designer from "./Designer.webp"; +import visualizer from "./Visualizer.webp"; +import meshmapInDocker from "./meshmap-docker-extension-for-meshery.webp"; + + + +
    +

    + Lee Calcote and Maximiliano Churichi gave a presentation entitled Extending Docker with Meshery, SPIRE, and Istio at DockerCon 2022. +

    +
    + +

    + Lee Calcote is an innovative product and technology leader, passionate about empowering engineers and enabling organizations. As the founder and CEO of Layer5, he is at the forefront of the cloud native movement. +

    + +

    + Maximiliano Churichi is a Software Engineer at Hewlett Packard Enterprise, working in the Security Engineering team, and fully engaged in open source technologies, passionate about service mesh and cloud-native security. +

    + +
    +

    + Cloud Native Management + Meshery Docker Extension +

    +

    + Lee Calcote introduces Meshery as a Cloud Native Management Plane, stating, "Meshery does Lifecycle and Performance Management of 10 different service meshes more than that it helps with configuration management with Kubernetes and with the Meshery Docker Extension it does same for the Docker Compose application." +

    +
    + +

    + "As a Docker Captain, Lee have always been a proponent of Docker, and in particular its enablement of developer workflows", "Now, Docker Extensions bring an integrated experience with ecosystem tooling, like Meshery - a critical tool for developers, who are configuring and managing cloud native applications." +

    + +
    +

    + Cloud Native Identity +

    +

    + Maximiliano Churichi briefly explains about Cloud Native Identity and HPE's open source Project Mithril, "SPIFFE (Secure Production Identity Framework For Everyone) is a CNCF-incubated project that defines a set of standards for identifying and securing communications between application services. The SPIRE project (another CNCF project), the SPIFFE Runtime Environment, is a production-ready reference implementation of the SPIFFE principles, and additionally it also implements a set of APIs for controlling attestation policies, and coordinate certificate issuance and rotation." +

    + Meshery Docker Extension +

    + Maximiliano also tells how HPE's Project Mithril integrates SPIRE and Istio to strengthen service identity in the data plane. Project Mithril leverages the service management capabilities of Istio and the strong identity by attestation principles of SPIFFE and SPIRE to deliver robust and flexible attestation beyond Kubernetes namespaces and service accounts, and provide end-to-end secure attestation of workloads based on zero trust principles regardless of the location of such workloads. The improvements introduced by Project Mithril were already upstreamed into Istio, and are expected to be released in the upcoming Istio 1.14. Starting from this release, Istio users will be able to leverage SPIRE for SPIFFE identities management, and stronger identity attestation mechanisms. +

    +
    + +

    +

    How "Docker Extension for Meshery" helps to deploy with the click of a button?

    +

    + Meshery Extension Meshery + The new Meshery Docker Extension brings Layer5 MeshMap, the world's only visual designer for Kubernetes and service mesh deployments, to the desktop of millions of developers. Developers and operators alike can visually configure and operate their cloud native infrastructure and applications using MeshMap's low code visual designer. +

    +

    +

    + Maximiliano Churichi, Software Engineer at HPE says how conveniently Meshery integrates different services into Docker. +

    +
      +
    • Kubernetes and service mesh support for your Docker Compose apps - Import your Docker Compose apps. Configure and deploy them to Kubernetes and any service mesh.
    • + +
    • Visual design of Kubernetes applications - Using MeshMap as a visual topology for designing Docker Compose applications, operating Kubernetes, all Kubernetes operators, workloads, and custom resources.
    • + +
    • Single-click deployment of your infrastructure - Support of 250+ different Kubernetes operators and 60+ cloud services at the fingertips of developers in connection with Docker Desktop’s ability to deliver Kubernetes locally.
    • + +
    • Detection of Kubernetes environments - Scan your kubeconfigs and select your current Kubernetes environment. Switch from one environment to another or manage all clusters concurrently.
    • +
    + +

    +

    Maximiliano demonstrates MeshMap

    +

    + +Layer5 MeshMap in Meshery Docker Extension + +
    +
    +

    +

    Designer Mode
    + Design a service mesh deployment with application and Envoy filter from scratch. Customize a service mesh deployment with application and Envoy filter from pattern. +

    + Meshery Docker Extension + +
    +
    +

    +

    Visualizer Mode
    + Examine a visual topology of Kubernetes cluster and its services. View and search log streams from your pod's containers. Connect an interactive terminal to instances of your containers. +

    + Meshery Docker Extension +
    +
    + + +
    + +
    + +

    Lee Calcote and Maximiliano Churichi packed a great deal of information in this talk. Find the recording below. The Meshery Extension is now out! Try now, and Share your Experience Apply for MeshMap Beta Program

    + +
    \ No newline at end of file diff --git a/src/collections/blog/2022/2022-05-14-service-meshcon-talk-intel/index.mdx b/src/collections/blog/2022/2022-05-14-service-meshcon-talk-intel/index.mdx index 08f737b48f4d..9f2185f0b74b 100644 --- a/src/collections/blog/2022/2022-05-14-service-meshcon-talk-intel/index.mdx +++ b/src/collections/blog/2022/2022-05-14-service-meshcon-talk-intel/index.mdx @@ -22,18 +22,18 @@ import { BlogWrapper } from "../../Blog.style.js"; import Blockquote from "../../../../reusecore/Blockquote"; import slidesTAG from "../../../events/2021/kubecon-china-2021/cncf-tag-network-and-service-mesh-working-group-kubecon-china-2021-lee-calcote-ken-owens.pdf"; import { Link } from "gatsby"; -import meshmark from './meshmark-dark-text-side.svg'; -import performanceQuestion from './performance-question.webp'; -import smp from './smp.webp'; -import meshmarkSlide from './meshmark.webp'; -import example from './example.webp'; -import formula from './formula.webp'; -import MUE from './mue.webp'; -import MeshMapDemo from './meshmark-score.webp'; +import meshmark from "./meshmark-dark-text-side.svg"; +import performanceQuestion from "./performance-question.webp"; +import smp from "./smp.webp"; +import meshmarkSlide from "./meshmark.webp"; +import example from "./example.webp"; +import formula from "./formula.webp"; +import MUE from "./mue.webp"; +import MeshMapDemo from "./meshmark-score.webp"; -
    +

    Lee Calcote and Mrittika Ganguli presented MeshMark: Service Mesh value measurement at ServiceMeshCon Europe 2022.

    @@ -102,8 +102,8 @@ the value that your infrastructure is providing. So we're really kind of missing

    -meshmark -meshmark example +meshmark +meshmark example

    MeshMark formula @@ -130,11 +130,14 @@ We could also take a look at service intentions of console and examine the effic

    - +

    MeshMark in Meshery (an excerpt from ServiceMeshCon EU 2022 demo)

    -

    Lee Calcote and Mrittika Ganguli covered all the concepts of SMP and MeshMark in this great talk. Learn more about MeshMark on the Service Mesh Performance website. +

    + + Lee Calcote and Mrittika Ganguli covered all the concepts of SMP and MeshMark in this great talk. Learn more about MeshMark on the Service Mesh Performance website. +

    diff --git a/src/collections/blog/2022/2022-05-20-meshmate-of-the-year-2021-aditya-chatterjee/index.mdx b/src/collections/blog/2022/2022-05-20-meshmate-of-the-year-2021-aditya-chatterjee/index.mdx index 4d55b829eb6f..5382cd742000 100644 --- a/src/collections/blog/2022/2022-05-20-meshmate-of-the-year-2021-aditya-chatterjee/index.mdx +++ b/src/collections/blog/2022/2022-05-20-meshmate-of-the-year-2021-aditya-chatterjee/index.mdx @@ -1,272 +1,271 @@ ---- -title: "MeshMate of the Year 2021: Aditya Chatterjee" -subtitle: "" -date: 2022-05-20 09:10:00 +0000 -author: Nikhil Ladha -thumbnail: ./MeshMate-of-the-Year-2021-Aditya-Chatterjee.webp -darkthumbnail: ./MeshMate-of-the-Year-2021-Aditya-Chatterjee.webp -category: Community -tags: - - Community -published: true ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import MMoY2021 from "./meshmate-of-the-year-2021.svg"; -import Blockquote from "../../../../reusecore/Blockquote"; -import BlockquoteAlt from "../../../../reusecore/Blockquote/Blockquote-alt-style"; -import { Link } from "gatsby"; -import graduateLFX from "./aditya-chatterjee-graduates-lfx-meshery-program.webp"; -import MeshMate from "../../../../assets/images/meshmate/meshmate-stack.svg"; -import MMOYAditya from "./MeshMate-of-the-Year-2021-Aditya-Chatterjee.webp"; - - - -

    - Nuturing a diverse, inclusive, and newcomer-friendly community like Layer5's - is not easy. As a group of hardworking, committed mentors,{" "} - - MeshMates - - , tirelessly work to help make the Layer5 community the award-winning, open - source community that it is. Each year, out of the group of MeshMates who - continuously engage and support community members, a single individual is - identified as the of MeshMate of the Year. -

    - -

    - As the{" "} - - inaugral winner of last year's - {" "} - MeshMate of the Year award, I am honored to present the prestigious MeshMate - of the Year badge to{" "} - - Aditya Chatterjee - - . Chosen by his peers and for his sheer dedication, Aditya Chatterjee is - awarded this badge of honor for 2021.{" "} - Congratulations mate, you have earned it! -

    - -{" "} -
    - -

    What is a Layer5 MeshMate?

    - -MeshMate -

    - - MeshMate - - is a distinction that Layer5 awards select members of the community who innately - align with our culture of helping others, paying it forward, and a commitment to - knowledge sharing. MeshMates are Layer5 mentors and ambassadors (not employees). -

    - -

    - A Layer5 MeshMate is individual who has consistently demonstrated their - commitment to helping community members. The MeshMate program pairs - experienced Layer5 community members with community newcomers to ensure a - smooth onboarding experience. Helping community members takes all forms from - ensuring the member has access to resources, is introduced to others, - understands the vision and goals of projects, can build and contribute to - projects, can use projects and have their feedback heard.{" "} -

    - MeshMates aid in identifying areas of projects and activities within the community - to engage within, which working groups to join, and in help community members grow - in their open source and cloud native knowledge. -

    - -

    - There is a lot going in the Layer5 community. Projects and working groups move - fast. By connecting one-on-one, MeshMates share tips on how to have the best - community experience possible, but also build a relationship with the - community member inevitably leaving a lasting mark as is evident from member - comments about Aditya. -

    - -

    It's not easy being a MeshMate

    - -

    - With thousands of members in the Layer5 community, many come and go. Many take - and many give. While we hope that each and every individual that joins will - find a fit in the community and/or on a project, this isn't always the case. - - Engaging with and investing in community members can be taxing on mentors in - terms of both their time and their emotional investment in seeing the newcomer - plant roots, grow, and blossom. -

    - -

    - One of the goals MeshMates have is that of enabling the newcomer's passion and - finding their sweetspot in the community and on a project, so that the - newcomer ultimately achieves their goals - goals that are often similar, but - different for each person. To help them acheive their goals, each individual - is engaged 1:1 by their Meshmate, supporting them in becoming a landstanding - Layer5 community member and contributor. MeshMates understand that many - mentees start out with the best of intentions, but that not all overcome their - hurdles in finding an area of the community to call home or aspect of a - project to own. -

    - - - - - - - -

    MeshMates are a massive force

    -

    - With all that said, you must have already realized that it is not easy being a - MeshMate. Only a few get this opportunity by showcasing their abilities and - commitment to the community. Aditya has always hovered around the horizon of - MeshMate since the moment he joined the community. In process of confirming - Aditya as the winner of the MeshMate of the Year award, we looked to the - community for validation. Little did I realize that meant reaching out to - nearly a hundred people whom Aditya has mentored or supported in the Layer5 - community. More than a few of them had something to say about their time with - Aditya: -

    - -
    -
    - -
    - -

    - Aditya graduates the LFX Meshery program. -

    -
    - -
    -
    - -
    - -
    -
    - -
    -
    - -
    - -
    - -
    - -
    -
    - -{" "} -Meshmate of the Year - -
    -
    - -
    -
    - -{" "} -
    - -{" "} -
    - -
    -
    - -MeshMate of the Year 2021: Aditya Chatterjee -

    - In recognition a year's worth of paying it forward, and for the award,{" "} - Aditya Chatterjee's - profile identifies him as the MeshMate of the Year award winner. Only two - people carry this badge today. I can only guess as to who this ribbon may be - awarded to in 2022. In the year and a half that Aditya has been in the - community, he has touched the lives of many people, including mine. -

    -
    - -

    - The MeshMate badge is a point of pride for individuals participating in the - program and looked upon with admiration and veneration by many within and - external to the Layer5 community. -

    - -

    - Wear your MeshMate of the Year badge proudly, Aditya. -

    - - +--- +title: "MeshMate of the Year 2021: Aditya Chatterjee" +subtitle: "" +date: 2022-05-20 09:10:00 +0000 +author: Nikhil Ladha +thumbnail: ./MeshMate-of-the-Year-2021-Aditya-Chatterjee.webp +darkthumbnail: ./MeshMate-of-the-Year-2021-Aditya-Chatterjee.webp +category: Community +tags: + - Community +published: true +--- + + +import MMoY2021 from "./meshmate-of-the-year-2021.svg"; + + + +import graduateLFX from "./aditya-chatterjee-graduates-lfx-meshery-program.webp"; +import MeshMate from "../../../../assets/images/meshmate/meshmate-stack.svg"; +import MMOYAditya from "./MeshMate-of-the-Year-2021-Aditya-Chatterjee.webp"; + + + +

    + Nuturing a diverse, inclusive, and newcomer-friendly community like Layer5's + is not easy. As a group of hardworking, committed mentors,{" "} + + MeshMates + + , tirelessly work to help make the Layer5 community the award-winning, open + source community that it is. Each year, out of the group of MeshMates who + continuously engage and support community members, a single individual is + identified as the of MeshMate of the Year. +

    + +

    + As the{" "} + + inaugral winner of last year's + + {" "}MeshMate of the Year award, I am honored to present the prestigious MeshMate + of the Year badge to{" "} + + Aditya Chatterjee + + . Chosen by his peers and for his sheer dedication, Aditya Chatterjee is + awarded this badge of honor for 2021.{" "} + Congratulations mate, you have earned it! +

    + +{" "} +
    + +

    What is a Layer5 MeshMate?

    + +MeshMate +

    + + MeshMate + + is a distinction that Layer5 awards select members of the community who innately + align with our culture of helping others, paying it forward, and a commitment to + knowledge sharing. MeshMates are Layer5 mentors and ambassadors (not employees). +

    + +

    + A Layer5 MeshMate is individual who has consistently demonstrated their + commitment to helping community members. The MeshMate program pairs + experienced Layer5 community members with community newcomers to ensure a + smooth onboarding experience. Helping community members takes all forms from + ensuring the member has access to resources, is introduced to others, + understands the vision and goals of projects, can build and contribute to + projects, can use projects and have their feedback heard.{" "} +

    + MeshMates aid in identifying areas of projects and activities within the community + to engage within, which working groups to join, and in help community members grow + in their open source and cloud native knowledge. +

    + +

    + There is a lot going in the Layer5 community. Projects and working groups move + fast. By connecting one-on-one, MeshMates share tips on how to have the best + community experience possible, but also build a relationship with the + community member inevitably leaving a lasting mark as is evident from member + comments about Aditya. +

    + +

    It's not easy being a MeshMate

    + +

    + With thousands of members in the Layer5 community, many come and go. Many take + and many give. While we hope that each and every individual that joins will + find a fit in the community and/or on a project, this isn't always the case. + + Engaging with and investing in community members can be taxing on mentors in + terms of both their time and their emotional investment in seeing the newcomer + plant roots, grow, and blossom. +

    + +

    + One of the goals MeshMates have is that of enabling the newcomer's passion and + finding their sweetspot in the community and on a project, so that the + newcomer ultimately achieves their goals - goals that are often similar, but + different for each person. To help them acheive their goals, each individual + is engaged 1:1 by their Meshmate, supporting them in becoming a landstanding + Layer5 community member and contributor. MeshMates understand that many + mentees start out with the best of intentions, but that not all overcome their + hurdles in finding an area of the community to call home or aspect of a + project to own. +

    + + + + + + + +

    MeshMates are a massive force

    +

    + With all that said, you must have already realized that it is not easy being a + MeshMate. Only a few get this opportunity by showcasing their abilities and + commitment to the community. Aditya has always hovered around the horizon of + MeshMate since the moment he joined the community. In process of confirming + Aditya as the winner of the MeshMate of the Year award, we looked to the + community for validation. Little did I realize that meant reaching out to + nearly a hundred people whom Aditya has mentored or supported in the Layer5 + community. More than a few of them had something to say about their time with + Aditya: +

    + +
    +
    + +
    + +

    + Aditya graduates the LFX Meshery program. +

    +
    + +
    +
    + +
    + +
    +
    + +
    +
    + +
    + +
    + +
    + +
    +
    + +{" "} +Meshmate of the Year + +
    +
    + +
    +
    + +{" "} +
    + +{" "} +
    + +
    +
    + +MeshMate of the Year 2021: Aditya Chatterjee +

    + In recognition a year's worth of paying it forward, and for the award,{" "} + Aditya Chatterjee's + profile identifies him as the MeshMate of the Year award winner. Only two + people carry this badge today. I can only guess as to who this ribbon may be + awarded to in 2022. In the year and a half that Aditya has been in the + community, he has touched the lives of many people, including mine. +

    +
    + +

    + The MeshMate badge is a point of pride for individuals participating in the + program and looked upon with admiration and veneration by many within and + external to the Layer5 community. +

    + +

    + Wear your MeshMate of the Year badge proudly, Aditya. +

    + + diff --git a/src/collections/blog/2022/2022-05-27-debug-envoy-proxy/index.mdx b/src/collections/blog/2022/2022-05-27-debug-envoy-proxy/index.mdx index d342bcf97ed4..b1b1a1487926 100644 --- a/src/collections/blog/2022/2022-05-27-debug-envoy-proxy/index.mdx +++ b/src/collections/blog/2022/2022-05-27-debug-envoy-proxy/index.mdx @@ -1,190 +1,187 @@ ---- -title: "Debug Envoy Proxy" -subtitle: "" -description: "An open index for measuring performance of cloud native infrastructure in context of the value provided to your business." -date: 2022-05-27 09:10:00 +0000 -author: Layer5 Team -thumbnail: ./debug-envoy-proxy.svg -darkthumbnail: ./debug-envoy-proxy.svg -category: Service Mesh -tags: - - Envoy - - Troubleshooting -published: true -resource: true -type: Blog -redirect_from: - - /blog/envoy/debug-envoy-proxy/ - - /blog/envoy/debug-envoy-proxy ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import { Link } from "gatsby"; -import bugEnvoy from "./debug-envoy-proxy.svg"; -import DockerExtensionCTA from "../../../../sections/Docker-Meshery/docker-extension-CTA"; -import Code from "../../../../components/CodeBlock"; - - -

    - Trying to figure out what's happening with your request traffic? Not sure why your Envoy configuration isn't working? If you're using Istio as your gateway and need to troubleshoot your ingress traffic requests, here are a few tips for debugging Envoy proxy. -

    -

    Enable Envoy Debug Logging

    -

    - By default Envoy system logs are sent to /dev/stderr. This location be overridden using --log-path. Logging to /dev/stderr for system logs and to /dev/stdout for access logs can be useful when running Envoy inside a container. In this way, these two individual logstreams can be separated, and using this approach, logging requires no additional files or directories to be mounted. -

    -
    -

    - We recommend setting the Envoy proxy’s log level to debug in a pre-production environment. Debug logs can help you identify issues before you graduate the associated configuration to your production environment. -

    -
    -

    Using envoy CLI

    -

    - The envoy command has a --log-level flag that can be useful for debugging. By default, it’s set to info. To change it to debug, edit the envoy DaemonSet in the istio-system namespace and replace the --log-level info flag with --log-level debug. Setting the Envoy log level to debug can be particilarly useful for debugging TLS connection failures. -

    -

    Using container image

    -

    - If you’re using the Envoy image, you can set the log level to debug through the ENVOY_LOG_LEVEL environment variable. The log level for Envoy system logs can be set using the -l or --log-level option. -

    - -The available log levels are: - -
      -
    • trace
    • -
    • debug
    • -
    • info
    • -
    • warning/warn
    • -
    • error
    • -
    • critical
    • -
    • off
    • -
    - -The default is info. - -

    Setting Envoy logs in the Helm configuration

    - -

    - The Consul helm chart uses envoyExtraArgs: to leverage Envoy command line options. One of the helpful options is --component-log-level. This provides granular control over setting log levels for Envoy components. In the example below, the components upstream, http, router and config are set to the debug log level. These four components are vital when debugging issues with requests between your services(sidecar proxies). -

    - -
    -
    -    connectInject:
    -  enabled: true
    -  envoyExtraArgs: "--component-log-level upstream:debug,http:debug,router:debug,config:debug"
    -  
    -
    - -

    - If you haven't set envoyExtraArgs: in consul-values.yaml just yet, you can set the log levels on the fly by using the following kubectl command: -

    - -
    -
    -    $ kubectl exec pod/pod-name -c container-name -- curl -X POST http://localhost:19000/logging?config=debug
    -  
    -
    - -

    Example:

    - -
    -
    -    $ kubectl exec pod/static-client-5bf4575d9c-zr2b -c static-client -- curl -X POST  http://localhost:19000/logging?config=debug
    -  
    -
    - -

    - You will execute the kubectl command for each component. Make sure to append the correct component at the end of the curl command, i.e. logging? component = debug. -

    - -

    - If curl is not able to be used in your pod, you can alternatively use kubectl port-forward pod-name 19000 to make the Envoy admin accessible. From another terminal window, you can then curl to change the log levels. The output you receive in the terminal will show the modified component log levels. -

    - -
    -
    -    $ curl -X POST http://localhost:19000/logging? component = debug
    -  
    -
    -

    Access Envoy logs in Kubernetes

    - -

    Accessing Envoy logs via pods can be done with the following command:

    - -
    -
    -    $ kubectl logs --follow pod/ pod-name -c envoy-sidecar
    -  
    -
    - -

    The --follow flag provides a real time observation into Envoy logs.

    - -

    Setting and Accessing Envoy logs when not using Helm.

    - -

    The following command will start an envoy side car proxy, set the log level to debug with -l debug and capture Envoy logs in envoy_logs.txt. The .txt file will need to be created before executing this command.

    - -
    -
    -    $ consul connect envoy -sidecar-for counting-1 -- -l debug --log-path envoy_logs.txt
    -  
    -
    - -

    To have granular control over the Envoy components that is needed to be debugged, use the following command:

    - -
    -
    -    $ consul connect envoy -sidecar-for counting-1 -- --log-path envoy_logs.txt --component-log-level upstream:debug,http:debug,router:debug,config:debug
    -  
    -
    - -

    Find your Istio Ingress Gateway

    -

    - With Istio as your gateway, you should first look at VirtualService objects. These can show if the hosts are registered to the gateway correctly. -

    - -
    -
    -    $ kubectl get virtualservice -o=yaml
    -  
    -
    - -

    - However, sometimes, the Envoy inside the gateway container is not properly configured (likely due to a bug). You can dump Envoy configuration to debug this further. -

    - -
    -
    -    # find istio ingress gateway pod \
    -      $ kubectl get pods -n istio-system -l app=istio-ingressgateway
    -  
    -
    - -

    - Let's use istio-ingressgateway-a93019f9dfw-l39xd as an example pod name. -

    - -
    -
    -    
    -      # enable debugging on envoy \
    -      $ kubectl exec --namespace=istio-system \
    -      istio-ingressgateway-a93019f9dfw-l39xd \
    -      -c istio-proxy -- curl -X POST \
    -      http://localhost:15000/logging?level=debug
    -    
    -  
    -
    -

    - Then, use istioctl tool to dump route configuration (this will show the output from the /config_dump admin endpoint on Envoy): -

    -
    -
    -    
    -    $ istioctl proxy-config routes -n istio-system -o=json \
    -      istio-ingressgateway-a93019f9dfw-l39xd
    -    
    -  
    -
    -

    - We hope these steps are useful to you. If you're still having trouble configuring Envoy proxy, open up a new thread on the community discussion forum or subscribe to the Layer5 newletter for tips and tricks. -

    - +--- +title: "Debug Envoy Proxy" +subtitle: "" +description: "An open index for measuring performance of cloud native infrastructure in context of the value provided to your business." +date: 2022-05-27 09:10:00 +0000 +author: Layer5 Team +thumbnail: ./debug-envoy-proxy.svg +darkthumbnail: ./debug-envoy-proxy.svg +category: Service Mesh +tags: + - Envoy + - Troubleshooting +published: true +resource: true +type: Blog +redirect_from: + - /blog/envoy/debug-envoy-proxy/ + - /blog/envoy/debug-envoy-proxy +--- + +import bugEnvoy from "./debug-envoy-proxy.svg"; + + + +

    + Trying to figure out what's happening with your request traffic? Not sure why your Envoy configuration isn't working? If you're using Istio as your gateway and need to troubleshoot your ingress traffic requests, here are a few tips for debugging Envoy proxy. +

    +

    Enable Envoy Debug Logging

    +

    + By default Envoy system logs are sent to /dev/stderr. This location be overridden using --log-path. Logging to /dev/stderr for system logs and to /dev/stdout for access logs can be useful when running Envoy inside a container. In this way, these two individual logstreams can be separated, and using this approach, logging requires no additional files or directories to be mounted. +

    +
    +

    + We recommend setting the Envoy proxy’s log level to debug in a pre-production environment. Debug logs can help you identify issues before you graduate the associated configuration to your production environment. +

    +
    +

    Using envoy CLI

    +

    + The envoy command has a --log-level flag that can be useful for debugging. By default, it’s set to info. To change it to debug, edit the envoy DaemonSet in the istio-system namespace and replace the --log-level info flag with --log-level debug. Setting the Envoy log level to debug can be particilarly useful for debugging TLS connection failures. +

    +

    Using container image

    +

    + If you’re using the Envoy image, you can set the log level to debug through the ENVOY_LOG_LEVEL environment variable. The log level for Envoy system logs can be set using the -l or --log-level option. +

    + +The available log levels are: + +
      +
    • trace
    • +
    • debug
    • +
    • info
    • +
    • warning/warn
    • +
    • error
    • +
    • critical
    • +
    • off
    • +
    + +The default is info. + +

    Setting Envoy logs in the Helm configuration

    + +

    + The Consul helm chart uses envoyExtraArgs: to leverage Envoy command line options. One of the helpful options is --component-log-level. This provides granular control over setting log levels for Envoy components. In the example below, the components upstream, http, router and config are set to the debug log level. These four components are vital when debugging issues with requests between your services(sidecar proxies). +

    + +
    +
    +    connectInject:
    +  enabled: true
    +  envoyExtraArgs: "--component-log-level upstream:debug,http:debug,router:debug,config:debug"
    +  
    +
    + +

    + If you haven't set envoyExtraArgs: in consul-values.yaml just yet, you can set the log levels on the fly by using the following kubectl command: +

    + +
    +
    +    $ kubectl exec pod/pod-name -c container-name -- curl -X POST http://localhost:19000/logging?config=debug
    +  
    +
    + +

    Example:

    + +
    +
    +    $ kubectl exec pod/static-client-5bf4575d9c-zr2b -c static-client -- curl -X POST  http://localhost:19000/logging?config=debug
    +  
    +
    + +

    + You will execute the kubectl command for each component. Make sure to append the correct component at the end of the curl command, i.e. logging? component = debug. +

    + +

    + If curl is not able to be used in your pod, you can alternatively use kubectl port-forward pod-name 19000 to make the Envoy admin accessible. From another terminal window, you can then curl to change the log levels. The output you receive in the terminal will show the modified component log levels. +

    + +
    +
    +    $ curl -X POST http://localhost:19000/logging? component = debug
    +  
    +
    +

    Access Envoy logs in Kubernetes

    + +

    Accessing Envoy logs via pods can be done with the following command:

    + +
    +
    +    $ kubectl logs --follow pod/ pod-name -c envoy-sidecar
    +  
    +
    + +

    The --follow flag provides a real time observation into Envoy logs.

    + +

    Setting and Accessing Envoy logs when not using Helm.

    + +

    The following command will start an envoy side car proxy, set the log level to debug with -l debug and capture Envoy logs in envoy_logs.txt. The .txt file will need to be created before executing this command.

    + +
    +
    +    $ consul connect envoy -sidecar-for counting-1 -- -l debug --log-path envoy_logs.txt
    +  
    +
    + +

    To have granular control over the Envoy components that is needed to be debugged, use the following command:

    + +
    +
    +    $ consul connect envoy -sidecar-for counting-1 -- --log-path envoy_logs.txt --component-log-level upstream:debug,http:debug,router:debug,config:debug
    +  
    +
    + +

    Find your Istio Ingress Gateway

    +

    + With Istio as your gateway, you should first look at VirtualService objects. These can show if the hosts are registered to the gateway correctly. +

    + +
    +
    +    $ kubectl get virtualservice -o=yaml
    +  
    +
    + +

    + However, sometimes, the Envoy inside the gateway container is not properly configured (likely due to a bug). You can dump Envoy configuration to debug this further. +

    + +
    +
    +    # find istio ingress gateway pod \
    +      $ kubectl get pods -n istio-system -l app=istio-ingressgateway
    +  
    +
    + +

    + Let's use istio-ingressgateway-a93019f9dfw-l39xd as an example pod name. +

    + +
    +
    +    
    +      # enable debugging on envoy \
    +      $ kubectl exec --namespace=istio-system \
    +      istio-ingressgateway-a93019f9dfw-l39xd \
    +      -c istio-proxy -- curl -X POST \
    +      http://localhost:15000/logging?level=debug
    +    
    +  
    +
    +

    + Then, use istioctl tool to dump route configuration (this will show the output from the /config_dump admin endpoint on Envoy): +

    +
    +
    +    
    +    $ istioctl proxy-config routes -n istio-system -o=json \
    +      istio-ingressgateway-a93019f9dfw-l39xd
    +    
    +  
    +
    +

    + We hope these steps are useful to you. If you're still having trouble configuring Envoy proxy, open up a new thread on the community discussion forum or subscribe to the Layer5 newletter for tips and tricks. +

    +
    \ No newline at end of file diff --git a/src/collections/blog/2022/2022-06-01-perfbytes-podcast/index.mdx b/src/collections/blog/2022/2022-06-01-perfbytes-podcast/index.mdx index 5a7a11a379e5..99d9f5f4f62e 100644 --- a/src/collections/blog/2022/2022-06-01-perfbytes-podcast/index.mdx +++ b/src/collections/blog/2022/2022-06-01-perfbytes-podcast/index.mdx @@ -1,129 +1,126 @@ ---- -title: "Perfbytes Podcast" -subtitle: "Ask Me Anything" -date: 2022-06-01 09:10:00 +0000 -author: Debopriya Bhattacharjee -thumbnail: ./perfbytes-layer5.svg -darkthumbnail: ./perfbytes-layer5.svg -category: Events -tags: - - Events - - Service Mesh Performance - - Meshery -published: true -resource: true -type: Blog -product: Meshery ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import Blockquote from "../../../../reusecore/Blockquote"; -import BlockquoteAlt from "../../../../reusecore/Blockquote/Blockquote-alt-style"; -import { Link } from "gatsby"; -import { PerfbytesPodcast } from "./perfbytesPodcast"; -import ConsulDemo from "./consul-docker-extension-demo.webp" - - - - -

    Podcast Insights

    -

    Many questions were asked, answered, and a variety of topics were discussed. The story just gets better. This podcast goes deep into service meshes, load generators, circuit breaker, service mesh patterns in addition to a live demo of Meshery and more. Hosted by Henrik from Perfbytes and joined by Mark, Lee Calcote from Layer5 and Mrittika Ganguli from Intel. Tune in to find out more. Get answers to all community questions as a bonus.

    - -

    What is a service mesh?

    -
    -

    Service mesh is one of the solutions that helps you to route traffic within your cluster so as to expose your services outside the cluster. It is a solution to control how different parts of an application share data with one another. Unlike other systems for managing this communication, a service mesh is a dedicated infrastructure layer built right into an app. You have different options like the service type load balancer or using ingress but service mesh makes sense because it will manage a lot of features around your service to service communication.

    -
    - -In general, service meshes arose from the concept of proxies such as the NGINX proxy. Then Envoy was introduced by Lyft. Lyft had the architecture, and Google came along and created it. That gave us Istio, which is now part of CNCF. -
    - -Service meshes, according to Lee, "hit a real sweet spot personally", having been focused on networking for most part of his career. -He believes that there are a couple of different ways to speak about the genesis of service meshes, with Linkerd being the first to coin the term. -We had Linkerd v1 written in scala and use jvm and then came Linkerd v2 which is something totally different at this point. It's all different code, different languages and a different service mesh architecture. There's a number of different architectures by which service meshes are deployed. There's a new one that's been softly announced in beta from called Cilium that is helping bring back some of the different architectures of how to run the proxies. - -
    -

    -The way I prefer to think about a surface mesh is that it's all about resiliency. -If you were to take a three-tiered web or three-tiered app and you think about how you're breaking out those tiers with some amount of -kind of vertical scaling, you'd probably, end up putting at least a virtual IP address out in front of the whole web tier and then you've got an app tier and a database tier because you've got multiple instances of those things. Maybe there's a load balancer in between. This structure makes it simple to boost your resiliency. -

    -
    - -Henrik goes on to elaborate that in service mesh we can do a lot of things to make sure that the communication is reliable. -When you design microservice architecture, there is a need of implementing retry logic. So if a service A needs to introduce another service B, then the service mesh will manage the retry logic such that if we reach at one time and the service B is not responding then the service mesh will try to reach out several times. Therefore a service mesh offers a variety of features like this to manage the certificates within the cluster and and circle them in a regular pace. You can also have traffic splitting if you do canary releases. In your service to service communication, there are a plethora of scenarios that the service mesh can handle. -Henrik recalled that it's normally difficult to obtain a full view of what rules we've applied in the cluster, and when he first saw Meshery, his immediate thought was, "Wow, this is exactly what is missing in the market at the moment." - - -Lets dig deeper into this tool we've been alluding to for a while now: Meshery. - -

    Meshery

    -If you were on a pager and were managing a large service mesh deployment with a number of rules and configurations around how security is enforced and identities are managed, and things like uniform observability and how metrics and logs are collected and enforced, and then the different traffic writing rules and stuff. You might soil myself if you had to go make a change in that sea of yaml. That's in part what we're working towards. There's a capability within Meshery for solving this challenge. As a cloud native management plane, Meshery presides over top of 10 different types of service meshes and it also presides over kubernetes. You can run it outside of kubernetes or inside of kubernetes. -

    -Meshery has a number of components to its architecture. There is Meshery UI. It has a Mesheryctl, which is a CLI component. We have a number of service mesh adapters for each service mesh that Meshery supports. -

    - -
    What is the need for different adapters?
    -
    -Meshery, as the multi-mesh manager, supports couple of different adapters. Adapters are used by Meshery to manage the numerous service meshes. Different service mesh adapters are written to expose the unique value of each service mesh. Consequently, they are not equally capable just as each service mesh is not equally capable as the other. Some of them work in a similar way. Some of the service meshes have their own differentiated value, which is why there are individual adapters. Some of them work slightly differently depending on whether they're running as a managed service or not. -
    - - -We have a plug-in for Meshery it's called MeshMap, it is what you might consider a visual topology. It has a lot of use cases for observing in kind of a read-only mode. There's a second mode to this tool: The Designer Mode. It's a visual configurator of not only the specific settings within any of those service meshes that it supports like a circuit breaker and adjusting the sensor video -but also end up being a visual designer for your kubernetes deployments. When users drop in, they're able to go over and grab the specific capabilities of any of those service mesh adapters that are loaded for any of the versions of that mesh that they might want to design. The concept here is that they drag and drop these capabilities over and there's a bit of discoverability that's afforded through this ui rather than parsing through yaml, trying to understand what's going on. - -Consul MeshMap Demo - -I like to pretend that I know a lot about service meshes, but when it comes to having to keep track of all of them, I don't know what the gateway tls sds config is, and so this type of inline help is quite useful to design your deployments. The deployments may or may not use a mesh; in fact, you can use this to create your Kubernetes configuration and deployment as well.  You can even save and recall those designs. - -Taking this example of consul, produced by hashicorp, is a little more of an -intriguing deployment and a simple two-tier deck. We announced the Meshery Docker Extension recently. So if you're using docker desktop, Meshery will be a first class app that's available inside of market and part of what it does as it integrates with docker desktop is it will import docker compose apps convert them to kubernetes manifests or kubernetes apps and they'll let you deploy those formerly docker compose apps onto a mesh which is why I'm talking about a two-tiered service. - -
    Does MeshMap allow you to load the current configuration that is has been applied in the current cluster? -
    -
    -Currently, there are two modes: the one we were looking at before was the designer mode, and the one we'll be looking at now is the visualizer mode, which is probably a little more of an it's not entirely read-only to the extent that you could grab a pod and start an interactive session with the containers in that pod or you could you start a logging session. You could also initiate a performance test against  that particular service or that particular endpoint.  -Meshery supports three different types of load generators, which is a nighthawk, fortio and wrk2. -
    - -
    What are the capabilities of these three load generators? When you speak about service mesh testing or performance testing, what is actually the process behind the scene? What should users think about when they're starting a gig and need to configure and optimize the service mesh?
    -
    -

    Lee expounds on that for our benefit. -It takes weeks to months that you've got to dedicate for performance engineers to go over and like pull together various tools and scripts around them to then get into a spreadsheet or into some database that you then generate results. -The genesis of Meshery part was to help people comprehend what a service mesh is, when to use one and which one to use? As you go to explain these common questions, the real answer is a totally disappointing, which is, it just depends on what you're asking to do.

    -

    -People want to measure it in cold hard quantitative metrics but if you're asking to do 100 percent sampling then also consider the distributed tracing implementation you had somewhere else and the fact that you're getting it -in a uniform way here. Maybe you're likely to consider the overhead that you would have over there. It's frustrating to be trying to explain stuff to folks and get them excited about the tech and and to give them a vague response. Instead we give them a tool that says "Hey look here's a tool that will deploy any of the service meshes that you want to test out." -

    -

    -There's a reason why there's ten of them like and actually many more than that. -There's a lot of overlap between them but different tools for different purposes for different size orgs, so it would be inappropriate to say well you know here's the one. It's rather hey here's a tool that that lets you deploy any number of them quickly, answer your own question about performance, because we can pump out benchmarks of the various service meshes under various configurations, using different types of workloads but which may or may not match your environment and over time those reports are going to get stale and so rather he's a tool to make you empowered. -

    -
    - -
    Do you actually generate traffic that will go through the sidecar proxy of the service and then reach out the actual service?
    -
    -That load is generated on demand or on schedule against one or more endpoints, one or more of your services or something that is not even on your service. You can generate load not only against something running within your infrastructure but something external as well to do statistical analysis based on the configuration that you gave it and so yeah the answer is yes the traffic flows through the sidecar. -
    - -
    If I say I have never scripted or built any scenarios for fortio or nighthawk. Let's say I'm a loadrunner, a neoload, or a k6 user, and I want to accomplish the same thing with them. So what is the journey on those load generator? is it the same thing you have to build a workflow of requests that you want to send in that scenario?
    -
    -

    That leads us to probably talk about one of our other projects which is called Performance which is a specification. It's another one of the projects that we've donated to the CNCF. Service Mesh Performance is the spec while Meshery is an implementation of the spec. -At a high level, if those other load generators were to adhere to how we standardize and describe the test that you want to run and then hand off that configuration to generate the performance profiles that are created here you're not gonna down download them but the descriptor is important. -

    -This implements a standard for the industry on what is the actual -service mesh test and then standardize the format so then anyone can use the same format to design their script or whatever they want and then use it to test. -So when I build a script, and I don't know loadrunner today and I want to use neologo tomorrow, then I don't have to rewrite everything. Great! -
    - -Missed the podcast? No worries, we got you covered. Check out the recording below :) - -
    - -
    - - - - +--- +title: "Perfbytes Podcast" +subtitle: "Ask Me Anything" +date: 2022-06-01 09:10:00 +0000 +author: Debopriya Bhattacharjee +thumbnail: ./perfbytes-layer5.svg +darkthumbnail: ./perfbytes-layer5.svg +category: Events +tags: + - Events + - Service Mesh Performance + - Meshery +published: true +resource: true +type: Blog +product: Meshery +--- + + + + + +import { PerfbytesPodcast } from "./perfbytesPodcast"; +import ConsulDemo from "./consul-docker-extension-demo.webp" + + + + +

    Podcast Insights

    +

    Many questions were asked, answered, and a variety of topics were discussed. The story just gets better. This podcast goes deep into service meshes, load generators, circuit breaker, service mesh patterns in addition to a live demo of Meshery and more. Hosted by Henrik from Perfbytes and joined by Mark, Lee Calcote from Layer5 and Mrittika Ganguli from Intel. Tune in to find out more. Get answers to all community questions as a bonus.

    + +

    What is a service mesh?

    +
    +

    Service mesh is one of the solutions that helps you to route traffic within your cluster so as to expose your services outside the cluster. It is a solution to control how different parts of an application share data with one another. Unlike other systems for managing this communication, a service mesh is a dedicated infrastructure layer built right into an app. You have different options like the service type load balancer or using ingress but service mesh makes sense because it will manage a lot of features around your service to service communication.

    +
    + +In general, service meshes arose from the concept of proxies such as the NGINX proxy. Then Envoy was introduced by Lyft. Lyft had the architecture, and Google came along and created it. That gave us Istio, which is now part of CNCF. +
    + +Service meshes, according to Lee, "hit a real sweet spot personally", having been focused on networking for most part of his career. +He believes that there are a couple of different ways to speak about the genesis of service meshes, with Linkerd being the first to coin the term. +We had Linkerd v1 written in scala and use jvm and then came Linkerd v2 which is something totally different at this point. It's all different code, different languages and a different service mesh architecture. There's a number of different architectures by which service meshes are deployed. There's a new one that's been softly announced in beta from called Cilium that is helping bring back some of the different architectures of how to run the proxies. + +
    +

    +The way I prefer to think about a surface mesh is that it's all about resiliency. +If you were to take a three-tiered web or three-tiered app and you think about how you're breaking out those tiers with some amount of +kind of vertical scaling, you'd probably, end up putting at least a virtual IP address out in front of the whole web tier and then you've got an app tier and a database tier because you've got multiple instances of those things. Maybe there's a load balancer in between. This structure makes it simple to boost your resiliency. +

    +
    + +Henrik goes on to elaborate that in service mesh we can do a lot of things to make sure that the communication is reliable. +When you design microservice architecture, there is a need of implementing retry logic. So if a service A needs to introduce another service B, then the service mesh will manage the retry logic such that if we reach at one time and the service B is not responding then the service mesh will try to reach out several times. Therefore a service mesh offers a variety of features like this to manage the certificates within the cluster and and circle them in a regular pace. You can also have traffic splitting if you do canary releases. In your service to service communication, there are a plethora of scenarios that the service mesh can handle. +Henrik recalled that it's normally difficult to obtain a full view of what rules we've applied in the cluster, and when he first saw Meshery, his immediate thought was, "Wow, this is exactly what is missing in the market at the moment." + + +Lets dig deeper into this tool we've been alluding to for a while now: Meshery. + +

    Meshery

    +If you were on a pager and were managing a large service mesh deployment with a number of rules and configurations around how security is enforced and identities are managed, and things like uniform observability and how metrics and logs are collected and enforced, and then the different traffic writing rules and stuff. You might soil myself if you had to go make a change in that sea of yaml. That's in part what we're working towards. There's a capability within Meshery for solving this challenge. As a cloud native management plane, Meshery presides over top of 10 different types of service meshes and it also presides over kubernetes. You can run it outside of kubernetes or inside of kubernetes. +

    +Meshery has a number of components to its architecture. There is Meshery UI. It has a Mesheryctl, which is a CLI component. We have a number of service mesh adapters for each service mesh that Meshery supports. +

    + +
    What is the need for different adapters?
    +
    +Meshery, as the multi-mesh manager, supports couple of different adapters. Adapters are used by Meshery to manage the numerous service meshes. Different service mesh adapters are written to expose the unique value of each service mesh. Consequently, they are not equally capable just as each service mesh is not equally capable as the other. Some of them work in a similar way. Some of the service meshes have their own differentiated value, which is why there are individual adapters. Some of them work slightly differently depending on whether they're running as a managed service or not. +
    + + +We have a plug-in for Meshery it's called MeshMap, it is what you might consider a visual topology. It has a lot of use cases for observing in kind of a read-only mode. There's a second mode to this tool: The Designer Mode. It's a visual configurator of not only the specific settings within any of those service meshes that it supports like a circuit breaker and adjusting the sensor video +but also end up being a visual designer for your kubernetes deployments. When users drop in, they're able to go over and grab the specific capabilities of any of those service mesh adapters that are loaded for any of the versions of that mesh that they might want to design. The concept here is that they drag and drop these capabilities over and there's a bit of discoverability that's afforded through this ui rather than parsing through yaml, trying to understand what's going on. + +Consul MeshMap Demo + +I like to pretend that I know a lot about service meshes, but when it comes to having to keep track of all of them, I don't know what the gateway tls sds config is, and so this type of inline help is quite useful to design your deployments. The deployments may or may not use a mesh; in fact, you can use this to create your Kubernetes configuration and deployment as well.  You can even save and recall those designs. + +Taking this example of consul, produced by hashicorp, is a little more of an +intriguing deployment and a simple two-tier deck. We announced the Meshery Docker Extension recently. So if you're using docker desktop, Meshery will be a first class app that's available inside of market and part of what it does as it integrates with docker desktop is it will import docker compose apps convert them to kubernetes manifests or kubernetes apps and they'll let you deploy those formerly docker compose apps onto a mesh which is why I'm talking about a two-tiered service. + +
    Does MeshMap allow you to load the current configuration that is has been applied in the current cluster?
    +
    +Currently, there are two modes: the one we were looking at before was the designer mode, and the one we'll be looking at now is the visualizer mode, which is probably a little more of an it's not entirely read-only to the extent that you could grab a pod and start an interactive session with the containers in that pod or you could you start a logging session. You could also initiate a performance test against  that particular service or that particular endpoint.  +Meshery supports three different types of load generators, which is a nighthawk, fortio and wrk2. +
    + +
    What are the capabilities of these three load generators? When you speak about service mesh testing or performance testing, what is actually the process behind the scene? What should users think about when they're starting a gig and need to configure and optimize the service mesh?
    +
    +

    Lee expounds on that for our benefit. +It takes weeks to months that you've got to dedicate for performance engineers to go over and like pull together various tools and scripts around them to then get into a spreadsheet or into some database that you then generate results. +The genesis of Meshery part was to help people comprehend what a service mesh is, when to use one and which one to use? As you go to explain these common questions, the real answer is a totally disappointing, which is, it just depends on what you're asking to do.

    +

    +People want to measure it in cold hard quantitative metrics but if you're asking to do 100 percent sampling then also consider the distributed tracing implementation you had somewhere else and the fact that you're getting it +in a uniform way here. Maybe you're likely to consider the overhead that you would have over there. It's frustrating to be trying to explain stuff to folks and get them excited about the tech and and to give them a vague response. Instead we give them a tool that says "Hey look here's a tool that will deploy any of the service meshes that you want to test out." +

    +

    +There's a reason why there's ten of them like and actually many more than that. +There's a lot of overlap between them but different tools for different purposes for different size orgs, so it would be inappropriate to say well you know here's the one. It's rather hey here's a tool that that lets you deploy any number of them quickly, answer your own question about performance, because we can pump out benchmarks of the various service meshes under various configurations, using different types of workloads but which may or may not match your environment and over time those reports are going to get stale and so rather he's a tool to make you empowered. +

    +
    + +
    Do you actually generate traffic that will go through the sidecar proxy of the service and then reach out the actual service?
    +
    +That load is generated on demand or on schedule against one or more endpoints, one or more of your services or something that is not even on your service. You can generate load not only against something running within your infrastructure but something external as well to do statistical analysis based on the configuration that you gave it and so yeah the answer is yes the traffic flows through the sidecar. +
    + +
    If I say I have never scripted or built any scenarios for fortio or nighthawk. Let's say I'm a loadrunner, a neoload, or a k6 user, and I want to accomplish the same thing with them. So what is the journey on those load generator? is it the same thing you have to build a workflow of requests that you want to send in that scenario?
    +
    +

    That leads us to probably talk about one of our other projects which is called Performance which is a specification. It's another one of the projects that we've donated to the CNCF. Service Mesh Performance is the spec while Meshery is an implementation of the spec. At a high level, if those other load generators were to adhere to how we standardize and describe the test that you want to run and then hand off that configuration to generate the performance profiles that are created here you're not gonna down download them but the descriptor is important.

    +This implements a standard for the industry on what is the actual +service mesh test and then standardize the format so then anyone can use the same format to design their script or whatever they want and then use it to test. +So when I build a script, and I don't know loadrunner today and I want to use neologo tomorrow, then I don't have to rewrite everything. Great! +
    + +Missed the podcast? No worries, we got you covered. Check out the recording below :) + +
    + +
    + + + + diff --git a/src/collections/blog/2022/2022-06-07-week-open-source-contributions-with-layer5/index.mdx b/src/collections/blog/2022/2022-06-07-week-open-source-contributions-with-layer5/index.mdx index 50dd4059621e..c971829c2964 100644 --- a/src/collections/blog/2022/2022-06-07-week-open-source-contributions-with-layer5/index.mdx +++ b/src/collections/blog/2022/2022-06-07-week-open-source-contributions-with-layer5/index.mdx @@ -12,14 +12,14 @@ tags: published: true --- -import { Link } from "gatsby"; -import { BlogWrapper } from "../../Blog.style.js"; -import mentees from './mentees.webp' + + +import mentees from "./mentees.webp" import meshmate from "../../../../assets/images/meshmate/meshmate-icon.svg" -
    +

    To newbies, open source contributions may seem daunting. In much the same way that non-techies develop a reverence for programmers courtesy of the film industry’s portrayal of them as wizards whose brains magically sprout up elaborate mathematical models and whose mouths eloquently spew technological jargon, so do newbies perceive contributors: a bunch of techies who debug in seconds, recite programming language documentation by heart and, well, create pull requests in their sleep (this is a bit exaggerated, but you get the point).

    @@ -89,7 +89,7 @@ To newbies, open source contributions may seem daunting. In much the same way th

    • - Ekene Leonard Nwobodo + Ekene Leonard Nwobodo
    • Etiene James diff --git a/src/collections/blog/2022/2022-06-08-experience-lfx-pranav-singh/index.mdx b/src/collections/blog/2022/2022-06-08-experience-lfx-pranav-singh/index.mdx index 5c188d25e8ce..08c95770e658 100644 --- a/src/collections/blog/2022/2022-06-08-experience-lfx-pranav-singh/index.mdx +++ b/src/collections/blog/2022/2022-06-08-experience-lfx-pranav-singh/index.mdx @@ -17,8 +17,8 @@ published: true type: Blog --- -import { BlogWrapper } from "../../Blog.style.js"; -import { Link } from "gatsby"; + + @@ -30,7 +30,7 @@ more excited by the enthusiasm and energy of each community members welcoming me learned about the project through the demos/updates from fellow contributors. Slowly and gradually, I started contributing too, then delivering updates in the community calls, and consequently started climbing the contributor ladder. -When I realised that I would be working on [Layer5 Cloud](https://cloud.layer5.io) and Meshery as an LFX intern at Layer5, then I couldn't control my excitement. +When I realised that I would be working on [Layer5 Cloud](https://meshery.layer5.io) and Meshery as an LFX intern at Layer5, then I couldn't control my excitement. That excitement was to ship more impactful features for the Layer5 projects, work and engage more deeply with the engineering team at Layer5 and have an overall upliftment of my development skills. Throughout my internship I worked on several features. Few on the top of the list are as follows, expanding [Meshery extension points](https://docs.meshery.io/extensibility), exposing node details of the K8s clusters on which Meshery runs performance tests, diff --git a/src/collections/blog/2022/2022-06-09-evolution-of-mesheryctl-ref/index.mdx b/src/collections/blog/2022/2022-06-09-evolution-of-mesheryctl-ref/index.mdx index a0436152f35d..c43c4a0af36e 100644 --- a/src/collections/blog/2022/2022-06-09-evolution-of-mesheryctl-ref/index.mdx +++ b/src/collections/blog/2022/2022-06-09-evolution-of-mesheryctl-ref/index.mdx @@ -1,100 +1,102 @@ ---- -title: "Evolution of the Meshery CLI Command Reference" -date: 2022-06-09 01:15:00 -0600 -author: Aadhitya Amarendiran -description: Autogeneration of Meshery CLI command reference -thumbnail: ./mesheryctl.webp -darkthumbnail: ./mesheryctl.webp -category: "Meshery" -tags: - - Projects - - Meshery - - mesheryctl -published: true -resource: true -type: Blog -product: Meshery -featured: true ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import Blockquote from "../../../../reusecore/Blockquote"; - -import oldDesign from "./initial-design.webp"; -import newDesign from "./mesheryctl-docs.webp"; - - - -
      -

      Documentation plays a major role in any project. Even if the project is small or too big, the creator or the team behind the project needs to curate the documentation very well such that it'll be useful for new end users to refer and learn to use the project, troubleshoot the problems occurred and lot more. Thus, we, Layer5 have curated the documentation for Meshery to meet such purposes. Not to mention, mesheryctl, the CLI client of Meshery needs a curated documentation as well. This blog describes about the evolution of mesheryctl command reference page.

      -
      - -

      Initial Command Reference Design

      -

      The initial design of mesheryctl command reference page is all made using pure markdown and the functionality is handled using Jekyll, the main framework used for Meshery Docs. This handled great at initial stage but had many limitations, such as: -

        -
      • Updation of YAML for data is often required
      • -
      • Design was obselete at initial stage
      • -
      • No separate pages for each command and subcommand
      • -
      - Thus, the idea for redesigning the mesheryctl reference page was desperately needed.

      -

      - Initial design of mesheryctl command reference

      - -

      Updated Command Reference Design

      -

      To tackle the shortcomings of the previous design, I was tasked to redesign the mesheryctl command reference page entirely. This was a big task at first glance to me, as I was a new contributor back then. Eventually after manipulating the reference section with help of great folks, I was able to pull off the task and the design was updated.

      -

      - -Meshery CLI command reference -

      -

      The redesign work was done with help of HTML in markdown and with optimization in YAML code. A sample is given below.

      - -``` - - - - # mesheryctl mesh - - - ## Description - - {% assign name = site.data.mesheryctlcommands.cmds[page.command] %} - {{ name.description }} - - -
      -    
      - mesheryctl mesh [flags] -
      -
      - ........... -``` - -

      Adding auto generation feature in reference

      -

      As time passed, we realized that the command reference missed something for a while, though the design has been changed. Then, we thought the idea of automating the generation of docs such that developers don't need to change the code in docs section while working towards mesheryctl. That's where we got to know that Cobra library (the library for CLI apps made using golang) has a feature to make doc pages automatically. So we decided to incorporate that feature into mesheryctl docs page as well! After making several changes and a PR, I was finally able to introduce the feature in the docs site!

      - -``` -var startCmd = &cobra.Command { - Use: "start", - Short: "Start Meshery", - Long: `Start Meshery and each of its service mesh components.`, - Args: cobra.NoArgs, - Example: ` -// Start meshery -mesheryctl system start -// To create a new context for in-cluster Kubernetes deployments and set the new context as your current-context -mesheryctl system context create k8s -p kubernetes -s -// (optional) skip checking for new updates available in Meshery. -mesheryctl system start --skip-update -// Reset Meshery's configuration file to default settings. -mesheryctl system start --reset -// Silently create Meshery's configuration file with default settings -mesheryctl system start --yes -..... -} - `, -``` - -

      Using this information provided above in each golang file, the markdown page is generated using Cobra CLI library and thus reducing the workload on the developer by automating via GitHub Actions.

      -
      -

      This is so far on how the mesheryctl command reference is evolved for now. And I hope that it'll continue to evolve in the field of documentation to serve the users to use Meshery in best way possible.

      -
      +--- +title: "Evolution of the Meshery CLI Command Reference" +date: 2022-06-09 01:15:00 -0600 +author: Aadhitya Amarendiran +description: Autogeneration of Meshery CLI command reference +thumbnail: ./mesheryctl.webp +darkthumbnail: ./mesheryctl.webp +category: "Meshery" +tags: + - Projects + - Meshery + - mesheryctl +published: true +resource: true +type: Blog +product: Meshery +featured: true +--- + + + + +import oldDesign from "./initial-design.webp"; +import newDesign from "./mesheryctl-docs.webp"; + + + +
      +

      Documentation plays a major role in any project. Even if the project is small or too big, the creator or the team behind the project needs to curate the documentation very well such that it'll be useful for new end users to refer and learn to use the project, troubleshoot the problems occurred and lot more. Thus, we, Layer5 have curated the documentation for Meshery to meet such purposes. Not to mention, mesheryctl, the CLI client of Meshery needs a curated documentation as well. This blog describes about the evolution of mesheryctl command reference page.

      +
      + +

      Initial Command Reference Design

      +

      +The initial design of mesheryctl command reference page is all made using pure markdown and the functionality is handled using Jekyll, the main framework used for Meshery Docs. This handled great at initial stage but had many limitations, such as: +

        +
      • Updation of YAML for data is often required
      • +
      • Design was obselete at initial stage
      • +
      • No separate pages for each command and subcommand
      • +
      + Thus, the idea for redesigning the mesheryctl reference page was desperately needed. +

      +

      + Initial design of mesheryctl command reference

      + +

      Updated Command Reference Design

      +

      To tackle the shortcomings of the previous design, I was tasked to redesign the mesheryctl command reference page entirely. This was a big task at first glance to me, as I was a new contributor back then. Eventually after manipulating the reference section with help of great folks, I was able to pull off the task and the design was updated.

      +

      + +Meshery CLI command reference +

      +

      The redesign work was done with help of HTML in markdown and with optimization in YAML code. A sample is given below.

      + +``` + + + + # mesheryctl mesh + + + ## Description + + {% assign name = site.data.mesheryctlcommands.cmds[page.command] %} + {{ name.description }} + + +
      +    
      + mesheryctl mesh [flags] +
      +
      + ........... +``` + +

      Adding auto generation feature in reference

      +

      As time passed, we realized that the command reference missed something for a while, though the design has been changed. Then, we thought the idea of automating the generation of docs such that developers don't need to change the code in docs section while working towards mesheryctl. That's where we got to know that Cobra library (the library for CLI apps made using golang) has a feature to make doc pages automatically. So we decided to incorporate that feature into mesheryctl docs page as well! After making several changes and a PR, I was finally able to introduce the feature in the docs site!

      + +``` +var startCmd = &cobra.Command { + Use: "start", + Short: "Start Meshery", + Long: `Start Meshery and each of its service mesh components.`, + Args: cobra.NoArgs, + Example: ` +// Start meshery +mesheryctl system start +// To create a new context for in-cluster Kubernetes deployments and set the new context as your current-context +mesheryctl system context create k8s -p kubernetes -s +// (optional) skip checking for new updates available in Meshery. +mesheryctl system start --skip-update +// Reset Meshery's configuration file to default settings. +mesheryctl system start --reset +// Silently create Meshery's configuration file with default settings +mesheryctl system start --yes +..... +} + `, +``` + +

      Using this information provided above in each golang file, the markdown page is generated using Cobra CLI library and thus reducing the workload on the developer by automating via GitHub Actions.

      +
      +

      This is so far on how the mesheryctl command reference is evolved for now. And I hope that it'll continue to evolve in the field of documentation to serve the users to use Meshery in best way possible.

      +
      diff --git a/src/collections/blog/2022/2022-06-10-validation-meshery-cli-functionality/index.mdx b/src/collections/blog/2022/2022-06-10-validation-meshery-cli-functionality/index.mdx index 7ad7b73dad00..38eaa8714dff 100644 --- a/src/collections/blog/2022/2022-06-10-validation-meshery-cli-functionality/index.mdx +++ b/src/collections/blog/2022/2022-06-10-validation-meshery-cli-functionality/index.mdx @@ -1,58 +1,54 @@ ---- -title: "Validating Meshery CLI Functionality" -subtitle: "An introduction to testing mesheryctl" -date: 2022-06-10 10:30:05 -0530 -author: Piyush Singariya -description: Guide for End to End manual testing Meshery CLI (mesheryctl) -thumbnail: ./thumbnail.webp -darkthumbnail: ./thumbnail.webp -category: "Meshery" -tags: - - Projects - - Meshery - - mesheryctl -published: true -resource: true -type: Blog -product: Meshery ---- - -import { BlogWrapper } from "../../Blog.style.js"; - - - -

      Hola folks,

      -

      As a contributor, each of us is always striving hard in the ocean to open more and more pull-requests, but being a contributor just doesn't mean only raising PRs, it also means reviewing other PRs, pointing out mistakes, helping others in improving the code-quality/code-reusability/code-readability, helping in finding missing edge-cases that haven't been tackled yet, giving your opinions, writing LGTM, CITY helps nothing but just improving the confidence and engagement of the PR author.

      -

      So put on your Quality Tester hats because here I'll talk about how to test the PRs with the label component/mesheryctl i.e. pull-requests related to mesheryctl

      -

      Okay before we start, I'll like to tell you about GitHub CLI, it helps you checkout PRs very easily in your local system.

      -
        -
      1. The very first step is to review the PR, suggest changes if you think of any, ask queries, help the author to improve the code quality/readability/reusability, ask questions because asking helps you learn asking more better questions next time.

        -
      2. -
      3. PR authors either attach a video showcasing expected behavior or add written instructions about their fix under User Acceptance Behavior

        -
      4. -
      5. Now it's the time to checkout PR in your local system, we can check out any PR like this

        -
        gh pr checkout https://github.com/meshery/meshery/pull/4823
        -
        -
      6. -
      7. You can check if you're into the same branch as the PR author with

        -
        git branch
        -
        -
      8. -
      9. Well, if we're testing a PR related to mesheryctl, we need to build the binary from the same branch. change your directory to mesheryctl folder and run

        -
        make
        -
        -

        This will create a mesheryctl binary according to your OS in the same directory

        -
      10. -
      11. Now it's time to test out this newly built binary according to what's been tackled in the PR and related issues. For e.g. system start has some new functionality, make sure you followed the pull-request/linked-issue instruction for env setup, as sometimes fix/features are tackling an issue with a specific type of environment.

        -
      12. -
      -
      ./mesheryctl system start 
      -
      -

      the ./ helps us in using the newly built cli-binary present in the current directory which we built in 5th step

      -
        -
      1. make sure we have a similar experience as mentioned in the Video or the instructions added to the PR. but the wait is it okay to give green flags to the PR? not yet tbh. We as a tester should turn a little evil and think of the relevant situations/environments which might not have been tackled but should be(basically we're trying to break the new feature/fix)
      2. -
      3. After spending a good amount of time testing the new behaviors, old standard behaviors, new test cases, few edge cases. We can provide new insights to the PR author about the behavior in your system, depending on our experience we can ask the PR author to address our new queries, or we can appreciate the work, or give green flags to the PR.
      4. -
      -

      Wow, that was a ton of work there. well being a Tester is tough but very important before we merge pull requests. Every PR should be marked green with end-to-end testing before merging, we as a project are using GH Workflows to perform standard golang-testing but manual end-to-end testing completely removes margins of error.

      - -
      +--- +title: "Validating Meshery CLI Functionality" +subtitle: "An introduction to testing mesheryctl" +date: 2022-06-10 10:30:05 -0530 +author: Piyush Singariya +description: Guide for End to End manual testing Meshery CLI (mesheryctl) +thumbnail: ./thumbnail.webp +darkthumbnail: ./thumbnail.webp +category: "Meshery" +tags: + - Projects + - Meshery + - mesheryctl +published: true +resource: true +type: Blog +product: Meshery +--- + + + + + +

      Hola folks,

      +

      As a contributor, each of us is always striving hard in the ocean to open more and more pull-requests, but being a contributor just doesn't mean only raising PRs, it also means reviewing other PRs, pointing out mistakes, helping others in improving the code-quality/code-reusability/code-readability, helping in finding missing edge-cases that haven't been tackled yet, giving your opinions, writing LGTM, CITY helps nothing but just improving the confidence and engagement of the PR author.

      +

      So put on your Quality Tester hats because here I'll talk about how to test the PRs with the label component/mesheryctl i.e. pull-requests related to mesheryctl

      +

      Okay before we start, I'll like to tell you about GitHub CLI, it helps you checkout PRs very easily in your local system.

      +
        +
      1. The very first step is to review the PR, suggest changes if you think of any, ask queries, help the author to improve the code quality/readability/reusability, ask questions because asking helps you learn asking more better questions next time.

      2. +
      3. PR authors either attach a video showcasing expected behavior or add written instructions about their fix under User Acceptance Behavior

      4. +
      5. +

        Now it's the time to checkout PR in your local system, we can check out any PR like this

        +
        gh pr checkout https://github.com/meshery/meshery/pull/4823
        +
      6. +
      7. +

        You can check if you're into the same branch as the PR author with

        +
        git branch
        +
      8. +
      9. +

        Well, if we're testing a PR related to mesheryctl, we need to build the binary from the same branch. change your directory to mesheryctl folder and run

        +
        make
        +

        This will create a mesheryctl binary according to your OS in the same directory

        +
      10. +
      11. Now it's time to test out this newly built binary according to what's been tackled in the PR and related issues. For e.g. system start has some new functionality, make sure you followed the pull-request/linked-issue instruction for env setup, as sometimes fix/features are tackling an issue with a specific type of environment.

      12. +
      +
      ./mesheryctl system start 
      +

      the ./ helps us in using the newly built cli-binary present in the current directory which we built in 5th step

      +
        +
      1. make sure we have a similar experience as mentioned in the Video or the instructions added to the PR. but the wait is it okay to give green flags to the PR? not yet tbh. We as a tester should turn a little evil and think of the relevant situations/environments which might not have been tackled but should be(basically we're trying to break the new feature/fix)
      2. +
      3. After spending a good amount of time testing the new behaviors, old standard behaviors, new test cases, few edge cases. We can provide new insights to the PR author about the behavior in your system, depending on our experience we can ask the PR author to address our new queries, or we can appreciate the work, or give green flags to the PR.
      4. +
      +

      Wow, that was a ton of work there. well being a Tester is tough but very important before we merge pull requests. Every PR should be marked green with end-to-end testing before merging, we as a project are using GH Workflows to perform standard golang-testing but manual end-to-end testing completely removes margins of error.

      + +
      diff --git a/src/collections/blog/2022/2022-07-06-aaditya-gsoc-blogpost/index.mdx b/src/collections/blog/2022/2022-07-06-aaditya-gsoc-blogpost/index.mdx index ef07d3865cf0..ccc749bac707 100644 --- a/src/collections/blog/2022/2022-07-06-aaditya-gsoc-blogpost/index.mdx +++ b/src/collections/blog/2022/2022-07-06-aaditya-gsoc-blogpost/index.mdx @@ -1,55 +1,55 @@ ---- -title: "My Journey as a Contributor to GSoC Intern at Layer5" -subtitle: "Nothing but a magical experience" -date: 2022-07-06 08:00:00 -0630 -author: Aaditya Narayan Subedy -thumbnail: ./aaditya-subedy-layer5-intern.webp -darkthumbnail: ./aaditya-subedy-layer5-intern.webp -category: Programs -description: "Aaditya Narayan Subedy's journey from a Contributor at Layer5 to getting an GSoC internship at Layer5" -tags: - - Programs - - GSoC - - Internship -type: Blog -published: true ---- -import { Link } from "gatsby"; -import { BlogWrapper } from "../../Blog.style.js"; -import aadityaFirstPr from "./aaditya-first-pr.webp" -import aadityaPresenting from "./aaditya-presenting.webp" - - - - -### Early Interest in Coding -I had a strong interest in computers growing up. I used to find it fascinating how computer programs operate because they have such a tremendous impact on their users. This has always motivated me to work in the field of computers. - -As I grew up, I was introduced to a broad spectrum of coding languages that enabled us to make the software that we used on the computer. These languages piqued my interest even more. I started exploring and made projects. The more I understood them, the more interesting they got. Slowly I realized that I don’t want to make projects that satisfy just my needs. I want to build something that will be on the internet and will be used by people around the world. With this goal in my mind, I started exploring and hit a gemstone that is open source. I would be working on real-world programming solutions that will be used by people all around the world. This helped me to get started and got me excited about contributing to open source projects. - -### First PR at Layer5 -I still remember the first issue I worked on for Layer5 was the auto labeler on a pull request. I spotted a [good first issue](https://github.com/issues?q=is%3Aopen+is%3Aissue+archived%3Afalse+org%3Alayer5io+org%3Ameshery+org%3Aservice-mesh-performance+org%3Aservice-mesh-patterns+label%3A%22good+first+issue%22+) tag and expressed interest in working on it despite not knowing what the task was. The issue required knowledge of GitHub Actions, something I was unaware of at the time. After getting the issue assigned, I started researching what GitHub Actions were. I found out that these actions helped automate workflows to build, test, and deploy software. After getting the basics down, I checked if there were any existing GitHub Actions for the auto labeling of the PR. To my surprise, there were a couple of them. - -So before actually making a PR, I experimented with the actions extensively in my private repo. I remember making about 20-25 PR in my private repo to get the auto labeler working fine. After verifying that I got the desired results, I made a PR. I also got to discuss my approach in the [Meshery Development Call](https://layer5.io/community/calendar). I was so nervous at that time since that was the first meeting I attended where I had to make people understand what I did and the strategies I used. I was quite thrilled when my code got merged. I was enthralled to see that my code was working and being useful to the community. This motivated me to make more and more contributions. - -Aaditya's first PR merged - -### A Journey Never to forget - -My Layer5 journey began with this small issue. I gradually started learning more about the projects and made some impactful contributions. I started to engage in the community more prominently. With the help of these contributions, I learned new technologies and techniques. Contributing to the codebase gave me so much exposure to React.js, which would not have been possible if I had done it on my own. I took up issues that used React.js and started solving them, and in no time, I was comfortable with it. I am thankful that I didn’t wait for me to learn more about react and then start contributing. I have always applied this principle, learning more by doing actual stuff rather than sitting there and getting stuck in the tutorial loop. - -Another new technology I discovered was Jekyll, a static site generator. I was unfamiliar with this technology as well. I started contributing to issues involving Jekyll and slowly understood the basics and how the language works. I was very happy that I was able to make the [compatibility matrix](https://docs.meshery.io/project/compatibility-matrix), using Jekyll. Even my project for GSoC is written in Jekyll. So, going from not knowing what Jekyll is, to making some big changes, did make me happy. - -The community also helped me boost my confidence. The weekly meetings are responsible for this. The way the meetings required me to explain my fixes and give updates regarding the issues I was working on, helped me get vocal and comfortable with talking to various people. - -Aaditya Presenting - -I am excited to be accepted as a Google Summer of Code Intern for this Summer of 2022. I am looking forward to contributing more and making an impact here. The project assigned to me is to create a dashboard on SMP Website. Results from the [CNCF Cluster labs](https://github.com/layer5io/meshery-smp-action/actions) will be displayed here graphically. I wish to learn more about cloud native technologies and make contributions on the backend too. I also want to state that this will not be the end. I will be engaged with this community as long as I can and will try to give back as much as I can. - -### Appreciation for the Community - -Finally, I would like to thank the Layer5 Community for always being so supportive whenever I needed it. I took away a very significant lesson from this experience, there is always something to learn, and there is no harm in asking questions if you don't know the answer. It’s kinda hard to find such a welcoming community. There was not a day that I felt completely lost here, and that is what I adore about this community. - -Keep Meshing. Thank you. - - +--- +title: "My Journey as a Contributor to GSoC Intern at Layer5" +subtitle: "Nothing but a magical experience" +date: 2022-07-06 08:00:00 -0630 +author: Aaditya Narayan Subedy +thumbnail: ./aaditya-subedy-layer5-intern.webp +darkthumbnail: ./aaditya-subedy-layer5-intern.webp +category: Programs +description: "Aaditya Narayan Subedy's journey from a Contributor at Layer5 to getting an GSoC internship at Layer5" +tags: + - Programs + - GSoC + - Internship +type: Blog +published: true +--- + + +import aadityaFirstPr from "./aaditya-first-pr.webp" +import aadityaPresenting from "./aaditya-presenting.webp" + + + + +### Early Interest in Coding +I had a strong interest in computers growing up. I used to find it fascinating how computer programs operate because they have such a tremendous impact on their users. This has always motivated me to work in the field of computers. + +As I grew up, I was introduced to a broad spectrum of coding languages that enabled us to make the software that we used on the computer. These languages piqued my interest even more. I started exploring and made projects. The more I understood them, the more interesting they got. Slowly I realized that I don’t want to make projects that satisfy just my needs. I want to build something that will be on the internet and will be used by people around the world. With this goal in my mind, I started exploring and hit a gemstone that is open source. I would be working on real-world programming solutions that will be used by people all around the world. This helped me to get started and got me excited about contributing to open source projects. + +### First PR at Layer5 +I still remember the first issue I worked on for Layer5 was the auto labeler on a pull request. I spotted a [good first issue](https://github.com/issues?q=is%3Aopen+is%3Aissue+archived%3Afalse+org%3Alayer5io+org%3Ameshery+org%3Aservice-mesh-performance+org%3Aservice-mesh-patterns+label%3A%22good+first+issue%22+) tag and expressed interest in working on it despite not knowing what the task was. The issue required knowledge of GitHub Actions, something I was unaware of at the time. After getting the issue assigned, I started researching what GitHub Actions were. I found out that these actions helped automate workflows to build, test, and deploy software. After getting the basics down, I checked if there were any existing GitHub Actions for the auto labeling of the PR. To my surprise, there were a couple of them. + +So before actually making a PR, I experimented with the actions extensively in my private repo. I remember making about 20-25 PR in my private repo to get the auto labeler working fine. After verifying that I got the desired results, I made a PR. I also got to discuss my approach in the [Meshery Development Call](https://layer5.io/community/calendar). I was so nervous at that time since that was the first meeting I attended where I had to make people understand what I did and the strategies I used. I was quite thrilled when my code got merged. I was enthralled to see that my code was working and being useful to the community. This motivated me to make more and more contributions. + +Aaditya's first PR merged + +### A Journey Never to forget + +My Layer5 journey began with this small issue. I gradually started learning more about the projects and made some impactful contributions. I started to engage in the community more prominently. With the help of these contributions, I learned new technologies and techniques. Contributing to the codebase gave me so much exposure to React.js, which would not have been possible if I had done it on my own. I took up issues that used React.js and started solving them, and in no time, I was comfortable with it. I am thankful that I didn’t wait for me to learn more about react and then start contributing. I have always applied this principle, learning more by doing actual stuff rather than sitting there and getting stuck in the tutorial loop. + +Another new technology I discovered was Jekyll, a static site generator. I was unfamiliar with this technology as well. I started contributing to issues involving Jekyll and slowly understood the basics and how the language works. I was very happy that I was able to make the [compatibility matrix](https://docs.meshery.io/project/compatibility-matrix), using Jekyll. Even my project for GSoC is written in Jekyll. So, going from not knowing what Jekyll is, to making some big changes, did make me happy. + +The community also helped me boost my confidence. The weekly meetings are responsible for this. The way the meetings required me to explain my fixes and give updates regarding the issues I was working on, helped me get vocal and comfortable with talking to various people. + +Aaditya Presenting + +I am excited to be accepted as a Google Summer of Code Intern for this Summer of 2022. I am looking forward to contributing more and making an impact here. The project assigned to me is to create a dashboard on SMP Website. Results from the [CNCF Cluster labs](https://github.com/layer5io/meshery-smp-action/actions) will be displayed here graphically. I wish to learn more about cloud native technologies and make contributions on the backend too. I also want to state that this will not be the end. I will be engaged with this community as long as I can and will try to give back as much as I can. + +### Appreciation for the Community + +Finally, I would like to thank the Layer5 Community for always being so supportive whenever I needed it. I took away a very significant lesson from this experience, there is always something to learn, and there is no harm in asking questions if you don't know the answer. It’s kinda hard to find such a welcoming community. There was not a day that I felt completely lost here, and that is what I adore about this community. + +Keep Meshing. Thank you. + + diff --git a/src/collections/blog/2022/2022-07-07-deploy-meshery-on-aks/index.mdx b/src/collections/blog/2022/2022-07-07-deploy-meshery-on-aks/index.mdx index 76aa27dcdb3b..134a103db165 100644 --- a/src/collections/blog/2022/2022-07-07-deploy-meshery-on-aks/index.mdx +++ b/src/collections/blog/2022/2022-07-07-deploy-meshery-on-aks/index.mdx @@ -1,76 +1,76 @@ ---- -title: "How to deploy Meshery on AKS" -date: 2022-07-21 08:00:00 -0630 -author: Srinivas Karnati -category: "Meshery" -description: "How to deploy Meshery on Azure Kubernetes service(AKS)." -tags: - - Meshery - - Kubernetes -thumbnail: ./Meshery-on-AKS.webp -darkthumbnail: ./Meshery-on-AKS.webp -type: Blog -published: true -resource: true ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import mesheryui from "./mesheryui.webp"; - - - -
      -

      Meshery's goal is to make the operation of cloud native infrastructure and the service mesh layer of cloud simplified. Originally created by Layer5, Meshery is an open source project with hundreds of contributors world-wide and is actively maintained by engineers from Red Hat, VMware, Intel, Layer5 and others.

      -
      -

      Setup and run Meshery on AKS

      -

      The following instructions expects you to have an active Azure subscription, and Azure CLI installed on your system.

      -

      Spin up the AKS Cluster

      -

      Create the resource group (a logical group where all our resources will be deployed). The following command creates a resource group named MesheryGroup in southindia location.

      -
      
      -az group create --name MesheryGroup --location southindia
      -
      - -

      Create AKS cluster using az aks create. The following command creates aks cluster with a single node.

      - -
      
      -az aks create --resource-group MesheryGroup --name MesheryAKS --node-count 1 --generate-ssh-keys
      -
      -

      After a few minutes, the command completes and returns a JSON formatted information about the cluster.

      -

      You can connect with your cluster by using az aks get-credentials , which basically downloads credentials and configure the Kubernetes CLI.

      -
      
      -az aks get-credentials --resource-group MesheryGroup --name MesheryAKS
      -
      -

      Verify the connection to your cluster using the kubectl get command.

      -
      
      -$kubectl get nodes
      -
      -

      Install Meshery into your AKS cluster

      - -``` -helm repo add meshery https://meshery.io/charts/ - -helm install meshery meshery/meshery --namespace meshery --create-namespace - -``` -

      Meshery server supports customizing authentication flow callback URL, which can be configured in the following way.

      - -
      
      -helm install meshery meshery/meshery --namespace meshery --set env.MESHERY_SERVER_CALLBACK_URL=https://custom-host --create-namespace
      -
      -

      Port forward to Meshery UI

      - -``` -export POD_NAME=$(kubectl get pods --namespace meshery -l "app.kubernetes.io/name=meshery,app.kubernetes.io/instance=meshery" -o jsonpath="{.items[0].metadata.name}") - -$ kubectl --namespace meshery port-forward $POD_NAME 9081:8080 - -``` -

      Meshery should now be running in your AKS cluster and the Meshery UI should be accessible at the specified endpoint you’ve exposed to. Navigate to the meshery service endpoint to log into Meshery.

      - -
      Meshery UI Dashboard
      - -

      From here, your Meshery deployment on AKS is ready to use. In order to login to Meshery, authenticate with your chosen provider from the list.

      -

      There are different ways to configure a Meshery on AKS. Join the community and share your deployment’s configuration on the discussion forum today!

      - - -
      +--- +title: "How to deploy Meshery on AKS" +date: 2022-07-21 08:00:00 -0630 +author: Srinivas Karnati +category: "Meshery" +description: "How to deploy Meshery on Azure Kubernetes service(AKS)." +tags: + - Meshery + - Kubernetes +thumbnail: ./Meshery-on-AKS.webp +darkthumbnail: ./Meshery-on-AKS.webp +type: Blog +published: true +resource: true +--- + + +import mesheryui from "./mesheryui.webp"; + + + +
      +

      Meshery's goal is to make the operation of cloud native infrastructure and the service mesh layer of cloud simplified. Originally created by Layer5, Meshery is an open source project with hundreds of contributors world-wide and is actively maintained by engineers from Red Hat, VMware, Intel, Layer5 and others.

      +
      +

      Setup and run Meshery on AKS

      +

      The following instructions expects you to have an active Azure subscription, and Azure CLI installed on your system.

      +

      Spin up the AKS Cluster

      +

      Create the resource group (a logical group where all our resources will be deployed). The following command creates a resource group named MesheryGroup in southindia location.

      +
      
      +az group create --name MesheryGroup --location southindia
      +
      + +

      Create AKS cluster using az aks create. The following command creates aks cluster with a single node.

      + +
      
      +az aks create --resource-group MesheryGroup --name MesheryAKS --node-count 1 --generate-ssh-keys
      +
      +

      After a few minutes, the command completes and returns a JSON formatted information about the cluster.

      +

      You can connect with your cluster by using az aks get-credentials , which basically downloads credentials and configure the Kubernetes CLI.

      +
      
      +az aks get-credentials --resource-group MesheryGroup --name MesheryAKS
      +
      +

      Verify the connection to your cluster using the kubectl get command.

      +
      
      +$kubectl get nodes
      +
      +

      Install Meshery into your AKS cluster

      + +``` +helm repo add meshery https://meshery.io/charts/ + +helm install meshery meshery/meshery --namespace meshery --create-namespace + +``` +

      Meshery server supports customizing authentication flow callback URL, which can be configured in the following way.

      + +
      
      +helm install meshery meshery/meshery --namespace meshery --set env.MESHERY_SERVER_CALLBACK_URL=https://custom-host --create-namespace
      +
      +

      Port forward to Meshery UI

      + +``` +export POD_NAME=$(kubectl get pods --namespace meshery -l "app.kubernetes.io/name=meshery,app.kubernetes.io/instance=meshery" -o jsonpath="{.items[0].metadata.name}") + +$ kubectl --namespace meshery port-forward $POD_NAME 9081:8080 + +``` +

      Meshery should now be running in your AKS cluster and the Meshery UI should be accessible at the specified endpoint you’ve exposed to. Navigate to the meshery service endpoint to log into Meshery.

      + +
      Meshery UI Dashboard
      + +

      From here, your Meshery deployment on AKS is ready to use. In order to login to Meshery, authenticate with your chosen provider from the list.

      +

      There are different ways to configure a Meshery on AKS. Join the community and share your deployment’s configuration on the discussion forum today!

      + + +
      diff --git a/src/collections/blog/2022/2022-07-28-managing-multiple-clusters-with-meshery/index.mdx b/src/collections/blog/2022/2022-07-28-managing-multiple-clusters-with-meshery/index.mdx index 3e0fbe7cb9ae..1f45e0146fa6 100644 --- a/src/collections/blog/2022/2022-07-28-managing-multiple-clusters-with-meshery/index.mdx +++ b/src/collections/blog/2022/2022-07-28-managing-multiple-clusters-with-meshery/index.mdx @@ -1,110 +1,110 @@ ---- -title: Multi-Cluster Kubernetes Management with Meshery -subtitle: Wrangling your services one cluster at-a-time -date: 2022-07-28 08:00:00 -0630 -author: Ashish Tiwari -description: "Manage all of your Kubernetes clusters with the cloud native management plane, Meshery. Learn how Meshery makes connecting, discovering, and configuring multiple clusters a breeze." -thumbnail: ./multi-cluster-kubernetes-management-with-meshery.webp -darkthumbnail: ./multi-cluster-kubernetes-management-with-meshery.webp -category: "Meshery" -tags: - - Meshery - - Multi-cluster - - Kubernetes -type: Blog -featured: true -published: true ---- - -import { BlogWrapper } from "../../Blog.style.js"; -import Switcher from "./context-switcher.webp"; -import Deploy from "./deploy-modal.webp"; -import Cluster2 from "./meshmap-cluster2.webp"; -import Cluster1 from "./meshmap-cluster1.webp"; -import Settings from "./settings.webp"; -import Cluster from "./cluster-mgmt.webp"; -import Flush from "./flush-meshsync.webp"; -import CoreArch from "./meshery-core-architecture.webp"; -import { Link } from "gatsby"; - - - -
      -

      - From multi-mesh to now multi-cluster, Meshery is - continuously expanding its capability to give developers, operators, and - security engineers more control over their infrastructure. In this post, - we'll take a look behind the scenes at how each component in Meshery's - architecture plays a role in the management of many Kubernetes clusters. -

      -
      - -## Philosophy behind Meshery's multi-cluster management approach - -While designing Meshery for the world of many clouds, and many Kubernetes clusters, much care has been taken to ensure that Meshery is an extensible management platform, ready for handling new types of infrastructure and new use cases rapidly through its plugin model. Under the hood, Meshery Server acts as a delegator of operations by figuring out which Meshery Adapter registered its capability against the given operation. The operation is then sent to that given component (like one of Meshery’s adapters,e.g. Istio adapter) via a gRPC call. deploy modal When the operation involves a Kubernetes cluster(s), the kubeconfig(s) is sent as a parameter to the RPCs. It is then the job of the handling adapter to respect that and perform the operation across the passed clusters from kubeconfigs as needed. The operations not requiring a kubeconfig are managed through the same RPC, with the only difference being that the handling component would ignore the `kubeconfigs` field altogether making the system work not just for Kubernetes, but for other cloud native use cases. This approach of reusing the same RPC for different types of requests is pretty common and sometimes debatable with the other approach of being strict with the RPCs. This is what makes Meshery completely pluggable and extensible. - -## Using multi cluster with Meshery - -From a client's perspective, there are two uses of the multi context feature in general. While deploying a MeshMap design or performing any other operation on their cluster(s), selecting any number of Kubernetes contexts will allow them to uniformly and parallely perform the operation across the clusters. And while visualizing the state of their cluster(s), the same context switcher will allow them to filter across the clusters whose view they want to see. - -All cluster specific operations are now applied over a number of clusters uniformly. So if you have 10 clusters to manage and 8 of those start with the exact same set of pods, deployments, services, etc then Meshery can help you to apply these operations quickly and easily. - -It is as simple as selecting the specific cluster(s) from the Kubernetes context switcher in the navbar, and then applying whatever operation you wanted to, whether that be deploying a sample app, a Prometheus daemonset, or a MeshMap design. - -

      - context switcher -

      - -Just before applying the operation, you will be prompted with a confirmation modal which will provide the information about which cluster(s) that operation will be performed against. As the User interface improves, this same modal will also convey more useful information about the operation they are going to perform. - -

      - deploy modal -

      - -
      - -### Using MeshMap visualizer - -You can switch between views of your cluster in visualizer mode while using MeshMap. - -

      - visualizer showing data of context1 -

      -

      - visualizer showing data of context2 -

      - -### Managing Meshery on multiple clusters - -Users can perform cluster related operations from the settings page like adding more clusters, removing data from existing clusters and removing existing clusters. - -Settings page - -Meshery also deploys Meshery operator across the cluster it’s about to manage. This operator manages the lifecycle of a Meshery broker and MeshSync. MeshSync pumps the blood into Meshery’s core, in other words, it is responsible for watching all different types of resources by establishing a watch stream over each of them. MeshSync then pumps that data into the NATS server, of which Meshery server itself is a client. From there, Meshery server gets all the relevant data related to activities in the cluster. - -By default, Meshery wants to be as much aware about your infrastructure as possible to provide value so it deploys its operator across each detected cluster. But you can fine tune this configuration by going over each one of them from the table as shown. - -Kubernetes multi-cluster management with Meshery - -If you disconnect your cluster and do not want to persist the data from that cluster then you can perform a fine-grained deletion by deleting all MeshSync data (which are the Kubernetes objects) for that specific cluster. - -flushing MeshSync data -## Future of multi-cluster - -Meshery as an extension point to your infrastructure provides out-of-the-box value by adding components which can be Kubernetes specific, service mesh specific or custom components to add new functionality. We can now add multi-cluster specific components to provide more abstraction. This model can be used along with Meshery’s multi-mesh capabilities to give an overall multi-mesh multi-cluster experience to the user. For instance, your Istio service mesh spanning across multiple clusters can be abstracted and managed by Meshery using custom components such as VirtualGateway and VirtualDestinationRules. In this case, Meshery’s Istio adapter will handle the logic of converting a VirtualGateway into gateways across the clusters. This abstraction provides high value by powering the service mesh to span across the clusters while the Ops team can configure the mesh with minimal effort. - -Just like the example above, many such Meshery extension points are in Meshery to add logic into and add useful functionality. And as more of such extension points are added, Meshery will continue to give more and more power to your cloud native infrastructure. - -
      +--- +title: Multi-Cluster Kubernetes Management with Meshery +subtitle: Wrangling your services one cluster at-a-time +date: 2022-07-28 08:00:00 -0630 +author: Ashish Tiwari +description: "Manage all of your Kubernetes clusters with the cloud native management plane, Meshery. Learn how Meshery makes connecting, discovering, and configuring multiple clusters a breeze." +thumbnail: ./multi-cluster-kubernetes-management-with-meshery.webp +darkthumbnail: ./multi-cluster-kubernetes-management-with-meshery.webp +category: "Meshery" +tags: + - Meshery + - Multi-cluster + - Kubernetes +type: Blog +featured: true +published: true +--- + + +import Switcher from "./context-switcher.webp"; +import Deploy from "./deploy-modal.webp"; +import Cluster2 from "./meshmap-cluster2.webp"; +import Cluster1 from "./meshmap-cluster1.webp"; +import Settings from "./settings.webp"; +import Cluster from "./cluster-mgmt.webp"; +import Flush from "./flush-meshsync.webp"; +import CoreArch from "./meshery-core-architecture.webp"; + + + + +
      +

      + From multi-mesh to now multi-cluster, Meshery is + continuously expanding its capability to give developers, operators, and + security engineers more control over their infrastructure. In this post, + we'll take a look behind the scenes at how each component in Meshery's + architecture plays a role in the management of many Kubernetes clusters. +

      +
      + +## Philosophy behind Meshery's multi-cluster management approach + +While designing Meshery for the world of many clouds, and many Kubernetes clusters, much care has been taken to ensure that Meshery is an extensible management platform, ready for handling new types of infrastructure and new use cases rapidly through its plugin model. Under the hood, Meshery Server acts as a delegator of operations by figuring out which Meshery Adapter registered its capability against the given operation. The operation is then sent to that given component (like one of Meshery’s adapters,e.g. Istio adapter) via a gRPC call. deploy modal When the operation involves a Kubernetes cluster(s), the kubeconfig(s) is sent as a parameter to the RPCs. It is then the job of the handling adapter to respect that and perform the operation across the passed clusters from kubeconfigs as needed. The operations not requiring a kubeconfig are managed through the same RPC, with the only difference being that the handling component would ignore the `kubeconfigs` field altogether making the system work not just for Kubernetes, but for other cloud native use cases. This approach of reusing the same RPC for different types of requests is pretty common and sometimes debatable with the other approach of being strict with the RPCs. This is what makes Meshery completely pluggable and extensible. + +## Using multi cluster with Meshery + +From a client's perspective, there are two uses of the multi context feature in general. While deploying a MeshMap design or performing any other operation on their cluster(s), selecting any number of Kubernetes contexts will allow them to uniformly and parallely perform the operation across the clusters. And while visualizing the state of their cluster(s), the same context switcher will allow them to filter across the clusters whose view they want to see. + +All cluster specific operations are now applied over a number of clusters uniformly. So if you have 10 clusters to manage and 8 of those start with the exact same set of pods, deployments, services, etc then Meshery can help you to apply these operations quickly and easily. + +It is as simple as selecting the specific cluster(s) from the Kubernetes context switcher in the navbar, and then applying whatever operation you wanted to, whether that be deploying a sample app, a Prometheus daemonset, or a MeshMap design. + +

      + context switcher +

      + +Just before applying the operation, you will be prompted with a confirmation modal which will provide the information about which cluster(s) that operation will be performed against. As the User interface improves, this same modal will also convey more useful information about the operation they are going to perform. + +

      + deploy modal +

      + +
      + +### Using MeshMap visualizer + +You can switch between views of your cluster in visualizer mode while using MeshMap. + +

      + visualizer showing data of context1 +

      +

      + visualizer showing data of context2 +

      + +### Managing Meshery on multiple clusters + +Users can perform cluster related operations from the settings page like adding more clusters, removing data from existing clusters and removing existing clusters. + +Settings page + +Meshery also deploys Meshery operator across the cluster it’s about to manage. This operator manages the lifecycle of a Meshery broker and MeshSync. MeshSync pumps the blood into Meshery’s core, in other words, it is responsible for watching all different types of resources by establishing a watch stream over each of them. MeshSync then pumps that data into the NATS server, of which Meshery server itself is a client. From there, Meshery server gets all the relevant data related to activities in the cluster. + +By default, Meshery wants to be as much aware about your infrastructure as possible to provide value so it deploys its operator across each detected cluster. But you can fine tune this configuration by going over each one of them from the table as shown. + +Kubernetes multi-cluster management with Meshery + +If you disconnect your cluster and do not want to persist the data from that cluster then you can perform a fine-grained deletion by deleting all MeshSync data (which are the Kubernetes objects) for that specific cluster. + +flushing MeshSync data +## Future of multi-cluster + +Meshery as an extension point to your infrastructure provides out-of-the-box value by adding components which can be Kubernetes specific, service mesh specific or custom components to add new functionality. We can now add multi-cluster specific components to provide more abstraction. This model can be used along with Meshery’s multi-mesh capabilities to give an overall multi-mesh multi-cluster experience to the user. For instance, your Istio service mesh spanning across multiple clusters can be abstracted and managed by Meshery using custom components such as VirtualGateway and VirtualDestinationRules. In this case, Meshery’s Istio adapter will handle the logic of converting a VirtualGateway into gateways across the clusters. This abstraction provides high value by powering the service mesh to span across the clusters while the Ops team can configure the mesh with minimal effort. + +Just like the example above, many such Meshery extension points are in Meshery to add logic into and add useful functionality. And as more of such extension points are added, Meshery will continue to give more and more power to your cloud native infrastructure. + +
      diff --git a/src/collections/blog/2022/2022-10-19-kubeconna2022/index.mdx b/src/collections/blog/2022/2022-10-19-kubeconna2022/index.mdx index 2713019e9659..540c6d3de7b6 100644 --- a/src/collections/blog/2022/2022-10-19-kubeconna2022/index.mdx +++ b/src/collections/blog/2022/2022-10-19-kubeconna2022/index.mdx @@ -24,7 +24,7 @@ import Button from "../../../../reusecore/Button";

      Detroit welcomes the largest open-cloud and container-based developer events and workshops in the world. The event offers tutorials, keynotes, and networking opportunities across five days.

      -
      +

      As a longstanding CNCF member, Layer5 has donated two of its open source projects to the CNCF: Meshery and Service Mesh Performance. We're hosting project office hours where you can learn more about each of the projects, and meet the project maintainers.

      @@ -48,7 +48,7 @@ Join us as we host project office hours. Don't be shy with your questions! Proje
    • Dynamic Management UIs

    -

    +

    - -### Session: CNCF TAG Network - Intro & Deep Dive - -

    -“It’s the network!” is the cry of every engineer. With the increased prevalence of microservices and distributed systems, it’s true - networking as a discipline has never been more critical in the well-architected design and efficient operation of modern infrastructure. Join this talk for an intro to the TAG, its charter and a deeper discussion of current cloud native networking topics being advanced in this TAG. -

    - -
    -

    - Date: November 14, 2024
    - Time: 11:55am - 12:30pm MST -

    - -
    - -### Session: Contribfest - Meshery Contribfest: Extending the Cloud Native Manager - -

    -Join the Meshery maintainers and community in improving the leading cloud native management plane. This is your chance to get hands-on with the tools shaping the future of collaborative cloud native management. Opportunities: Work on core functionality in the Server (Golang) or UI (React) or extend Meshery by building your own plugin. Contribute to the Meshery documentation by incorporating your own examples of cloud native solution architectures using Meshery Designer. -

    -

    -Why Contribute to Meshery? - Gain experience with cloud native technologies, including essentially every CNCF project and open source development practices. As is the 10th fastest growing CNCF project, Meshery has a vibrant community. Work alongside passionate maintainers and contributors. No Prior Experience Needed: We welcome contributions from all levels of experience. Join us at Meshery Contribfest and be part of the growing community shaping the future of collaborative cloud native management. -

    - -
    -

    - Date: November 14, 2024
    - Time: 4:30pm - 6:00pm MST -

    -
    - - +{/* +