<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Abdallah Abedraba</title>
    <description>The latest articles on DEV Community by Abdallah Abedraba (@aabedraba).</description>
    <link>https://dev.to/aabedraba</link>
    <image>
      <url>https://media2.dev.to/dynamic/image/width=90,height=90,fit=cover,gravity=auto,format=auto/https:%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Fuser%2Fprofile_image%2F820155%2F207d8ad7-7a01-4472-a389-b2849be4922e.png</url>
      <title>DEV Community: Abdallah Abedraba</title>
      <link>https://dev.to/aabedraba</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/aabedraba"/>
    <language>en</language>
    <item>
      <title>The Three Steps of Building Design-First APIs in Kubernetes</title>
      <dc:creator>Abdallah Abedraba</dc:creator>
      <pubDate>Tue, 13 Dec 2022 05:42:59 +0000</pubDate>
      <link>https://dev.to/kubeshop/the-three-steps-of-building-design-first-apis-in-kubernetes-4kf1</link>
      <guid>https://dev.to/kubeshop/the-three-steps-of-building-design-first-apis-in-kubernetes-4kf1</guid>
      <description>&lt;p&gt;Every time your organization needs to create a new API from scratch on Kubernetes, you’re faced with a decision: Are we going to create and follow a process to get this job done, or are we just going to stumble our way into a deployment that we hope gets the job done?&lt;/p&gt;

&lt;p&gt;If your organization  &lt;em&gt;is&lt;/em&gt;  mature enough to follow a process, which is a great first step, you also need to decide which route to go. There are a few popular approaches to API design and development, but we’re going to hone in on the  &lt;a href="https://kusk.io/blog/from-design-first-to-automated-deployment-with-openapi" rel="noopener noreferrer"&gt;design-first approach&lt;/a&gt;  because it means you’re generating the API’s specifications from the  &lt;em&gt;design of your API&lt;/em&gt;, not your code. It’s the best way to create APIs that are developer-friendly, go to market faster, and solve everyone’s problems the right way, the first time.&lt;/p&gt;

&lt;p&gt;There are big steps to get the job done.‍&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhikbsv392auo6iesxai2.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fhikbsv392auo6iesxai2.png" alt="determine, design, codify" width="800" height="559"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  1. Determine what business problem you’re trying to solve
&lt;/h2&gt;

&lt;p&gt;You start by getting the people from technical and business units in the same room (or Zoom call) together to discuss and iterate on how the API should work and validate the design decisions you’re making  &lt;em&gt;before&lt;/em&gt;  anyone even opens up an IDE.&lt;/p&gt;

&lt;p&gt;You’ll ask questions like:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  What do we need to get buy-in from customers, leadership, developers, QA testers, and IT operation?&lt;/li&gt;
&lt;li&gt;  What kinds of naming conventions or code quality guides should we enforce?&lt;/li&gt;
&lt;li&gt;  Which security, authentication, and authorization standards do we need?&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  2. Codify your API in a human- and machine-readable document
&lt;/h2&gt;

&lt;p&gt;Once you know exactly what your team is trying to accomplish, you can start translating the business requirements and goals into an API definition using  &lt;a href="https://www.openapis.org/" rel="noopener noreferrer"&gt;OpenAPI&lt;/a&gt;, which is the most broadly adopted specification for new APIs. The YAML syntax makes it approachable for technical and business folks alike.&lt;/p&gt;

&lt;p&gt;Your goal in this step is to convert your agreed-upon design into an OpenAPI definition, a single document that details exactly how the API works, like the path(s) it responds to, what structure and type those responses should be, what security schemes the API will need, what kind of validation is required, and more.&lt;/p&gt;

&lt;p&gt;In the end, this definition becomes your API contract: A single source of truth for how your API works on the frontend, backend, and from the end user’s perspective.&lt;/p&gt;

&lt;h2&gt;
  
  
  3. Convert the API design into code, tests, and other artifacts using generators… like Kusk!
&lt;/h2&gt;

&lt;p&gt;With your OpenAPI definition in Git, your teams can start writing client- and server-side code that meets those requirements. Or you can use other tools that convert your API into other valuable resources or knowledge:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;  With  &lt;a href="https://openapi-generator.tech/" rel="noopener noreferrer"&gt;openapi-generator&lt;/a&gt;, you can generate client- and server-side code in a variety of languages.&lt;/li&gt;
&lt;li&gt;  Tools like  &lt;a href="https://github.com/apideck-libraries/portman" rel="noopener noreferrer"&gt;portman&lt;/a&gt;  automatically create tests from your OpenAPI definition&lt;/li&gt;
&lt;li&gt;  Complete, up-to-date, and exhaustive documentation that can be generated with  &lt;a href="https://stoplight.io/open-source/elements" rel="noopener noreferrer"&gt;Stoplight Elements&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;  Security verification against known vulnerabilities and remediation advice using tools like  &lt;a href="https://42crunch.com/" rel="noopener noreferrer"&gt;42Crunch&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;And when it comes to taking an OpenAPI definition to a live Kubernetes deployment, there’s  &lt;a href="https://kusk.io/" rel="noopener noreferrer"&gt;Kusk&lt;/a&gt;, an API Gateway that helps you validate, deploy, and monitor your APIs using the open-source and much-loved  &lt;a href="https://www.envoyproxy.io/" rel="noopener noreferrer"&gt;Envoy Proxy&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;With Kusk, developers can annotate existing OpenAPI definitions to add any gateway-related configurations, like CORS rules, cache controls, rate limiting, and much more. Kusk automatically turns that under the hood into an Envoy Proxy configuration, plus the rest of the OpenAPI definition, into a functional gateway that can validate requests and consolidate your error handling.&lt;/p&gt;

&lt;p&gt;There’s more — once you’re using Kusk, your frontend developers can use gateway-level mocking to start building the end-user experience while their peers in the backend team work on implementing the API, getting your API to production way faster.&lt;/p&gt;

&lt;p&gt;Ready to build your next API with a design-first strategy?  &lt;a href="https://docs.kusk.io/getting-started/install-kusk-cli/" rel="noopener noreferrer"&gt;Install Kusk&lt;/a&gt;  and get involved on  &lt;a href="https://bit.ly/kubeshop-discord" rel="noopener noreferrer"&gt;Discord&lt;/a&gt;  to learn from others at this exciting intersection between OpenAPI and Kubernetes. The power of the API community awaits…!&lt;/p&gt;

</description>
      <category>api</category>
      <category>kubernetes</category>
      <category>openapi</category>
    </item>
    <item>
      <title>Kusk + Cloudentity - Fine-Grained Authorization for your APIs</title>
      <dc:creator>Abdallah Abedraba</dc:creator>
      <pubDate>Tue, 18 Oct 2022 04:48:37 +0000</pubDate>
      <link>https://dev.to/kubeshop/kusk-cloudentity-fine-grained-authorization-for-your-apis-1dd4</link>
      <guid>https://dev.to/kubeshop/kusk-cloudentity-fine-grained-authorization-for-your-apis-1dd4</guid>
      <description>&lt;p&gt;The Kusk team is glad to announce it has partnered with &lt;a href="https://cloudentity.com/" rel="noopener noreferrer"&gt;Cloudentity&lt;/a&gt;, an authorization-as-a-service platform, to enable users to leverage Cloudentity's robust centralized policy management and distributed Authorizer frameworks in combination with &lt;a href="https://kusk.io" rel="noopener noreferrer"&gt;Kusk's&lt;/a&gt; OpenAPI extensions.&lt;/p&gt;

&lt;p&gt;Security and infrastructure teams at organizations across the world rely on Cloudentity to keep their applications safe and secure. We're excited to join their team of trusted partners like Okta, Amazon Web Services (AWS), Azure, Google, and Axway.&lt;/p&gt;

&lt;p&gt;This is part of our main effort in helping companies create better and more resilient APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  OpenAPI for Open Standards
&lt;/h2&gt;

&lt;p&gt;Cloudentity embraces open standards and open-source in its journey to enable developers to implement scalable security from day one. Cloudentity users achieve security compliance faster and with less effort in ecosystems like Open Banking, which heavily rely on standards like OpenAPI.&lt;/p&gt;

&lt;p&gt;Kusk allows users to extend their OpenAPI definitions to include API gateway configuration rules so developers can have less complexity in their path to production. The configuration of the API gateway by use of OpenAPI enables developers to include features like response mocking and request body validation, among many others, out-of-the-box from day one.&lt;/p&gt;

&lt;h2&gt;
  
  
  Control the Authorization of APIs
&lt;/h2&gt;

&lt;p&gt;Kusk allows users to create their own authorization logic with &lt;a href="https://docs.kusk.io/guides/authentication/custom-auth-upstream" rel="noopener noreferrer"&gt;Custom Auth Upstreams&lt;/a&gt;. But dealing with authorization rules is complicated and doesn’t easily scale. &lt;/p&gt;

&lt;p&gt;With Cloudentity added as an authorizer to Kusk Gateway, API requests are now protected with rules that developers can create using Cloudentity’s &lt;a href="https://cloudentity.com/developers/howtos/access_policies/creating-cloudentity-policies-using-visual-editor/" rel="noopener noreferrer"&gt;Visual Policy Editor&lt;/a&gt; or &lt;a href="https://cloudentity.com/developers/howtos/access_policies/protecting-apps-using-open-policy-agent/" rel="noopener noreferrer"&gt;REGO policies&lt;/a&gt; built on Open Policy Agent. These rules are then orchestrated in Cloudentity allowing developers to tailor the authorization of their APIs easily and scale it at the same time their API grows.&lt;/p&gt;

&lt;p&gt;This is a great step for developers that use Kusk Gateway with their APIs, enabling more out-the-box working API self-service solutions, while still maintaining flexibility and control over the gateway in their Kubernetes clusters. &lt;/p&gt;

&lt;h2&gt;
  
  
  How does this integration work?
&lt;/h2&gt;

