 Hi everybody, I'm Flavio Castelli from Sousa Rancher. I'm here today to talk about how to write queue-cuddled plugins using WebAssembly and WASI. Let's start by taking a look at how regular queue-cuddled plugins are written. Well, they are just traditional binaries that are shipped on your machine using a tool called Crew. By being regular binaries, the plugin offers to maintain a build matrix for all the different operating systems and architectures that you plan to support. Things change instead when we try to write plugins using WebAssembly. The first thing is that I don't have this build matrix anymore. As a plugin offer, I just have to compile for one target, which is the WASI one. And once I obtain my WebAssembly file, I can just run this file on any kind of operating system architecture where I have a WebAssembly runtime. Also, we gain some nice security improvements because traditional queue-cuddled plugins are executed in an unconfined way. On the other end, WebAssembly runs their run inside of dedicated sandboxes. Each WebAssembly module is run inside of its own sandbox, which means it cannot interact with other WebAssembly modules. But most interesting, it cannot interact with other processes running on your machine. It cannot start them. It cannot also interact with devices of your machine or make network calls or make a file system operation unless you give access to a portion of the file system. So this is allowing us to have a more constrained environment where we can run queue-cuddled plugins. Another thing is the majority of queue-cuddled plugins are written using the Go programming language, which is notorious for producing big binaries. On the other end, WebAssembly modules tend to be way, way smaller. So this is a nice improvement as well. The last point, however, the main driver for me, it was the fun factor. I really wanted to push the limits of WebAssembly in Wasi and see where I could go with that. And this is how I ended up creating this tool called Crewwasm. So first of all, big disclaimer, Crewwasm is not meant to be a replacement of the Crew tool. On the upside, it is a complementary tool. Its main purpose is to manage the queue-cuddled WebAssembly plugins, which means download them, remove them, and of course, run them. And so that means Crewwasm is a WebAssembly runtime that is the only piece that has to be maintained for all the different operating systems and architectures if we go back to this Bill Matrix problem that I described before. It is also responsible of making the plugins visible to Kube-cuddle. So let's see how Crewwasm works. Let's have a live demo. First of all, we will list all the Kube-cuddled plugins that I have installed on my machine. As you can see, I have a bunch of them already there. The one that I'm going to show today written in WebAssembly is called Decoder. It doesn't show up there because I haven't hit around. It doesn't also show up by using Crewwasm. So Crewwasm is not managing this plugin yet. That's because we have to download it. So as I said before, Crewwasm is in charge of downloading the plugin. We're going to download the plugin from the container registry, like the same infrastructure used to manage container images. And now that we downloaded it, the Decoder plugin is visible both to Crewwasm and also to Kube-cuddle. Yes, we can use it. So how do we interact with it? Well, there is nothing special you have to do. It is just like any other Kube-cuddled plugin. So let's start it with minus, minus help to understand what this plugin is doing. Well, this plugin is here to help us interact with Kubernetes secrets. It also has a subcomment called secret, which provides a specific action. So let's take a look at this action. So yeah, basically what this plugin does is provide a nicer way, a more human friendly way to look into Kubernetes secrets. So this is the output produced by Kube-cuddle Vanilla about a secret that I have inside of my Kubernetes cluster. And as we all know, Kubernetes secrets are Bay64 encoded. So the plugin is going to do a decode, a Bay64 decode of this information, and print all of that in a, let's say, human friendly way. But we can do more than that. Let's take a look at Kubernetes secrets, which holds a TLS certificate. So this is the output produced by Vanilla Kube-cuddle. But let's be honest, doing a Bay64 decode of this information is not going to be useful either because we're going to get a Pam encoded certificate. What we can do instead by using this plugin is to decode the certificate and provide some specific information about it. So you can see here, we can see who is the subject of it, who issued that, the validity of the certificate. So a bunch of more useful information. So this is a WebAssembly module for Kube-cuddle that is working, as you can see, doing a relatively complex operation. So what was the experience in writing that, what is the overall experience of WebAssembly and Kube-cuddle? Well, first of all, WASI, which is the target platform we are using for WebAssembly, is providing us a lot of good things. So it allows us to interact with the FI system, and we need that in order to read the Kube config that we need to have to access to the Kubernetes API server. It allows us to read environment variables if we want to, and we are doing that, for example, to see where the Kube config file is located. It allows us to interact with a terminal to handle CLI arguments, to have a color and output, to have input and output, you know, a lot of the things that you expect when writing a CLI program. The last point is more about Rust, which is the language I used to write this plugin. So Rust is providing an excellent experience towards WebAssembly development. I used a bunch of Rust libraries inside of this plugin, like the ones to decode TLS certificates. They want to interact with the terminal, you know, for the ASCII tables, for the color output. They all work out of the box. There is no change you have to do. This is really impressive. It's a great experience. There are, however, some downsides. The biggest issue is the lack of network capabilities of WebAssembly. So right now there is no socket capabilities inside of WebAssembly, inside of WASI. There is work being done as we speak, and this is going to change. In the meantime, it means that we have to find other ways to interact with the Kubernetes API server. So the only way you have to do that is by providing some functions to the WebAssembly guest to the plugin. So this is what CrewWasm is doing. CrewWasm is exposing a series of functions that the guest then can use to perform this operation. But these functions are, you know, kind of proprietary, let's say, they are specific to CrewWasm. So you can just take a regular Rust library that is doing network operation and just expect that to work, because this library has to use the network functionality exposed by CrewWasm. So I was really lucky, because the Kubernetes library for Rust is using an approach which has been pioneered instead of a Python word, which is called SansIo, which means that this library is just focusing on defining Kubernetes objects and providing, you know, ways to list them and to create them, to delete them. But it doesn't focus on the way in which network packets are transferred. This is something that you can plug in, and this is exactly what I'm doing. I plugged into that the functions that I'm exposing through CrewWasm and everything is working. But this is a big limiting factor, which means that right now I think only Rust is a viable language for writing kubectl WebAssembly modules. But this is going to change because the WebAssembly module is evolving pretty fast. So that's all for today. These are a bunch of links about all the things I've shown. I hope you enjoy the talk. And if you have other questions, feel free to reach out to me. Have a great day. Bye-bye.