 Hello, everyone. My name is James Blair, and this is probably going to be the weirdest thing that you'll see today. I'm going to talk about testing container applications with a new system that I've created called Cogate. Cogate is end-to-end testing for container-based applications, and the idea is that when you open a pull request on GitHub, Cogate will build your images, create an ephemeral Kubernetes environment, and deploy your application, run any tests that you have, merge the changes when you approve them, and after they merge, publish new images. So if you're familiar with Zool, this is very similar to what Zool does, but it is targeted very narrowly to Kubernetes applications, and it does a lot of stuff behind scenes to make this easy for you. So it uses Zool to do speculative image builds, create speculative test environments, project gating, and it has the fabulous auto-hold feature, which if you've been here for the previous talk, then you've learned all about. Auto-holds let you not only log into a Kubernetes cluster to debug your application, but in this case, you can use them as preview environments. So if you want to see what your application looks like, then you can have Cogate deployment and deploy it in one of these ephemeral Kubernetes clusters and then use the auto-hold to preview what it's going to look and function like. So what are speculative builds? These are container builds that depend on unmerged changes in other projects. So let's say that you have container images for your application, and those container images are based on other container images. For instance, you might have a base image that you use for all of your images, and then from that base image you build on top of it. So with Cogate, not only can you, when you open a pull request, can you say build this container image with this pull request, you can actually have that pull request depend on another pull request, possibly even in another repository. And Cogate will not only speculatively build your container image for the pull request that you're opening, but any that it depends on as well. There's really no limit to how deep this wrap-a-hole goes. Speculative test environments. So once we've built these images, Cogate is going to spin up a Kubernetes. It's going to deploy the images that it just built. Again, these changes aren't even merged yet, but it's going to use whatever deployment methodology you tell it to, to deploy and run your app, and then run any tests that it needs to, and then destroy the cluster at the end of this process. When you put all these things together, you get something that we call project gating. And this is when you take a change that is a change to your application, you want to test it, and then automatically have it merge as soon as it passes tests. So basically, you can open up GitHub pull request, review it, say, this looks good to me, and then Cogate is going to deploy your application with it, test it, and if it passes tests, then automatically merge it. The auto-holds feature that I mentioned earlier, like I said, you can use that deployment as an interactive preview environment or use it to diagnose failures. So I'm going to show you a little bit of what Cogate looks like. It's not a full demo, but it's a lightning talk walkthrough so you can get an idea of what this is and how it works. So you can log in with an email address or, of course, log in with GitHub. So it integrates with everything that you've got there. Once you've logged in, this is the list of projects that it has access to. You can fairly easily turn it on and off for any of your GitHub projects. You can also, you'll notice there's a branches column there. You can tell what branches to act on. So it can act on all of the branches or you can tell it to only deal with protected branches. This is sort of depending on your workflow, whether you use the protected branch workflow or not. You can set that there. So for this example, what I have here is a very simple application that has two container images and they're in two different repos. The application is a calculator and it's a client server-based calculator because, of course, why wouldn't you use a client server calculator? So there's a calculator server and a calculator client. The client just doesn't arrest call to the server to do arithmetic. So the first thing that we need to do is take a look at our calculator server app and tell Cogate to build an image. This is all it takes to do that. There are some other options if you need them. But if your repo has a Docker file in it, then if you add this Cogate.yaml to it, this is all you need to do to tell Cogate build this repo into an image that is called calculator server. Oh, yeah, I made that bigger so it's easy for you to read. Sorry. So once you add this file and open up a pull request for it, Cogate is going to immediately start building it. So this is something I think it's pretty neat. Basically, any changes that you make to Cogate configuration, they don't have to merge before it starts using them. So you can just propose this change and Cogate will build an image for it. And going back to the Cogate interface, that's what this looks like. Here's the build result. You can see up there that it knows that it built the Docker Hub calculator server image with the latest tag. And if you want, you can click on the View Logs button and see the build blogs. But you know what those look like. So the next thing that we need to do is add our second image. So we added the calculator server image before. Now we're going to switch to the other repo and tell it to build the calculator client image. We also need to tell it to how to actually deploy this application. So I'm going to remember that I have a zoomed in version this time. So this is the Cogate YAML file for the calculator client repo. You can see that we define the image there at the top. So that's just like the calculator server. And then underneath that, we define our deployment. So this is where most of the magic happens. Within that deployment, we tell it what images that we use. So we're going to tell it that we need the calculator client and the calculator server image. And Cogate is going to use that so that whenever you make a change that causes either of these images to be built, it knows that it's going to need to run this deployment. Then we tell it what kind of platform we need. So this can run on a single node Kubernetes cluster. So the platform here is Kubernetes one node. Over time, Cogate will grow any number of different platforms. It's pretty simple right now. We're kind of like in a beta test phase. But we're going to get multi-node Kubernetes systems. We could use EKS, AKS, GKS, all the KSs. And then we tell Cogate how to actually deploy it. So in this case, we're telling it to run kubectl apply. So you can deploy this app by doing kubectl apply deploy.yaml. And then we tell it what. So Cogate expects something to run. That thing needs to not only deploy the application, but also do some kind of evaluation and return success or failure for whether this works or not. And so we, as part of the deployment, we have a job that actually does some arithmetic. And that job, then we just need to wait for that to complete. So there's other methods of application. Instead of doing kubectl apply, you could also use customize. You could create what we call an action container. So that's basically, in this instance, that would be a third image that gets built. And inside of that image is all of your deployment code. So if you wanted to run Helm or something like that, then what you would do is build an image that runs your Helm charts. So with the concept of an action container, it's very powerful. You can basically do anything that way. So this is what our deployment build looks like. It's a little bit different than the image builds. You can see that not only it tells you which image builds were used, and not only can you see the logs, but down here at the bottom of the page, we actually have, and Cogate has an understanding of what resources existed in the cluster during the job. So we've got a little card up there for each of those resources. So it's pretty easy to just click on any of those and get basically the equivalent of a kubectl describe or something like that. So here's what happens if you click on the info icon for the deployment. You get the kubectl describe for that. So you can see all of these Kubernetes resources. You can see all of the logs very easily just from the web interface. Here's our pod that actually ran the arithmetic. So these are the logs from our calculator server doing, adding 1 plus 4. So it's really easy to see the results of the build that way. So let's see. That seems duplicative. Oh, so auto holds. So if you set an auto hold for, that's what this is showing. There's a little hold. So if you flip the hold switch on the build, then you're telling Cogate that you want an auto hold. You want to hold the end of this build. And so once it completes, not only do you have all the things that I showed you before, but there's a button there that says kubconfig. And if you click on that, then it will show you the kubconfig for that cluster. So you can copy and paste that to your local environment and then start running kubectl commands on it and have at it, do whatever you want with the cluster. And then when you're done, you can just hit the delete hold button and it'll release the cluster back from when it came. So that's the quick demo for Cogate. So feel free to take a look at the website. It's got a sort of tutorial walkthrough based on this calculator client server thing. So you can kind of get hands on with it pretty easily. And like I said, this is very new. Consider it in beta. And please let me know if you have any questions or it's not quite working out for you. You need to do something else. I'm very open to feedback. So my email address is up there too. And I've got a little pamphlet here that you can take as well. So thank you very much.