&lt;p&gt;To use Cloudentity as the authorizer of your API requests with Kusk Gateway, you need to add the &lt;code&gt;auth&lt;/code&gt; extension to your OpenAPI spec:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Kusk then configures the gateway to use a Cloudentity Authorizer that will filter requests using Cloudentity’s powerful and highly customizable authorization rules that API developers can create using Cloudentity’s platform. &lt;/p&gt;

&lt;p&gt;You can see the full instructions on how to use Cloudentity with Kusk in our &lt;a href="https://docs.kusk.io/guides/authentication/cloudentity" rel="noopener noreferrer"&gt;guides&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcusxukah2viadwht4t4.jpg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frcusxukah2viadwht4t4.jpg" alt="Kusk + Cloudentity" width="800" height="449"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it out now!
&lt;/h2&gt;

&lt;p&gt;We are very excited to add more integrations that enable our users to build great APIs. Check  on how to use Cloudentity with Kusk in our &lt;a href="https://docs.kusk.io/guides/authentication/cloudentity" rel="noopener noreferrer"&gt;guides&lt;/a&gt;. If you have any issues or questions about Kusk Gateway with Cloudentity, reach out to the team on the &lt;a href="https://discord.gg/6zupCZFQbe" rel="noopener noreferrer"&gt;Discord channel&lt;/a&gt; or open an issue in the GitHub &lt;a href="http://github.com/kubeshop/kusk-gateway" rel="noopener noreferrer"&gt;repository&lt;/a&gt;).&lt;/p&gt;

</description>
      <category>authorization</category>
      <category>openapi</category>
      <category>gateway</category>
    </item>
    <item>
      <title>Setup Ingress Controller with CORS configuration</title>
      <dc:creator>Abdallah Abedraba</dc:creator>
      <pubDate>Tue, 04 Oct 2022 16:43:48 +0000</pubDate>
      <link>https://dev.to/kubeshop/setup-ingress-controller-with-cors-configuration-10oc</link>
      <guid>https://dev.to/kubeshop/setup-ingress-controller-with-cors-configuration-10oc</guid>
      <description>&lt;p&gt;Configuring CORS in Kubernetes is not easy, let alone debugging issues with it. In a microservices architecture, leaving CORS to be managed by each backend could lead to non-standardized CORS rules throughout your APIs. So how can we solve these issues?&lt;/p&gt;

&lt;h2&gt;
  
  
  First things first, what is CORS?
&lt;/h2&gt;

&lt;p&gt;CORS is a mechanism implemented by browsers to ensure that requests are not sent to the server when the request is made by a domain the server does not expect to receive a request from (for example, malicious.com). &lt;/p&gt;

&lt;p&gt;It’s a security feature implemented for browsers mainly because when using CORS acts on the &lt;code&gt;Origin&lt;/code&gt; header of a request (which an attacker can easily set if they’re running the request outside of the browser), it’s no good for the server to protect against these types of requests. But, if the request is made through a browser, the &lt;code&gt;Origin&lt;/code&gt; header cannot be overridden by an attacker because the browser controls this header. So CORS becomes a browser’s responsibility as it’s the browser that should block the malicious requests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fakaiztasu5pmltqj8ucx.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fakaiztasu5pmltqj8ucx.png" alt=" " width="800" height="429"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  How to configure your Ingress Controller for CORS?
&lt;/h2&gt;

&lt;p&gt;For this example, we will be using &lt;a href="https://kusk.io/" rel="noopener noreferrer"&gt;Kusk Gateway&lt;/a&gt;, an open-source OpenAPI-driven Ingress Controller. The reasons we want to use Kusk Gateway is that firstly it simplifies the configuration of Envoy, a very sophisticated proxy, and it allows users to configure it using an &lt;a href="https://www.openapis.org/" rel="noopener noreferrer"&gt;OpenAPI definition&lt;/a&gt;, so the developers don’t need to learn yet another Kubernetes annotations (the case with Nginx Ingress for example), and they can &lt;a href="https://thenewstack.io/what-it-means-to-be-openapi-first-in-kubernetes/" rel="noopener noreferrer"&gt;leverage the OpenAPI ecosystem&lt;/a&gt; for code-generation, API mocking, testing, &lt;a href="https://openapi.tools/" rel="noopener noreferrer"&gt;and more&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Let’s see how that looks in practice. We will deploy a simple hello-world example.&lt;/p&gt;

&lt;h3&gt;
  
  
  1- Install Kusk in your Kubernetes cluster
&lt;/h3&gt;

&lt;p&gt;First, let’s install the Kusk CLI:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="c"&gt;# MacOS&lt;/span&gt;
brew &lt;span class="nb"&gt;install &lt;/span&gt;kubeshop/kusk/kusk

&lt;span class="c"&gt;# Linux&lt;/span&gt;
curl &lt;span class="nt"&gt;-sSLf&lt;/span&gt; https://raw.githubusercontent.com/kubeshop/kusk-gateway/main/cmd/kusk/scripts/install.sh | bash

&lt;span class="c"&gt;# Windows (go binary needed)&lt;/span&gt;
go &lt;span class="nb"&gt;install&lt;/span&gt; &lt;span class="nt"&gt;-x&lt;/span&gt; github.com/kubeshop/kusk-gateway/cmd/kusk@latest 
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;
&lt;p&gt;&lt;br&gt;
 &lt;br&gt;
Once the CLI is installed, proceed to install Kusk in your cluster:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kusk cluster &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  2- Deploy a sample application to your clusterYou can deploy this example application:
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl create deployment hello-world &lt;span class="nt"&gt;--image&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;kubeshop/kusk-hello-world:v1.0.0
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And we now wrap it in a service:&lt;br&gt;
&lt;br&gt;
 &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl expose deployment hello-world &lt;span class="nt"&gt;--type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;ClusterIP &lt;span class="nt"&gt;--port&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;8080
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  3- Configure your OpenAPI definition for Kusk
&lt;/h3&gt;

&lt;p&gt;Create a file &lt;code&gt;openapi.yaml&lt;/code&gt; with the following content: &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;As you can see this is a standard OpenAPI definition. This API exposes a single &lt;code&gt;/hello&lt;/code&gt; path. &lt;/p&gt;

&lt;p&gt;We also have the &lt;code&gt;x-kusk&lt;/code&gt; extension, this is a standard way to make annotations in OpenAPI, we’ve added there the CORS rules for our API and also the upstream details of the application we deployed in the first step.&lt;/p&gt;

&lt;h3&gt;
  
  
  4- Apply the changes to the cluster
&lt;/h3&gt;

&lt;p&gt;The following command will configure Kusk Gateway with the new rules:&lt;br&gt;
&lt;br&gt;
 &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kusk deploy &lt;span class="nt"&gt;-i&lt;/span&gt; openapi.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  5- Connect to Kusk Gateway
&lt;/h3&gt;

&lt;p&gt;One way of testing CORS rules is by trying to access the website from the browser through a different domain than the one we have defined in CORS. The other way of testing it is through the CLI with &lt;code&gt;curl&lt;/code&gt;. Let’s explore both.&lt;/p&gt;

&lt;p&gt;But first, let’s get the External IP of our Ingress Controller:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kusk ip
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  6- How to test CORS?
&lt;/h3&gt;

&lt;p&gt;As you’ve seen in the step earlier, we have configured CORS to expect requests from example.com and we will now make our requests from example.org to test that the requests are blocked.  &lt;/p&gt;

&lt;p&gt;Open &lt;a href="https://example.org" rel="noopener noreferrer"&gt;https://example.org&lt;/a&gt; in your browser, and access the developer console, then run the following Javascript snippet (make sure your change the EXTERNAL-IP):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kd"&gt;function&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nf"&gt;fetch&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="s2"&gt;http://EXTERNAL-IP/hello&lt;/span&gt;&lt;span class="dl"&gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;res&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;span class="p"&gt;})()&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Given that our CORS configuration expects requests from example.com and not example.org, the browser should fail the request with the following error:&lt;/p&gt;

&lt;p&gt;What is happening under the hood is that the browser makes a &lt;a href="https://developer.mozilla.org/en-US/docs/Glossary/Preflight_request" rel="noopener noreferrer"&gt;preflight request&lt;/a&gt; (a request before the actual request is made) which essentially asks the server for the origins that it expects to be called from. This happens by making an HTTP request using the &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Methods/OPTIONS" rel="noopener noreferrer"&gt;OPTIONS&lt;/a&gt; method. &lt;/p&gt;

&lt;p&gt;The server checks the origin header that the browser has set and it then can decide between either adding the &lt;code&gt;Access-Control-Allow-Origin: https://example.com\&lt;/code&gt; or not adding it. In case it’s not added (meaning the server does not recognize the origin it’s being called from), the browser blocks the actual request. &lt;/p&gt;

&lt;h2&gt;
  
  
  CORS through your Ingress Controller made easy
&lt;/h2&gt;

&lt;p&gt;With Kusk, it’s really easy to configure CORS in your APIs from a single place and using a standard like OpenAPI, which is essential for any modern REST API developer. &lt;/p&gt;

&lt;p&gt;Check out how to configure CORS, rate-limiting and authentication in your Ingress Controller in our &lt;a href="http://docs.kusk.io" rel="noopener noreferrer"&gt;guides&lt;/a&gt; and let us know about your experience in our &lt;a href="https://discord.gg/uNuhy6GDyn" rel="noopener noreferrer"&gt;Discord channel&lt;/a&gt;, and we are more than happy to see issues raised and PRs opened in our &lt;a href="https://github.com/kubeshop/kusk-gateway" rel="noopener noreferrer"&gt;Github repository&lt;/a&gt; :)&lt;/p&gt;

&lt;p&gt;Thank you for reading!&lt;/p&gt;

