diff --git a/docs/features/github/_category_.json b/docs/features/github/_category_.json new file mode 100644 index 000000000..35ca77b0f --- /dev/null +++ b/docs/features/github/_category_.json @@ -0,0 +1,8 @@ +{ + "label": "GitHub", + "position": 6, + "collapsed": true, + "customProps": { + "image": "/img/icons/github-logo.svg" + } +} diff --git a/docs/features/github/index.mdx b/docs/features/github/index.mdx new file mode 100644 index 000000000..5b6146162 --- /dev/null +++ b/docs/features/github/index.mdx @@ -0,0 +1,32 @@ +--- +sidebar_position: 1 +title: GitHub | Overview +hide_table_of_contents: true +hide_title: true +--- + +import DocsLinkCard from "@site/src/components/LinkCard"; + +export const tutorials = [ + { + title: 'Automated Authorization Pull Requests', + description: 'Automatically create pull requests to resolve any drifts detected in your cluster', + url: '/features/github/tutorials/automated-pull-requests' + }, +]; + + +# GitHub + +Otterize can create just-in-time AWS IAM roles and policies for your workloads running on EKS Kubernetes clusters, greatly simplifying the lifecycle of managing IAM roles and policies. + +### Tutorials + +To learn how to leverage Otterize's continuous monitoring of your cluster's access to detect and resolve any drifts. + + +### How does Otterize work with GitHub? + +After installing Otterize in your cluster, it immediately begins monitoring both incoming and outgoing network traffic to your pods and the public internet via the network mapper feature (see Network Mapper for more details). Additionally, Otterize can track activity across various resources, including Postgres, AWS, Kafka, and more. This tracking helps Otterize create a detailed map of interactions and relationships. + +By leveraging ClientIntents, Otterize simplifies the application and enforcement of access rights, thereby enhancing cluster security. Once ClientIntents are defined and stored in a GitHub repository, Otterize compares these intended access patterns against actual usage within the cluster. Discrepancies trigger a pull request to update the ClientIntent definitions to reflect current usage. This process enables development teams to either accept the suggested changes or adjust them based on newly observed behaviors. \ No newline at end of file diff --git a/docs/features/github/reference.mdx b/docs/features/github/reference.mdx new file mode 100644 index 000000000..6e53dac6d --- /dev/null +++ b/docs/features/github/reference.mdx @@ -0,0 +1,30 @@ +--- +sidebar_position: 3 +title: Reference +--- + +## Triggers + +#### About + +Teams adopt various strategies for organizing their repositories, including creating separate repositories for individual clusters, namespaces, and services or using branches to represent different states of deployment. Triggers enhance this organizational flexibility, enabling you to tailor the mapping of your environment to your GitHub repositories according to your specific requirements. You can fine-tune the GitHub integration by configuring multiple triggers to align precisely with your needs. + +#### On Trigger + +The *On Trigger* configurations define the trigger’s scope, limiting it to only the specific contexts required to be monitored for changes. This allows targeted workflows, such as tracking changes in the *Staging* environment to prepare intents for an upcoming production release. + +| Item | Description | +|--------------|--------------------------------------------------------------| +| Clusters | Relates to a Kubernetes cluster integrated into Otterize. The names associated with the cluster are those provided during the integration. | +| Environments | One or more environments (testing, staging, production, etc.) are to be monitored for changes. Default is *All* | +| Namespaces | One or more Kubernetes namespaces to be monitored for changes. Default is *All* | +| Services | One or more Kubernetes Services to be monitored for changes. Default is *All* | +#### Open PR On + +The *Open PR On* definition associates the *On Trigger* scope to a specific repository, branch, and directory path in your repository. + +| Item | Description | +|--------------------|--------------------------------------------------------------| +| Repository | Refers to the owner and repository combination that uniquely identifies a repository in GitHub. For example, Otterizes network mapper would be supplied by `otterize/network-mapper` | +| Base branch | Base branch for most repositories is `main` or `master`. | +| ClientIntents path | The path from the repository root folder that contains the intent definition files. For instance: `/helm/intents/` | diff --git a/docs/features/github/tutorials/_category_.json b/docs/features/github/tutorials/_category_.json new file mode 100644 index 000000000..e04728744 --- /dev/null +++ b/docs/features/github/tutorials/_category_.json @@ -0,0 +1,5 @@ +{ + "label": "Tutorials", + "position": 1, + "collapsed": false +} diff --git a/docs/features/github/tutorials/automated-pull-requests.mdx b/docs/features/github/tutorials/automated-pull-requests.mdx new file mode 100644 index 000000000..18934eb11 --- /dev/null +++ b/docs/features/github/tutorials/automated-pull-requests.mdx @@ -0,0 +1,209 @@ +--- +sidebar_position: 1 +title: Automated Authorization Pull Requests +image: /img/quick-tutorials/github/social.png +--- + +Let’s learn how Otterize can integrate with your GitHub repository to automatically generate pull requests when your cluster’s access changes. + +In this tutorial, we will: + +- Deploy a sample cluster. +- Establish a repository for our pods’ ClientIntents. +- Integrate our new repository into Otterize Cloud and install Otterize’s GitHub app. +- Modify our cluster, thereby triggering Otterize to creating a pull request with the updated ClientIntents. + +## Prerequisites + +### CLI tools +We will need the following CLI tools to set up our repository and export our ClientIntents + +1. [Otterize CLI](https://docs.otterize.com/overview/installation#install-the-otterize-cli) +2. [Github CLI](https://cli.github.com). After installing please log in to an account capable of creating new repositories. + +### Install Otterize on your cluster +To deploy Otterize, head over to [Otterize Cloud](https://app.otterize.com/), and to integrate your cluster, navigate to the [Integrations Page](https://app.otterize.com/integrations) and follow the instructions. + +## Tutorial + +### Deploy a cluster + +The command below will set up the namespace we will use for our tutorial and deploy a sample cluster that simulates a fantasy tabletop game using several services to generate different aspects of the game. + +```yaml +kubectl apply -n otterize-tutorial-github -f ${ABSOLUTE_URL}/code-examples/github/all.yaml +``` +
+ View Deployment + +```yaml +{@include: ../../../../static/code-examples/github/all.yaml} +``` +
+ +Once deployed, we can see our network map on Otterize Cloud: + +visual graph of cluster deployment + + +### Export & apply our ClientIntents + +Now that our pods are deployed, we want to apply network access rules to our cluster using [ClientIntents](/reference/IBAC-Overview). Otterize can automatically generate these on our behalf based on the mapped network traffic. + +We can use the Otterize CLI tool to export the intent definitions. Note, these definitions are accessible within the Access Graph on Otterize Cloud. + +```bash +mkdir otterize-tutorial-github +cd otterize-tutorial-github +mkdir intents +otterize network-mapper export -n otterize-tutorial-github > ./intents/intents.yaml +``` +
+ View intents.yaml + +```yaml +apiVersion: k8s.otterize.com/v1alpha3 +kind: ClientIntents +metadata: + name: adventure + namespace: otterize-tutorial-github +spec: + service: + name: adventure + calls: + - name: character-generator + - name: monster-generator + - name: quest-generator + - name: treasure-generator +``` +
+ +Let’s secure our pods by applying these intents to our cluster: + +```bash +kubectl apply -n otterize-tutorial-github -f ./intents/intents.yaml +``` +We can see in the Access Graph that the pods are now protected: +visual graph of cluster deployment with protected edges + +### Create our repository + +To ensure teams have a versioned lasting record of the intents applied for our services, we should store them in a repository. Using the command below, we will create a new repository and push our intents into the code base. + +```bash +export GH_USER=$(gh api user | jq -r '.login') +gh repo create otterize-tutorial-github --private +git init +git add . +git commit -m "Initial Intents" +git branch -M main +git remote add origin https://github.com/$GH_USER/otterize-tutorial-github.git +git push -u origin main +``` + +Now that our intents are being version, we can integrate the repository into Otterize Cloud to detect any drifts in our pods needs. + +### Add our GitHub repository to Otterize Cloud + +To add the repository to Otterize Cloud, we head over to the [Integrations page](https://app.otterize.com/integrations) + +1. Click *Add Integration* +2. Select Integration Type: *GitHub* +3. Provide a name for the integration: *otterize-tutorial-github* +4. For *On Trigger*, select your Kubernetes cluster, and leave the other options set to the predefined defaults +5. For *Repository*, provide {owner name}/otterize-tutorial-github, replacing your specific user or organization name where you created the repository. +6. For the *Base Branch* option type in *main*. Other branches may be useful for long-held branches that identify “stagging,” “testing,” or other deployment states. +7. For *ClientIntents path*, we are looking for the directory within our repository that contains our existing intents. For this tutorial, it will be *intents/* +8. Next, Hit the *Add* button. This will redirect you to GitHub. From here, you’ll select the repository with the intent for your cluster. For our tutorial, that would be *otterize-tutorial-github* and click on *Install* + +Github App Install Example + +The Otterize GitHub app is now installed on your repository. Otterize will continuously look for differences between the ClientIntents definitions in your repository compared to the detected use in your cluster. As drifts are detected, pull requests will be open to update the intent definitions to incorporate the new usage behaviors. Let’s see how this works. + +You can learn more about configuring GitHub and how to use the Triggers on the [Reference page](/features/github/reference) + +### Update our cluster + +In the original deployment of our pods, our game simulation pod (“adventure”) utilized the *monster-generator* pod to fetch a random monster for our game. Now, our newly improved version of our monster generator is ready to be deployed. Let’s deploy it with the command deploy. + +```bash +kubectl apply -n otterize-tutorial-github -f ${ABSOLUTE_URL}/code-examples/github/all-v2.yaml +``` + +Once the pods are deployed, we can check the logs of our *adventure* pod using the command below to see that it’s now utilizing the new version of the monster generator. + +```bash +kubectl logs -f -n otterize-tutorial-github deploy/adventure +``` + +Example Log Output: + +``` +**************************************************** +Let another great adventure begin! +**************************************************** +Using MonsterV2 generated monster +Welcome to your adventure, Elf Wizard! +Your quest: Escort the Caravan +Beware, a wild Elephant appears! +The Elephant has 90 hit points, Our Elf has 244 points. +--------------------------------------------- +Elf lands a 19 point strike against the smelly Beast! +Elephant hits our strong Elf doing 20 point of damage. +The Elephant has 71 hit points, Our Elf has 224 points. +``` + +*monster-generator-v2* in Otterize Cloud Access Graph: + +visual graph of cluster deployment + +### View new pull request + +With our *adventure* pod calling *monster-generator-v2* the access for *adventure* has changed. We should see a new pull request if we visit the repository with our intent definitions and GitHub app integration. + +visual graph of cluster deployment + +Let’s merge the pull request, pull down the latest to our local copy, and apply the changes to our cluster. + +```bash +git pull +kubectl apply -n otterize-tutorial-github -f ./intents/intents.yaml +``` + +## Teardown + +To remove the deployed examples, run: + +```*bash* +kubectl delete namespace otterize-tutorial-github +``` + +You can remove the repository with the following command, provided you replace the `{owner name}` with appropriate owner : + +Note, that your API key might not have privileges to delete the repository, in which case you will need do so in the *Settings* section of your repository. + +```bash +gh repo delete {owner name}/otterize-tutorial-github +``` + +To remove the local files, run: + +```bash +cd .. +rm -rf otterize-tutorial-github +``` \ No newline at end of file diff --git a/docs/getting-started/README.mdx b/docs/getting-started/README.mdx index 2e6928edd..f5e1c3874 100644 --- a/docs/getting-started/README.mdx +++ b/docs/getting-started/README.mdx @@ -44,6 +44,11 @@ export const features = [ icon: '/img/icons/istio-no-word-mark.svg', url: '/features/istio/' }, + { + title: 'GitHub', + icon: '/img/icons/github-logo.svg', + url: '/features/github/' + }, ]; export const tutorials_access = [ diff --git a/static/code-examples/github/all-v2.yaml b/static/code-examples/github/all-v2.yaml new file mode 100644 index 000000000..9fba3ef05 --- /dev/null +++ b/static/code-examples/github/all-v2.yaml @@ -0,0 +1,190 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: otterize-tutorial-github +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: adventure +spec: + replicas: 1 + selector: + matchLabels: + app: adventure + template: + metadata: + labels: + app: adventure + spec: + containers: + - name: github-tutorial + image: otterize/github-tutorial:latest + args: ["./adventure"] +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: character-generator +spec: + selector: + matchLabels: + app: character-generator + template: + metadata: + labels: + app: character-generator + spec: + containers: + - name: github-tutorial + image: otterize/github-tutorial:latest + args: ["./character-generator"] + ports: + - containerPort: 8080 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: quest-generator +spec: + selector: + matchLabels: + app: quest-generator + template: + metadata: + labels: + app: quest-generator + spec: + containers: + - name: github-tutorial + image: otterize/github-tutorial:latest + args: ["./quest-generator"] + ports: + - containerPort: 8080 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: monster-generator +spec: + selector: + matchLabels: + app: monster-generator + template: + metadata: + labels: + app: monster-generator + spec: + containers: + - name: github-tutorial + image: otterize/github-tutorial:latest + args: ["./monster-generator"] + ports: + - containerPort: 8080 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: treasure-generator +spec: + selector: + matchLabels: + app: treasure-generator + template: + metadata: + labels: + app: treasure-generator + spec: + containers: + - name: github-tutorial + image: otterize/github-tutorial:latest + args: ["./treasure-generator"] + ports: + - containerPort: 8080 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: monster-generator-v2 +spec: + selector: + matchLabels: + app: monster-generator-v2 + template: + metadata: + labels: + app: monster-generator-v2 + spec: + containers: + - name: github-tutorial + image: otterize/github-tutorial:latest + args: ["./monster-generator-v2"] + ports: + - containerPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: treasure-generator +spec: + type: ClusterIP + selector: + app: treasure-generator + ports: + - name: http + port: 8080 + targetPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: character-generator +spec: + type: ClusterIP + selector: + app: character-generator + ports: + - name: http + port: 8080 + targetPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: monster-generator +spec: + type: ClusterIP + selector: + app: monster-generator + ports: + - name: http + port: 8080 + targetPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: quest-generator +spec: + type: ClusterIP + selector: + app: quest-generator + ports: + - name: http + port: 8080 + targetPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: monster-generator-v2 +spec: + type: ClusterIP + selector: + app: monster-generator-v2 + ports: + - name: http + port: 8080 + targetPort: 8080 +--- \ No newline at end of file diff --git a/static/code-examples/github/all.yaml b/static/code-examples/github/all.yaml new file mode 100644 index 000000000..8cd298f32 --- /dev/null +++ b/static/code-examples/github/all.yaml @@ -0,0 +1,157 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: otterize-tutorial-github +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: adventure +spec: + replicas: 1 + selector: + matchLabels: + app: adventure + template: + metadata: + labels: + app: adventure + spec: + containers: + - name: github-tutorial + image: otterize/github-tutorial:latest + args: ["./adventure"] +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: character-generator +spec: + selector: + matchLabels: + app: character-generator + template: + metadata: + labels: + app: character-generator + spec: + containers: + - name: github-tutorial + image: otterize/github-tutorial:latest + args: ["./character-generator"] + ports: + - containerPort: 8080 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: quest-generator +spec: + selector: + matchLabels: + app: quest-generator + template: + metadata: + labels: + app: quest-generator + spec: + containers: + - name: github-tutorial + image: otterize/github-tutorial:latest + args: ["./quest-generator"] + ports: + - containerPort: 8080 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: monster-generator +spec: + selector: + matchLabels: + app: monster-generator + template: + metadata: + labels: + app: monster-generator + spec: + containers: + - name: github-tutorial + image: otterize/github-tutorial:latest + args: ["./monster-generator"] + ports: + - containerPort: 8080 + +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: treasure-generator +spec: + selector: + matchLabels: + app: treasure-generator + template: + metadata: + labels: + app: treasure-generator + spec: + containers: + - name: github-tutorial + image: otterize/github-tutorial:latest + args: ["./treasure-generator"] + ports: + - containerPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: treasure-generator +spec: + type: ClusterIP + selector: + app: treasure-generator + ports: + - name: http + port: 8080 + targetPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: character-generator +spec: + type: ClusterIP + selector: + app: character-generator + ports: + - name: http + port: 8080 + targetPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: monster-generator +spec: + type: ClusterIP + selector: + app: monster-generator + ports: + - name: http + port: 8080 + targetPort: 8080 +--- +apiVersion: v1 +kind: Service +metadata: + name: quest-generator +spec: + type: ClusterIP + selector: + app: quest-generator + ports: + - name: http + port: 8080 + targetPort: 8080 +--- \ No newline at end of file diff --git a/static/img/icons/github-logo.svg b/static/img/icons/github-logo.svg new file mode 100644 index 000000000..a8d117404 --- /dev/null +++ b/static/img/icons/github-logo.svg @@ -0,0 +1,3 @@ + + + diff --git a/static/img/quick-tutorials/github/install-github-app.png b/static/img/quick-tutorials/github/install-github-app.png new file mode 100644 index 000000000..fa80f9b38 Binary files /dev/null and b/static/img/quick-tutorials/github/install-github-app.png differ diff --git a/static/img/quick-tutorials/github/pull-request.png b/static/img/quick-tutorials/github/pull-request.png new file mode 100644 index 000000000..b517399ee Binary files /dev/null and b/static/img/quick-tutorials/github/pull-request.png differ diff --git a/static/img/quick-tutorials/github/visual-graph-intents-applied.png b/static/img/quick-tutorials/github/visual-graph-intents-applied.png new file mode 100644 index 000000000..c23baf9bf Binary files /dev/null and b/static/img/quick-tutorials/github/visual-graph-intents-applied.png differ diff --git a/static/img/quick-tutorials/github/visual-graph-unsecure-deploy.png b/static/img/quick-tutorials/github/visual-graph-unsecure-deploy.png new file mode 100644 index 000000000..3303df35a Binary files /dev/null and b/static/img/quick-tutorials/github/visual-graph-unsecure-deploy.png differ diff --git a/static/img/quick-tutorials/github/visual-graph-updated-services.png b/static/img/quick-tutorials/github/visual-graph-updated-services.png new file mode 100644 index 000000000..d979c5a91 Binary files /dev/null and b/static/img/quick-tutorials/github/visual-graph-updated-services.png differ