</description>
      <category>cors</category>
      <category>openapi</category>
      <category>api</category>
      <category>kubernetes</category>
    </item>
    <item>
      <title>Kusk v1.3 Release - Updated CLI and dashboard experience!</title>
      <dc:creator>Abdallah Abedraba</dc:creator>
      <pubDate>Tue, 04 Oct 2022 16:29:03 +0000</pubDate>
      <link>https://dev.to/kubeshop/kusk-v13-release-updated-cli-and-dashboard-experience-3lcf</link>
      <guid>https://dev.to/kubeshop/kusk-v13-release-updated-cli-and-dashboard-experience-3lcf</guid>
      <description>&lt;p&gt;The Kusk team is proud to announce the v1.3 release of Kusk Gateway, which adds OAuth support, mocking of the API directly from the CLI and improved developer experience of the CLI!&lt;/p&gt;

&lt;h2&gt;
  
  
  CLI improvements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;New &lt;code&gt;kusk deploy&lt;/code&gt; that allows you to deploy your OpenAPI definition to Kusk directly without needing to pipe it to &lt;code&gt;kubectl&lt;/code&gt;. It also adds a watched that looks for changes in your OpenAPI file and re-applies them to the LoadBalancer.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New &lt;code&gt;kusk ip&lt;/code&gt; command that returns the IP address of the default Kusk LoadBalancer so you can now pipe it to your favorite commands. &lt;code&gt;curl $(kusk ip)/api&lt;/code&gt;&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;&lt;code&gt;kusk install&lt;/code&gt; and &lt;code&gt;kusk upgrade&lt;/code&gt; have now moved to &lt;code&gt;kusk cluster install/upgrade&lt;/code&gt;. We have also removed the dependency on &lt;code&gt;helm&lt;/code&gt; and we install Kusk directly using &lt;code&gt;kubectl&lt;/code&gt; under-the-hood, this has vastly improved the speed of installation and upgrade of Kusk Gateway!&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;New &lt;code&gt;kusk cluster uninstall&lt;/code&gt; command that uninstalls Kusk and all of its components from your Kubernetes clusters.&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2&gt;
  
  
  Dashboard Overhaul
&lt;/h2&gt;

&lt;p&gt;We have redesigned Kusk Dashboard to make it easier to use and more familiar with the entire Kusk ecosystem. There are new guides and recommendations added that will help you navigate easier.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcze28zwg14e4h9jvm4xe.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fcze28zwg14e4h9jvm4xe.png" alt="Imrpoved Kusk dashboard" width="800" height="392"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Improved Documentation
&lt;/h2&gt;

&lt;p&gt;We’ve improved the experience and design of the documentation because we like amazing experiences everywhere 😎 Check out the new &lt;a href="https://docs.kusk.io" rel="noopener noreferrer"&gt;docs.kusk.io&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Try it out!
&lt;/h2&gt;

&lt;p&gt;Try and download the new version of Kusk &lt;a href="//docs.kusk.io/getting-started"&gt;here&lt;/a&gt;! If you have any questions or ideas please feel free to join our &lt;a href="https://discord.gg/uNuhy6GDyn" rel="noopener noreferrer"&gt;Discord server&lt;/a&gt; and get in touch. Kusk is fully open source, so you can always help us by starring the &lt;a href="https://github.com/kubeshop/kusk-gateway/" rel="noopener noreferrer"&gt;project on github&lt;/a&gt;, opening issues or a PR!&lt;/p&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

</description>
      <category>opensource</category>
      <category>openapi</category>
      <category>kubernetes</category>
      <category>ingress</category>
    </item>
    <item>
      <title>Kusk on the Road - Our September ‘22 Schedule</title>
      <dc:creator>Abdallah Abedraba</dc:creator>
      <pubDate>Thu, 08 Sep 2022 21:12:06 +0000</pubDate>
      <link>https://dev.to/kubeshop/kusk-on-the-road-our-september-22-schedule-gkm</link>
      <guid>https://dev.to/kubeshop/kusk-on-the-road-our-september-22-schedule-gkm</guid>
      <description>&lt;p&gt;The Kusk team is hitting the road to meet users and industry friends face-to-face across the US in September. &lt;/p&gt;

&lt;p&gt;We (&lt;a href="https://twitter.com/olensmar" rel="noopener noreferrer"&gt;Ole Lensmar&lt;/a&gt;, CTO of Kubeshop, &lt;a href="https://twitter.com/olensmar" rel="noopener noreferrer"&gt;Abdallah Abedraba&lt;/a&gt; Developer Advocate and &lt;a href="https://twitter.com/crjones" rel="noopener noreferrer"&gt;Christopher Jones&lt;/a&gt;, PM for Kusk) would like to say hi to you if you’re around the conferences from the list below, or just in the area of Michigan and San Francisco; to talk about APIs, and everything Kubernetes!&lt;/p&gt;

&lt;h1&gt;
  
  
  What are we doing in these conferences
&lt;/h1&gt;

&lt;p&gt;We will be discussing mainly about APIs, how to develop them in Kubernetes and great API development workflows!We will give presentations on scaling API teams and GitOps-ing APIs in Kubernetes.&lt;/p&gt;

&lt;h1&gt;
  
  
  Conferences we are attending
&lt;/h1&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://desertedisland.club/" rel="noopener noreferrer"&gt;Deserted Island DevOps Conf&lt;/a&gt; - Sept 14-15&lt;/strong&gt; Mackinac Island&lt;/p&gt;

&lt;p&gt;&lt;a href="https://desertedisland.club/agenda" rel="noopener noreferrer"&gt;Can You GitOps Your API?&lt;/a&gt; - Sept 14 | 11am ET | Abdallah Abedraba&lt;/p&gt;

&lt;p&gt;Description of the presentation:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;”One of the major trends in contemporary cloud-native application development is the adoption of GitOps; managing the state of your Kubernetes cluster(s) in Git - with all the bells and whistles provided by modern Git platforms like GitHub and GitLab in the regards to workflows, auditing, security, tooling, etc.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;Let’s dive into how your teams can leverage it for a faster and safer road to production!”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://events.linuxfoundation.org/openapi-asc/" rel="noopener noreferrer"&gt;API Specification Conference&lt;/a&gt; - Sept 19-21&lt;/strong&gt;&lt;br&gt;
San Francisco&lt;br&gt;
&lt;a href="https://asc2022api.sched.com/event/15pWO" rel="noopener noreferrer"&gt;Key Note - Retrospective Panel&lt;/a&gt; - Wed Sept 21&lt;/p&gt;

&lt;p&gt;Presentation -  Boosting your Kubernetes API development workflows with OpenAPI | Sept 19 | Virtual Session&lt;/p&gt;

&lt;p&gt;Description of the presentation:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;”Achieving a productive workflow for API development under Kubernetes is a challenge, especially for developers who are new to Kubernetes and related constructs like manifests, Ingress controllers, GitOps, etc. Adopting an OpenAPI-centric approach to API development can bring many benefits in this regard; the metadata contained in OpenAPI can be used to automate many of the tasks related to building and deploying APIs to Kubernetes - both in manual and CI/CD workflows - helping your team to keep up the pace while transitioning to Kubernetes.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;This talk will show you how to leverage OpenAPI to accelerate your API development workflow for Kubernetes. Both design-first and code-first approaches are covered, with both manual and automated CI/CD/GitOps processes.”&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.apidays.global/australia/" rel="noopener noreferrer"&gt;API Days Australia&lt;/a&gt; - Sept 14-15&lt;/strong&gt; Online&lt;/p&gt;

&lt;p&gt;Scale Your API teams with a Design-First Approach | Sept 14&lt;/p&gt;

&lt;p&gt;Description of the presentation:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;“Kubernetes scales APIs from a workload perspective, but teams have a long way to go to find a good workflow that includes simplifying development, prototyping, iteration, stakeholder collaboration, and much more.&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;&lt;em&gt;In this talk, we will explore how Kusk Gateway helps bridge the gap of a productive API workflow in Kubernetes with APIOps and OpenAPI at its core.”&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Come talk to us
&lt;/h2&gt;

&lt;p&gt;We having a booth at API Specification Conference, where will be more than happy to talk to you about:- Adopting API-first approach in your development teams- Achieving a productive API workflow in Kubernetes- Creating a robust API experience starting from the gateway all the way back to the microservices&lt;/p&gt;

&lt;p&gt;Can’t wait to meet you there!&lt;/p&gt;

</description>
      <category>conference</category>
      <category>techtalks</category>
    </item>
    <item>
      <title>Kusk Gateway 1.2.0 Release - OAuth, Local Mocking and more!</title>
      <dc:creator>Abdallah Abedraba</dc:creator>
      <pubDate>Thu, 08 Sep 2022 08:36:55 +0000</pubDate>
      <link>https://dev.to/kubeshop/kusk-gateway-120-release-oauth-local-mocking-and-more-2gdn</link>
      <guid>https://dev.to/kubeshop/kusk-gateway-120-release-oauth-local-mocking-and-more-2gdn</guid>
      <description>&lt;h1&gt;
  
  
  Intro
&lt;/h1&gt;

&lt;p&gt;The Kusk team is proud to announce the v1.2.0 release of Kusk Gateway! For the unfamiliar, what makes &lt;a href="https://kubeshop.github.io/kusk-gateway/" rel="noopener noreferrer"&gt;Kusk Gateway&lt;/a&gt; unique is that it uses the ubiquitous OpenAPI specification file as a single source of truth for making an API available to consumers, which includes routing configuration, request validation, timeouts, etc. &lt;/p&gt;

&lt;p&gt;Kusk will especially resonate with developers and teams like ours, who have adopted a design-first approach to API development.&lt;/p&gt;

&lt;p&gt;Thanks to Kusk Gateway and industry-standard OpenAPI (f.k.a Swagger), you can quickly publish your APIs deployed in Kubernetes without having to add any additional configuration resources, which plays nicely with both manual and automated/GitOps-based development workflows. Kusk Gateway enables you to design and deploy your APIs from a single OpenAPI definition, allowing you to:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Rapidly prototype your REST APIs&lt;/strong&gt; by mocking your API responses, allowing your teams to instantly start building on top of your APIs without your services being implemented&lt;/li&gt;
&lt;li&gt;Protect your endpoints with &lt;strong&gt;automatic request and response validations&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Configure critical policies like authentication and CORS with &lt;strong&gt;no coding required&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;Centrally control your APIs from an Open Source dashboard&lt;/li&gt;
&lt;li&gt;Enable &lt;strong&gt;automation of the entire deployment process of your API&lt;/strong&gt; without requiring manual DevOps intervention&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  What’s new?
&lt;/h1&gt;

&lt;p&gt;Since the 1.1.0 release we have been focusing on making the core of Kusk Gateway production ready - but have also managed to squeeze in some new functionality.&lt;/p&gt;

&lt;h2&gt;
  
  
  OAuth Authentication (Experimental)
&lt;/h2&gt;

&lt;p&gt;OAuth2 ensures that your applications (upstreams) don’t get requests which are not authenticated and authorized. It effectively helps to protect your API. Kusk now allows you to add simple configuration and use it with your favorite auth provider, taking away the headache of setting up complex OAuth flows. &lt;/p&gt;

&lt;p&gt;Learn more about implementing OAuth in Kusk at &lt;a href="https://docs.kusk.io/guides/oauth2" rel="noopener noreferrer"&gt;https://docs.kusk.io/guides/oauth2&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Local auto-mocking from schema 
&lt;/h2&gt;

&lt;p&gt;Spin up a local mocking server that generates responses from your content schema or returns your defined examples. No need to have Kusk running in a cluster anymore to take advantage of OpenAPI mocking!&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kusk mock &lt;span class="nt"&gt;-i&lt;/span&gt; &amp;lt;path to openapi file&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Learn more at &lt;a href="https://docs.kusk.io/reference/cli/mock-cmd" rel="noopener noreferrer"&gt;https://docs.kusk.io/reference/cli/mock-cmd&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Public OpenAPI Path
&lt;/h2&gt;

&lt;p&gt;The &lt;code&gt;openapi-path&lt;/code&gt; field takes a path name and will expose your OpenAPI definition in the defined path.&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight yaml"&gt;&lt;code&gt;&lt;span class="na"&gt;...x-kusk: openapi-path&lt;/span&gt;&lt;span class="pi"&gt;:&lt;/span&gt; &lt;span class="s"&gt;openapi.json...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will expose your entire OpenAPI definition, without the Kusk extensions, on yourdomain.com/openapi.json.&lt;/p&gt;

&lt;h2&gt;
  
  
  ARM64 support
&lt;/h2&gt;

&lt;p&gt;Kusk Gateway now supports being deployed to clusters running on ARM64.&lt;/p&gt;

&lt;h2&gt;
  
  
  Misc Enhancements
&lt;/h2&gt;

&lt;ul&gt;
&lt;li&gt;Improved CLI developer experience&lt;/li&gt;
&lt;li&gt;Authentication now happens before Mocking to allow for use of both polcies together.&lt;/li&gt;
&lt;li&gt;Ability to disable telemetry during installation&lt;/li&gt;
&lt;li&gt;Improving overall experience with developing Restful APIs&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  The roadmap post 1.2.0
&lt;/h1&gt;

&lt;p&gt;The main areas for improvement we are planning after this 1.2.0 release include:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Upgraded Envoy to the newest version 1.23.0&lt;/li&gt;
&lt;li&gt;Onboarding and Help improvements, especially on the CLI&lt;/li&gt;
&lt;li&gt;An new and improved Dashboard experience- Packaging for APT, Chocolatey and an improved Brew experience&lt;/li&gt;
&lt;li&gt;Hot Deploy (Deploy to a target from the CLI when the OpenAPI spec file changes)&lt;/li&gt;
&lt;li&gt;… and more enhancements and bug fixes.For more about future enhancements, you’re welcome to check out the &lt;a href="https://github.com/kubeshop/kusk-gateway/milestone/9" rel="noopener noreferrer"&gt;1.3.0 Release project on GitHub&lt;/a&gt; to see how things are going, don’t hesitate to jump in with comments, suggestions or a Pull Request!&lt;/li&gt;
&lt;/ul&gt;

&lt;h1&gt;
  
  
  Try it out!
&lt;/h1&gt;

&lt;p&gt;Head over to the &lt;a href="https://github.com/kubeshop/kusk-gateway" rel="noopener noreferrer"&gt;Kusk Gateway GitHub repository&lt;/a&gt; to download the &lt;a href="https://github.com/kubeshop/kusk-gateway/releases" rel="noopener noreferrer"&gt;latest release&lt;/a&gt; - installation instructions and documentation are &lt;a href="https://docs.kusk.io" rel="noopener noreferrer"&gt;available there as well&lt;/a&gt;. If you have any questions or ideas please feel free to join our &lt;a href="https://discord.gg/uNuhy6GDyn" rel="noopener noreferrer"&gt;Discord server&lt;/a&gt; and get in touch.&lt;/p&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

</description>
      <category>api</category>
      <category>kubernetes</category>
      <category>gateway</category>
      <category>openapi</category>
    </item>
    <item>
      <title>Rapidly prototype your APIs on Kubernetes with Kusk Gateway</title>
      <dc:creator>Abdallah Abedraba</dc:creator>
      <pubDate>Sun, 26 Jun 2022 12:09:20 +0000</pubDate>
      <link>https://dev.to/kubeshop/rapidly-prototype-your-apis-on-kubernetes-with-kusk-gateway-4757</link>
      <guid>https://dev.to/kubeshop/rapidly-prototype-your-apis-on-kubernetes-with-kusk-gateway-4757</guid>
      <description>&lt;p&gt;&lt;a href="https://www.openapis.org/" rel="noopener noreferrer"&gt;OpenAPI&lt;/a&gt; (f.k.a Swagger) has introduced a set of standardized specifications for REST APIs that, among many things, allows producers and consumers of APIs to work together in designing an API before even writing a single line of code!&lt;/p&gt;

&lt;p&gt;This design-first approach has improved the experience of API developers by giving them the opportunity to use tools like &lt;a href="https://openapi-generator.tech/" rel="noopener noreferrer"&gt;OpenAPI generator&lt;/a&gt; which takes an OpenAPI definition and generates scaffolding code for backenders, making the development of APIs much faster. &lt;/p&gt;

&lt;p&gt;But consumers of APIs still didn’t have a way of really taking advantage of this design-first approach as they still depended on the backend teams to implement and deploy APIs.&lt;/p&gt;

&lt;h3&gt;
  
  
  How could consumers of APIs then take advantage of OpenAPI and the design-first approach? By making the API gateway aware of the OpenAPI definition. Let me explain how!
&lt;/h3&gt;

&lt;p&gt;An API gateway sits in front of your microservices routing incoming traffic that your Kubernetes cluster receives to the corresponding microservice. By having the API gateway be aware of your OpenAPI definition it can then see what a response would look like and generate a mock (or fake) response for the consumers instead.&lt;/p&gt;

&lt;p&gt;This approach would allow API consumers to start using the API with mocked results and meanwhile (in parallel!) the backend team can start implementing the actual API; it essentially loses the dependency between consumer and producer teams and allows for quicker prototyping of the API. With no code whatsoever, just your run-of-the-mill OpenAPI definition. &lt;/p&gt;

&lt;p&gt;In this tutorial, you will learn how to use &lt;a href="https://github.com/kubeshop/kusk-gateway" rel="noopener noreferrer"&gt;Kusk Gateway&lt;/a&gt;, an open-source OpenAPI-driven API gateway, to enable this rapid prototyping development! Let’s make a simple example of how to achieve this:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgxyz3qqc4jm6qr830zuq.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fgxyz3qqc4jm6qr830zuq.png" alt="Schema of using OpenAPI and Kusk Gateway" width="800" height="469"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Walkthrough
&lt;/h2&gt;

&lt;h3&gt;
  
  
  1. Install Kusk Gateway CLI
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;brew &lt;span class="nb"&gt;install &lt;/span&gt;kubeshop/kusk/kusk
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;For other installation methods, check the &lt;a href="https://kubeshop.github.io/kusk-gateway/cli/overview/" rel="noopener noreferrer"&gt;installation docs&lt;/a&gt;.&lt;/p&gt;
&lt;h3&gt;
  
  
  2. Install Kusk Gateway in your Kubernetes cluster
&lt;/h3&gt;


&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kusk &lt;span class="nb"&gt;install&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  3. Create an OpenAPI definitionCreate the file &lt;code&gt;openapi.yaml&lt;/code&gt; with the content:
&lt;/h3&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;This is a simple common OpenAPI definition for a single &lt;code&gt;/hello&lt;/code&gt; route that accepts a GET method. There are a couple of important details here: &lt;/p&gt;

&lt;h4&gt;
  
  
  1. The &lt;code&gt;x-kusk&lt;/code&gt; extension 
&lt;/h4&gt;

&lt;p&gt;This section is an extension to the OpenAPI specification. We use it to configure Kusk Gateway to enable in this case CORS access and mocking of the API. This approach makes OpenAPI the definition of your API &lt;em&gt;and&lt;/em&gt; your gateway configuration(!) essentially having a single source of truth. &lt;/p&gt;

&lt;h4&gt;
  
  
  2. The &lt;code&gt;example&lt;/code&gt; field
&lt;/h4&gt;

&lt;p&gt;To allow Kusk Gateway to generate mock responses, you'll need to define examples of your responses under OpenAPI's &lt;code&gt;example&lt;/code&gt; field. In this case we have an example message "Hello from a mocked response!". &lt;/p&gt;

&lt;h3&gt;
  
  
  4. Apply the API configuration to the cluster
&lt;/h3&gt;



&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kusk api generate &lt;span class="nt"&gt;-i&lt;/span&gt; openapi.yaml &lt;span class="nt"&gt;--envoyfleet&lt;/span&gt;.name kusk-gateway-envoy-fleet | kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; -
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;This applies the configuration to the gateway and deploys the API. &lt;/p&gt;
&lt;h3&gt;
  
  
  5. Test your mocked API
&lt;/h3&gt;

&lt;p&gt;Now you are ready to test the API and build against mocked responses!&lt;/p&gt;

&lt;p&gt;First, you need to get the External IP of the gateway, i.e. the entry point of your APIs. For that run:&lt;br&gt;
&lt;br&gt;
 &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get &lt;span class="nt"&gt;-n&lt;/span&gt; kusk-system svc/kusk-gateway-envoy-fleet
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Note: if you're running a local cluster with Minikube, the ExternalIP might be in pending state; in case it is, you can port-forward to the gateway by running &lt;code&gt;kubectl port-forward -n kusk-system svc/kusk-gateway-envoy-fleet 8080:80&lt;/code&gt;, so your external IP becomes &lt;code&gt;localhost:8080&lt;/code&gt;. &lt;/p&gt;

&lt;p&gt;And now test the &lt;code&gt;/hello&lt;/code&gt; path:&lt;br&gt;
&lt;br&gt;
 &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nv"&gt;$EXTERNAL_IP&lt;/span&gt;/hello&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"message"&lt;/span&gt;: &lt;span class="s2"&gt;"Hello from a mocked response!"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And that's it! You can see that this is the same response that was defined in our OpenAPI definition. Now your API consumer teams can already start working with the mocked API!&lt;/p&gt;

&lt;p&gt;Once the API team has implemented the service, you will stop mocking your endpoint and connect it to a microservice in your cluster. That's what we'll cover in the next sections.&lt;/p&gt;
&lt;h3&gt;
  
  
  6. Deploy your application to the cluster
&lt;/h3&gt;

&lt;p&gt;Deploy this example application that we will connect with the API gateway:&lt;br&gt;
&lt;br&gt;
 &lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; https://gist.githubusercontent.com/aabedraba/e9e7a48c7bc48386f4dadd0d9fe3b7df/raw/9048bcae0675dade44a2cd4b091e752acafaf960/hello-kubernetes.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;

&lt;h3&gt;
  
  
  7. Connect your application to Kusk Gateway
&lt;/h3&gt;

&lt;p&gt;Now, you will need to disable the mocking for your API and connect the upstream. Update your &lt;code&gt;openapi.yaml&lt;/code&gt; file with the following changes:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;h3&gt;
  
  
  8. Test your implemented application
&lt;/h3&gt;

&lt;p&gt;With the same External IP from step 5, run&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;curl &lt;span class="nv"&gt;$EXTERNAL_IP&lt;/span&gt;/hello&lt;span class="o"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;"message"&lt;/span&gt;: &lt;span class="s2"&gt;"Hello from an implemented service!"&lt;/span&gt;&lt;span class="o"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Voilá! You've just implemented and connected a service to your gateway!&lt;/p&gt;

&lt;p&gt;You can find the code for the article &lt;a href="https://github.com/aabedraba/kusk-examples/tree/main/rapid-prototype" rel="noopener noreferrer"&gt;on Github&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Conclusions
&lt;/h2&gt;

&lt;p&gt;Kusk Gateway enabled you to take advantage of OpenAPI and a design-first approach to allow your teams to work in parallel once they've agreed on a specific API design. Nothing should have be stopping them anyway!&lt;/p&gt;

&lt;p&gt;Having an OpenAPI-aware gateway allows you to reap more advantages of the &lt;a href="https://kubeshop.io/blog/the-apiops-lifecycle-managing-api-workflows-through-the-open-api-definition" rel="noopener noreferrer"&gt;OpenAPI lifecycle&lt;/a&gt;, like for example &lt;a href="https://kubeshop.github.io/kusk-gateway/guides/validation/" rel="noopener noreferrer"&gt;automatic validation of your APIs&lt;/a&gt; and more!&lt;/p&gt;

&lt;p&gt;Head over to the &lt;a href="https://kubeshop.github.io/kusk-gateway/getting-started/installation/" rel="noopener noreferrer"&gt;Kusk Gateway documentation&lt;/a&gt; to try it out and explore all the benefits of an OpenAPI-driven gateway! We would love to hear your thoughts and ideas in our &lt;a href="https://discord.gg/uNuhy6GDyn" rel="noopener noreferrer"&gt;Discord server&lt;/a&gt; or just drop by if you to say hi :) &lt;/p&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>openapi</category>
      <category>api</category>
    </item>
    <item>
      <title>From Design-First to Automated Deployment with OpenAPI</title>
      <dc:creator>Abdallah Abedraba</dc:creator>
      <pubDate>Tue, 26 Apr 2022 07:19:40 +0000</pubDate>
      <link>https://dev.to/kubeshop/from-design-first-to-automated-deployment-with-openapi-2lg2</link>
      <guid>https://dev.to/kubeshop/from-design-first-to-automated-deployment-with-openapi-2lg2</guid>
      <description>&lt;p&gt;Being an API-first organization is becoming a must as organizations need to build APIs to enable consumers (internal or external) to extend the functionality of their systems, share data across organizations and build customized experiences.&lt;/p&gt;

&lt;p&gt;The microservices architecture — building services that perform only one function, as opposed to covering an entire area of functionality — provides the agile and efficient building workflows needed to deliver seamless customer experiences.&lt;/p&gt;

&lt;p&gt;Finally, Kubernetes, a container orchestration system, has been an extremely popular choice for orchestrating those microservices. It has helped adopt the organizational agile structure into the API development process, but has inherently introduced a new set of challenges.&lt;/p&gt;

&lt;p&gt;Current API development processes require developers to adhere to an organizational set of best practices — if they even exist and assuming that developers have read those best practices and are implementing them — that can only recommend, but not enforce the best practices, giving turn to inconsistent API quality, (slow) developer experience and configuration control.&lt;/p&gt;

&lt;p&gt;In this article we will discuss how you can address these challenges by implementing a design-first approach in your APIs and automating their deployment.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design-First
&lt;/h2&gt;

&lt;p&gt;Most developers have been following a code-first approach to build their APIs. That is, implement the API first, and everything from documentation — usually &lt;a href="https://swagger.io/tools/swagger-codegen/" rel="noopener noreferrer"&gt;code-generated OpenAPI specifications&lt;/a&gt; used with &lt;a href="https://swagger.io/docs/" rel="noopener noreferrer"&gt;Swagger&lt;/a&gt; — to the organization’s policy requirements (security, etc) have come &lt;em&gt;after&lt;/em&gt; the fact.&lt;/p&gt;

&lt;p&gt;The code-first approach has increased the speed of the development itself, but it has compromised the consistent experience between the organization’s APIs and their quality.&lt;/p&gt;

&lt;p&gt;To introduce consistency and quality to a code-first approach, organizations have usually introduced blockers in the deployment process (for example, requiring an API team approval) and in turn slowing down going to production.&lt;/p&gt;

&lt;p&gt;Going design-first means you start by designing your API — writing how your APIs should behave and translating that to the OpenAPI specification — and, once it has been agreed upon, you would then start writing the code to implement the designed behavior of the API.&lt;/p&gt;

&lt;p&gt;Design-first approach enables you to include multiple stakeholders from your organization early in the API design process. Additionally, there are tools that can validate the designed specification, which reduces risks of failure, improves consistency and enforces required aspects of the APIs.&lt;/p&gt;

&lt;h2&gt;
  
  
  Design-First in Practice
&lt;/h2&gt;

&lt;p&gt;A lot of companies have tried design-first methodologies, but have failed to maintain them after a while because they either could not set up the right process, or it was extremely time consuming or tedious.&lt;/p&gt;

&lt;p&gt;In the following walkthrough, we will use three tools to help us set up the process required to go from design to implementation with little overhead. Our design-first approach will be the following:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;We’ll use &lt;a href="https://swagger.io/tools/swaggerhub/" rel="noopener noreferrer"&gt;SwaggerHub&lt;/a&gt; to create our OpenAPI document which allows us to automatically validate the designed API against our standardization rules. The design-time validation ensures that the new API will be consistent with other APIs across the organization. Additionally, we can specify validation rules, to ensure operational consistency across our microservices landscape.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;After that, the designed spec would go into a git repository that will help having a single source of truth of our APIs. This git repository will be connected to ArgoCD, which can then ensure that the cluster is up-to-date with the repository.&lt;/p&gt;&lt;/li&gt;
&lt;li&gt;&lt;p&gt;Finally, ArgoCD will use Kusk-gateway, an OpenAPI driven Kubernetes gateway, to deploy the API so developers can start implementing the services.&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;The process would look like the following diagram:&lt;br&gt;
&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu84t2z915cid55e2jgzo.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fu84t2z915cid55e2jgzo.png" alt=" " width="800" height="452"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h2&gt;
  
  
  Walkthrough
&lt;/h2&gt;

&lt;p&gt;Enough talk — let’s see this in action — here comes a step-by-step walkthrough to get this in place for the automated deployment and execution of OpenAPI specifications in your cluster of choice!&lt;/p&gt;

&lt;p&gt;Let’s start with setting things up for our APIOps-powered development!&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;1. Setting up a Github repository&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://github.com/new" rel="noopener noreferrer"&gt;Create a Github repository&lt;/a&gt; that we will use to put our OpenAPI specifications in and synchronize them with the deployed API in the cluster.&lt;/p&gt;

&lt;p&gt;After the repository is created, create a new folder in the repository with the name api. This is where we will put our OpenAPI spec.&lt;/p&gt;

&lt;p&gt;For that, run the following commands&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;mkdir api # folder where the OpenAPI spec will go to
touch api/.gitkeep
git add . git commit -m “Initial commit”
git push origin main
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;2. Create a new API in SwaggerHub&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In SwaggerHub, on the top left menu, click on “Create New API”&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4rm3b3nb8cbcy2jw2n47.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F4rm3b3nb8cbcy2jw2n47.png" alt=" " width="550" height="245"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Fill in the form as shown below:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsal1wv1msf8bg47rjmjs.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fsal1wv1msf8bg47rjmjs.png" alt=" " width="800" height="1061"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Once the API is created, let’s write an example API to deploy. Copy the spec below and paste it in your SwaggerHub editor.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;OpenAPI allows extending the spec by use of decorators. To extend the OpenAPI specification, you just need to create a new section in the spec that starts with “x-”. In the spec above, you can see that we have used x-kusk to add Kusk-gateway’s configurations.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Connect SwaggerHub to your Github repository&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To deploy it to our Github repository you will need to hover on the &lt;em&gt;Sync&lt;/em&gt; button as seen below and click on &lt;em&gt;Setup Integration&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwpfu715lfsea9sz2i0xf.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fwpfu715lfsea9sz2i0xf.png" alt=" " width="800" height="206"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Choose the &lt;em&gt;Github Sync&lt;/em&gt; integration and click on &lt;em&gt;Next&lt;/em&gt;.&lt;/p&gt;

&lt;p&gt;In the next window, click on &lt;em&gt;Connect to Github&lt;/em&gt; and follow the procedure to connect it. Remember to choose the right repository (the one we just created in the first step).&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fudq8z2wegtlrx5t8quls.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fudq8z2wegtlrx5t8quls.png" alt=" " width="522" height="584"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now fill out the rest of the form as seen below. After that click on the &lt;em&gt;Create and Execute&lt;/em&gt; button and click on &lt;em&gt;Done&lt;/em&gt; in the next window.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbidkj5mi0l2q3cs5dn30.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fbidkj5mi0l2q3cs5dn30.png" alt=" " width="488" height="642"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To check if the integration works, click on the &lt;em&gt;Sync&lt;/em&gt; button as seen below, &lt;em&gt;Push the changes&lt;/em&gt; and you should see the updates in your Github repository!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9csvqgwip115kcn62h3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fe9csvqgwip115kcn62h3.png" alt=" " width="732" height="659"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Facj0ewfknfseqw28c2b4.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Facj0ewfknfseqw28c2b4.png" alt=" " width="800" height="354"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;4. Install Kusk-gateway in your Kubernetes cluster&lt;/strong&gt;  &lt;/p&gt;

&lt;p&gt;Follow the Kusk-gateway &lt;a href="https://kubeshop.github.io/kusk-gateway/installation/" rel="noopener noreferrer"&gt;installation guide&lt;/a&gt;. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;5. Install ArgoCD in your Kubernetes cluster&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Follow the ArgoCD &lt;a href="https://argo-cd.readthedocs.io/en/stable/getting_started/" rel="noopener noreferrer"&gt;installation guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;6.Configure ArgoCD to use Kusk-gateway&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;ArgoCD allows the use of &lt;a href="https://argo-cd.readthedocs.io/en/stable/user-guide/config-management-plugins/" rel="noopener noreferrer"&gt;plugins&lt;/a&gt; that we will use to install Kusk’s CLI tool with, so that when our Github repository is updated, ArgoCD can run the CLI tool to generate the YAML manifests from the OpenAPI specification and apply them to the cluster. &lt;/p&gt;

&lt;p&gt;Create a deployment patch manifest patch.yaml, this will be of type JSON-patch:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;And apply it with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl patch deployments.apps -n argocd argocd-repo-server --type json --patch-file patch.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Now let’s add Kusk CLI to ArgoCD’s plugin ConfigMap. Create the file&lt;br&gt;
&lt;code&gt;argocd-plugins.yaml&lt;/code&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;As you can see here, we’re using the command &lt;code&gt;kgw api generate&lt;/code&gt; which creates the Custom Resources (manifests) that ArgoCD will then add to our cluster. Apply the patch with the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl patch &lt;span class="nt"&gt;-n&lt;/span&gt; argocd configmaps argocd-cm &lt;span class="nt"&gt;--patch-file&lt;/span&gt; argocd-plugin.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Finally, create the ArgoCD application that will manage your API’s gateway deployment.&lt;/p&gt;

&lt;p&gt;Create the file &lt;code&gt;kusk-gateway-application.yaml&lt;/code&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Notice that we have defined &lt;code&gt;path: api&lt;/code&gt; which is the folder in the Github repository with the &lt;code&gt;api-spec.yaml&lt;/code&gt; from the steps earlier. We have also defined the &lt;code&gt;.destination.namespace&lt;/code&gt; to be &lt;code&gt;default&lt;/code&gt;, which is where the gateway should be deployed in the cluster. And apply it with&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; kusk-gateway-application.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;strong&gt;7. Run the initial ArgoCD sync and check your cluster&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On ArgoCD’s dashboard, we will now see the newly created application. Let’s click to get into it and sync our API.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnuveuv82ldtnbboqkmdy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fnuveuv82ldtnbboqkmdy.png" alt="ArgoCD's dashboard" width="759" height="505"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now click on &lt;em&gt;Sync&lt;/em&gt; to create the gateway for the first time‍.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frwaf35b1u9t5zu4mcgqa.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Frwaf35b1u9t5zu4mcgqa.png" alt="Clicking on Sync in ArgoCD's dashbaord" width="800" height="305"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And voilà, there’s our newly created gateway created and managed by ArgoCD with every new update on the OpenAPI spec in the Github repository!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feh8nlnmwocki4hq97y6x.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Feh8nlnmwocki4hq97y6x.png" alt="ArgoCD's dashboard showing a new API has been created" width="779" height="272"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;8. Consuming the Deployed API&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;In our API we have configured Kusk-gateway to mock our single endpoint, so we can have a testable endpoint before implementing the service. It uses OpenAPIs &lt;a href="https://swagger.io/docs/specification/adding-examples/" rel="noopener noreferrer"&gt;example section&lt;/a&gt; to use as a response mock of the API.&lt;/p&gt;

&lt;p&gt;For that we will have to get the Kusk-gateway API endpoint, which you can find by running&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl get svc &lt;span class="nt"&gt;-l&lt;/span&gt; &lt;span class="s2"&gt;"app.kubernetes.io/component=envoy-svc"&lt;/span&gt; &lt;span class="nt"&gt;--namespace&lt;/span&gt; kusk-system
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz2llysqj1n0vjv0khb0r.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz2llysqj1n0vjv0khb0r.png" alt=" " width="800" height="78"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Copy the External IP from the result and query the /hello path defined in our OpenAPI spec:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;curl 127.0.0.1/hello
“Hello world!”
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;And we are set to start implementing the API!&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;This flow of programmatic API design we call it the APIOps, which combined with GitOps philosophy (having your repository as a single source of truth, combining it with CI/CD pipeline) provide a powerful alternative to a more traditional code-first approach not so closely aligned with the lifecycle of Kubernetes applications.&lt;/p&gt;

&lt;p&gt;Let us know what you think about this method, we’re open to hearing your feedback in our &lt;a href="https://discord.gg/uNuhy6GDyn" rel="noopener noreferrer"&gt;Discord server&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;Check &lt;a href="https://github.com/kubeshop/kusk-gateway" rel="noopener noreferrer"&gt;Kusk-gateway on GitHub&lt;/a&gt; and &lt;a href="https://swagger.io/tools/swaggerhub/" rel="noopener noreferrer"&gt;SwaggerHub&lt;/a&gt;!&lt;/p&gt;

&lt;p&gt;You can also check the &lt;a href="https://smartbear.com/resources/webinars/microservices-kubernetes-from-design-first-to-auto/" rel="noopener noreferrer"&gt;webinar on this article&lt;/a&gt; if you want to &lt;em&gt;see&lt;/em&gt; the action yourself!&lt;/p&gt;

&lt;p&gt;Thank you!&lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>openapi</category>
    </item>
    <item>
      <title>A GitOps-Powered Kubernetes Testing Machine with ArgoCD and Testkube — Kubeshop</title>
      <dc:creator>Abdallah Abedraba</dc:creator>
      <pubDate>Thu, 21 Apr 2022 08:51:23 +0000</pubDate>
      <link>https://dev.to/kubeshop/a-gitops-powered-kubernetes-testing-machine-with-argocd-and-testkube-kubeshop-19d7</link>
      <guid>https://dev.to/kubeshop/a-gitops-powered-kubernetes-testing-machine-with-argocd-and-testkube-kubeshop-19d7</guid>
      <description>&lt;p&gt;One of the major trends in contemporary cloud native application development is the adoption of GitOps; managing the state of your Kubernetes cluster(s) in Git — with all the bells and whistles provided by modern Git platforms like GitHub and GitLab in regard to workflows, auditing, security, tooling, etc. Tools like ArgoCD or Flux are used to do the heavy lifting of keeping your Kubernetes cluster in sync with your Git repository; as soon as difference is detected between Git and your cluster it is deployed to ensure that your repository is the source-of-truth for your runtime environment.&lt;/p&gt;

&lt;p&gt;Don’t you agree that it’s time to move testing and related activities into this paradigm also? Exactly! We at Kubeshop are working hard to provide you with the first GitOps-friendly Cloud-native test orchestration/execution framework — Testkube — to ensure that your QA efforts align with this new and shiny approach to application/cluster configuration management. Combined with the GitOps approach described above, Testkube will include your test artifacts and configuration in the state of your cluster and make git the source of truth for these test artifacts. And it’s Open-Source too.&lt;/p&gt;

&lt;p&gt;Key wins achieved with this approach:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Since your tests are included in the state of your cluster you are always able to validate that your application components/services work as required.&lt;/li&gt;
&lt;li&gt;Since tests are executed from inside your cluster there is no need to expose services under test externally purely for the purpose of being able to test them.&lt;/li&gt;
&lt;li&gt;Tests in your cluster are always in sync with the external tooling used for authoring&lt;/li&gt;
&lt;li&gt;Test execution is not strictly tied to CI but can also be triggered manually for ad-hoc validations or via internal triggers (Kubernetes events)&lt;/li&gt;
&lt;li&gt;You can leverage all your existing test automation assets from Postman, or Cypress, or through executor plugins.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;From a conceptual perspective this can be illustrated as follows:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpjn03hsb6hrg7dkp3mhj.jpeg" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpjn03hsb6hrg7dkp3mhj.jpeg" alt="Diagram of how the entire process looks like" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Walkthrough
&lt;/h2&gt;

&lt;p&gt;Enough talk - let’s see this in action - here comes a step-by-step walkthrough to get this in place for the automated deployment and execution of Postman collections in a local Minikube cluster to test.&lt;/p&gt;

&lt;p&gt;Let’s start with setting things up for our GitOps-powered testing machine!&lt;/p&gt;

&lt;h3&gt;
  
  
   Installations
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;1. Install Minikube&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can follow the minikube installation for your operating system &lt;a href="https://minikube.sigs.k8s.io/docs/start/" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;2. Install ArgoCD&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Follow the &lt;a href="https://argo-cd.readthedocs.io/en/stable/getting_started" rel="noopener noreferrer"&gt;ArgoCD installation guide&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: For step 3 “ Access The Argo CD API Server”, choose the “Port Forwarding” method, as that is the easiest way to connect to it with a Minikube cluster. &lt;/p&gt;

&lt;p&gt;&lt;strong&gt;3. Install Testkube&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Follow the installation guide for Testkube &lt;a href="https://kubeshop.github.io/testkube/installing" rel="noopener noreferrer"&gt;here&lt;/a&gt;. Make sure to install the CLI client and the components in your cluster.&lt;/p&gt;

&lt;h3&gt;
  
  
  Setting up application and tests
&lt;/h3&gt;

&lt;p&gt;Install a “Hello Kubernetes!” application in your cluster&lt;br&gt;
We will create a YAML file for a simple “Hello Kubernetes” application that we will then create our integration tests against. &lt;/p&gt;

&lt;p&gt;Create the file &lt;code&gt;hello-kubernetes.yaml&lt;/code&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;And deploy the &lt;em&gt;Hello Kubernetes&lt;/em&gt; deployment with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl apply -f hello-kubernetes.yaml‍
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You can test that your application has been correctly installed by running:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;minikube service hello-kubernetes-service
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;5. Set up a Git Repository containing some Postman collections&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;We are going to use tests created by Postman and exported in a &lt;a href="https://www.postman.com/collection/" rel="noopener noreferrer"&gt;Postman collections&lt;/a&gt; file.&lt;/p&gt;

&lt;p&gt;We can upload this to the same Git Repository as our application, but in practice the repository could be the same repository hosting the application or it could also be in a separate repository where you manage all your test artifacts.&lt;/p&gt;

&lt;p&gt;So let’s create our &lt;code&gt;postman-collections.json&lt;/code&gt; and push it to the repository.&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;You can see an example of how the repository should look like &lt;a href="https://github.com/aabedraba/testkube-argocd-tests" rel="noopener noreferrer"&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configure ArgoCD to work with Testkube
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;6. Configure ArgoCD to use the Testkube plugin&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;To get ArgoCD to use Testkube, we need to add Testkube as a &lt;a href="https://argo-cd.readthedocs.io/en/stable/user-guide/config-management-plugins/" rel="noopener noreferrer"&gt;plugin&lt;/a&gt;. For that we have built a customized &lt;code&gt;argocd-repo-server&lt;/code&gt; container image that will include Testkube as a binary.&lt;/p&gt;

&lt;p&gt;Patch the ArgoCD repo-server pod image. &lt;/p&gt;

&lt;p&gt;Create a deployment patch manifest patch.yaml, this will be of type &lt;a href="http://jsonpatch.com/" rel="noopener noreferrer"&gt;JSON-patch&lt;/a&gt;:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;And apply it with the following command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl patch deployments.apps &lt;span class="nt"&gt;-n&lt;/span&gt; argocd argocd-repo-server — &lt;span class="nb"&gt;type &lt;/span&gt;json — patch-file patch.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;7. Define Testkube as a plugin in ArgoCD’s Configuration Management Plugin&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create the file &lt;code&gt;argocd-plugins.yaml&lt;/code&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;‍As you can see here, we’re using the command &lt;code&gt;testkube crd&lt;/code&gt; which creates the Custom Resources (manifests) that ArgoCD will then add to our cluster. Apply the patch with the command:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl patch &lt;span class="nt"&gt;-n&lt;/span&gt; argocd configmaps argocd-cm — patch-file argocd-plugin.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;8. Configure an ArgoCD application to manage test collections in your cluster&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Create the file &lt;code&gt;testkube-application.yaml&lt;/code&gt;&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;Notice that we have defined &lt;code&gt;path: postman-collections&lt;/code&gt; which is the test folder with our Postman collections from the steps earlier. With Testkube you can use multiple test executors like curl for example, so it is convenient to have a folder for each. We have also defined the &lt;code&gt;.destination.namespace&lt;/code&gt; to be &lt;code&gt;testkube&lt;/code&gt;, which is where the tests should be deployed in our cluster.‍&lt;/p&gt;

&lt;p&gt;Now let’s create the application with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl apply &lt;span class="nt"&gt;-f&lt;/span&gt; testkube-application.yaml
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;&lt;strong&gt;9. Run the initial ArgoCD sync and check your cluster&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;On ArgoCD’s dashboard, we will now see the newly created application. Let’s click to get into it and sync our tests.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi0s4ccoyb0hhpo1znj5a.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fi0s4ccoyb0hhpo1znj5a.png" alt="Clicking on Testkube application in ArgoCD" width="777" height="511"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And now click on &lt;em&gt;Sync&lt;/em&gt; to see your tests created.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1b8fp0ewm5xuq4sw8kv0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F1b8fp0ewm5xuq4sw8kv0.png" alt="Clicking on Sync in ArgoCD" width="800" height="388"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And voilà, there’s our test collection created and managed by ArgoCD with every new test created and updated in the Github repository containing the tests!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd6doefm75rogzqjiw86l.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fd6doefm75rogzqjiw86l.png" alt="hello-kubernetes successfully deployed in ArgoCD" width="800" height="281"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;h3&gt;
  
  
  Run your tests!
&lt;/h3&gt;

&lt;p&gt;&lt;strong&gt;10. Run ad-hoc tests from the CLI&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Now that we’re all set - let’s try some ad-hoc test execution using Testkube’s CLI&lt;/p&gt;

&lt;p&gt;List the tests in your cluster with:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;kubectl-testkube tests list
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;You should see your deployed test artifacts &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz3yldfr9z01h4ov6167v.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fz3yldfr9z01h4ov6167v.png" alt="listing testkube tests in terminal" width="310" height="95"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;To run those tests execute the following command:&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl-testkube tests run hello-kubernetes
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;The test execution will start in the background, you now need to copy the command from the image below to check the result of the execution of the test&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffgih8l1bkhpz2rkzkvxn.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ffgih8l1bkhpz2rkzkvxn.png" alt="running a testkube test in terminal" width="565" height="498"&gt;&lt;/a&gt;&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl testkube tests execution EXECUTION_ID
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;And you should see that the tests have run successfully, just like in the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy5kfw6gj4ad7nwqr5dz9.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy5kfw6gj4ad7nwqr5dz9.png" alt="Results of a Testkube test in terminal" width="511" height="540"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;11. See test results in the Testkube dashboard&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;You can also see the results of your tests in a nice dashboard. Just open the Testkube dashboard with the following command&lt;br&gt;
&lt;/p&gt;
&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;kubectl-testkube dashboard
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;‍&lt;/p&gt;

&lt;p&gt;And you will be able to see the results of the execution in the Executions tab as seen in the image below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftr73924tztywg19s8pkw.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Ftr73924tztywg19s8pkw.png" alt="Testkube dashboard showing the tests run" width="800" height="418"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;12. Test the flow: update the test and deploy the updated test with ArgoCD&lt;/strong&gt;&lt;/p&gt;

&lt;p&gt;Let’s add an additional test to our collection. Replace the content our existing test in &lt;code&gt;hello-kubernetes.json&lt;/code&gt; with the following: &lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;As you can see, we have added a request status check. Now commit this change to the Github repository. &lt;/p&gt;

&lt;p&gt;If you now go to ArgoCD’s dashboard you’ll see that your tests are out of sync with the deployed artifacts.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F79upqadsxkv0jk4ee1mp.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F79upqadsxkv0jk4ee1mp.png" alt="ArgoCD dashboard showing OutOfSync message" width="421" height="209"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on Sync again and apply the changes. With that, your test artifacts are back in sync!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvibcnzf18gug7pqxmx73.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fvibcnzf18gug7pqxmx73.png" alt="ArgoCD dashboard showing Synced message" width="423" height="185"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Wow - that was quite a lot to get through but we ended up with something really neat - an automated test deployment and execution pipeline based on GitOps principles!&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping up
&lt;/h2&gt;

&lt;p&gt;Once fully realized - using GitOps for testing of Kubernetes applications as described above provides a powerful alternative to a more traditional approach where orchestration is tied to your current CI/CD tooling and not closely aligned with the lifecycle of Kubernetes applications.&lt;/p&gt;

&lt;p&gt;Would love to get your thoughts on the above approach - over-engineering done right? Waste of time? Let us know!&lt;/p&gt;

&lt;p&gt;Check Testkube on GitHub — and let us know if you’re missing something we should be adding to make your k8s resource testing easier.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://github.com/kubeshop/testkube/releases" rel="noopener noreferrer"&gt;Download the latest release&lt;/a&gt; on GitHub&lt;/li&gt;
&lt;li&gt;Check out the &lt;a href="https://kubeshop.github.io/testkube/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Get in touch with us on our &lt;a href="https://discord.gg/uNuhy6GDyn" rel="noopener noreferrer"&gt;Discord server&lt;/a&gt; &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Thank you! &lt;/p&gt;

</description>
      <category>kubernetes</category>
      <category>argo</category>
      <category>testing</category>
      <category>gitops</category>
    </item>
    <item>
      <title>How to Create a YAML Manifest Template in Monokle</title>
      <dc:creator>Abdallah Abedraba</dc:creator>
      <pubDate>Wed, 02 Mar 2022 08:29:18 +0000</pubDate>
      <link>https://dev.to/kubeshop/how-to-create-a-yaml-manifest-template-in-monokle-2kmp</link>
      <guid>https://dev.to/kubeshop/how-to-create-a-yaml-manifest-template-in-monokle-2kmp</guid>
      <description>&lt;p&gt;&lt;a href="https://monokle.kubeshop.io/" rel="noopener noreferrer"&gt;Monokle&lt;/a&gt; is a great tool to inspect your Kubernetes manifests with an easy and intuitive interface showing you how your manifests are connected to each other and how they translate to your existing cluster. It also allows your team to avoid drifts between your manifests and clusters as you keep adding more and more components.&lt;/p&gt;

&lt;p&gt;Apart from inspecting your existing manifests, Monokle allows you to create manifests both from scratch and from templates. These templates help you gain speed while creating new components, but more importantly, they reduce grounds for errors from wrongly misconfiguring them.&lt;/p&gt;

&lt;p&gt;For example, if your team has a policy of adding a specific property to every component, you can enforce the correct creation of these properties in your template instead of having the developer manually create the manifest and forgetting to add the required property.&lt;/p&gt;

&lt;p&gt;When you create your templates with Monokle, you will be able to have a form that developers will fill out to create the resources they need, as seen in the example below.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmzdfnitt93u81h0hcheb.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fmzdfnitt93u81h0hcheb.png" alt="Created form example" width="800" height="566"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Monokle comes with a number of default templates to get you started with Kubernetes, and in this tutorial, you will learn how to make your own template for a simple Kubernetes Pod.&lt;/p&gt;

&lt;h1&gt;
  
  
  Setting up the project
&lt;/h1&gt;

&lt;p&gt;Templates are installed through a plugin in Monokle. A plugin is basically a Github repository with a valid Monokle &lt;code&gt;package.json&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;So, first of all, let’s go ahead and create a Github repository -you can call it &lt;code&gt;monokle-templates-plugin&lt;/code&gt; - and connect the repository to your local machine.&lt;/p&gt;

&lt;p&gt;We will create now the &lt;code&gt;package.json&lt;/code&gt; for our template plugin in the root of our repository:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;h1&gt;
  
  
   Template configuration
&lt;/h1&gt;

&lt;ul&gt;
&lt;li&gt;a &lt;strong&gt;Monokle template configuration&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;a &lt;strong&gt;Form configuration&lt;/strong&gt;
&lt;/li&gt;
&lt;li&gt;and a &lt;strong&gt;Kubernetes YAML manifest&lt;/strong&gt; with placeholders&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We will expand on those in the next section while we are creating them.&lt;/p&gt;

&lt;h2&gt;
  
  
   1. Monokle template configuration
&lt;/h2&gt;

&lt;p&gt;We will need a specific folder for each template. Let’s create a folder and call it &lt;code&gt;basic-pod-template&lt;/code&gt;, just like we have defined it in the path section of our &lt;code&gt;package.json&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;$ mkdir basic-pod-template &amp;amp;&amp;amp; cd basic-pod-template
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;


&lt;p&gt;Let’s now create the template configuration, which is Monokle-specific and defines what type of template you are creating. There are two types of templates in Monokle for now: &lt;em&gt;vanilla&lt;/em&gt; and &lt;em&gt;helm-charts&lt;/em&gt;; we will be creating a simple &lt;em&gt;vanilla&lt;/em&gt; type template.&lt;/p&gt;

&lt;p&gt;Create the file &lt;code&gt;monokle-template-json&lt;/code&gt; with following content:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;



&lt;p&gt;In the code above, we have defined the fields forms.schema and &lt;code&gt;forms.uiSchema&lt;/code&gt;. Both of these fields define files that will be used by Monokle to provide users of our template with a nice input form. The &lt;code&gt;form-schema.json&lt;/code&gt; file will contain the form fields that we will request the user to input, and the &lt;code&gt;form-ui-schema.json&lt;/code&gt; defines how the form is going to appear (titles for the fields, descriptions, etc).&lt;/p&gt;

&lt;p&gt;Let’s go ahead and create our &lt;code&gt;form-schema.json&lt;/code&gt; defining the basic fields that we will request from the user to create a Pod:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;This is a standard JSON schema format, which you can read more about in the &lt;a href="https://www.google.com/url?q=https://json-schema.org/&amp;amp;sa=D&amp;amp;source=editors&amp;amp;ust=1645113432201802&amp;amp;usg=AOvVaw2mJdf6Q7SZLRbYx9oEBrgn" rel="noopener noreferrer"&gt;json-schema website&lt;/a&gt;. JSON schema is used in most projects to define custom forms like the one we are creating now, where you can define, among other things, the required fields of your form, as seen in the required section.&lt;/p&gt;

&lt;p&gt;Monokle uses the &lt;code&gt;react-json-schema-form&lt;/code&gt; frontend component to render the forms for these templates. It takes the form fields definition which we just created, and a UI form definition, which we will build next.&lt;/p&gt;

&lt;p&gt;Create the file the file &lt;code&gt;form-ui-schema.json&lt;/code&gt; with the following content:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;Notice that we are using a custom widget, internally defined for Monokle, called &lt;code&gt;namespaceSelection&lt;/code&gt;. This widget provides the user with a dropdown of available namespaces.&lt;/p&gt;

&lt;h2&gt;
  
  
   3. YAML manifest template
&lt;/h2&gt;

&lt;p&gt;Finally, we’ll define the &lt;code&gt;YAML manifest template&lt;/code&gt; with the placeholders that we will update the form data with. Note that we are using forms as an array because we can define multiple successive forms in our &lt;code&gt;monokle-template.json&lt;/code&gt;, instead of having one huge form. In our case, as we have only one form, we will use &lt;code&gt;forms[0]&lt;/code&gt; to access it.&lt;/p&gt;

&lt;p&gt;Create the &lt;code&gt;template.yaml&lt;/code&gt; file and populate it with:&lt;/p&gt;


&lt;div class="ltag_gist-liquid-tag"&gt;
  
&lt;/div&gt;


&lt;p&gt;As you can see, we have been able to enforce a specific type of property, by marking the form field as required and formatting it in a specific way in our template. You can also see that Monokle uses [[,..]] as the syntax for interpolation of form values and simple scripts written in javascript.&lt;/p&gt;

&lt;h2&gt;
  
  
   Upload your project to Github
&lt;/h2&gt;

&lt;p&gt;Let us wrap up with the creation of the template and upload the &lt;code&gt;package.json&lt;/code&gt; and our template folder to the Github repository that we created at the beginning of this tutorial.&lt;/p&gt;

&lt;h2&gt;
  
  
   Importing your template in Monokle
&lt;/h2&gt;

&lt;p&gt;Now that we have defined our template configuration, the form definition and our manifest with its placeholders, we need to import the template to Monokle in our configured project.&lt;/p&gt;

&lt;p&gt;Click on the plugin section, on the top right of Monokle’s interface&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fae8uxj3lcsya7lkytvs1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fae8uxj3lcsya7lkytvs1.png" alt=" " width="523" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Click on install, and add your Github repository link on the prompted field.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fps4y7ywf0jnoq2hecxyr.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fps4y7ywf0jnoq2hecxyr.png" alt=" " width="523" height="270"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;You will now find your brand new plugin in the Plugin Manager, as shown below&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy6o149t5gfhgoefg9tcy.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fy6o149t5gfhgoefg9tcy.png" alt=" " width="399" height="409"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;If you check the Templates section, you’ll now find your new template available to use.&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5cz57maadzk8mijthyz1.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2F5cz57maadzk8mijthyz1.png" alt=" " width="558" height="339"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;h1&gt;
  
  
  Using your template
&lt;/h1&gt;

&lt;p&gt;Let’s create a basic pod by using the template and filling the form: &lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpdnkpku0qkr3eew8wio0.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fpdnkpku0qkr3eew8wio0.png" alt=" " width="800" height="523"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now that the Manifest is created, we can save it and deploy it!&lt;/p&gt;

&lt;p&gt;&lt;a href="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdyepr6arv2mdf59zpbu3.png" class="article-body-image-wrapper"&gt;&lt;img src="https://media2.dev.to/dynamic/image/width=800%2Cheight=%2Cfit=scale-down%2Cgravity=auto%2Cformat=auto/https%3A%2F%2Fdev-to-uploads.s3.amazonaws.com%2Fuploads%2Farticles%2Fdyepr6arv2mdf59zpbu3.png" alt=" " width="800" height="398"&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;And just like that, you’ve created a template! 🥳&lt;/p&gt;

&lt;h1&gt;
  
  
  Next Steps
&lt;/h1&gt;

&lt;p&gt;All the steps from this tutorial can be found in &lt;a href="https://github.com/aabedraba/monokle-templates-plugin" rel="noopener noreferrer"&gt;this Github repository&lt;/a&gt; – feel free to clone it, make your own changes and use it as a starting point to your new templates. You can also read and learn more in the Monokle documentation about &lt;a href="https://kubeshop.github.io/monokle/plugins/" rel="noopener noreferrer"&gt;plugins&lt;/a&gt; and &lt;a href="https://kubeshop.github.io/monokle/templates/" rel="noopener noreferrer"&gt;templates&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Check &lt;a href="https://github.com/kubeshop/monokle" rel="noopener noreferrer"&gt;Monokle on GitHub&lt;/a&gt; — and let us know if you’re missing something we should be adding to make your everyday life with k8s manifests and resources easier.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href="https://github.com/kubeshop/monokle/releases/tag/latest-version" rel="noopener noreferrer"&gt;Download the latest release on GitHub&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Check out the &lt;a href="https://kubeshop.github.io/monokle/" rel="noopener noreferrer"&gt;documentation&lt;/a&gt;
&lt;/li&gt;
&lt;li&gt;Get in touch with us on our &lt;a href="https://discord.gg/uNuhy6GDyn" rel="noopener noreferrer"&gt;Discord server&lt;/a&gt;
&lt;/li&gt;
&lt;/ul&gt;

</description>
      <category>kubernetes</category>
      <category>yaml</category>
    </item>
  </channel>
</rss>
