 Today we're going to be talking about how you can improve your RGOSD experience with UI extensions But before I get to that, I'd like to introduce myself My name is Remington Breeze. I'm a software engineer at Acuity and I'm also an RGOSD project maintainer Leo, would you like to introduce yourself? Sure. Hi everyone. My name is Leonardo Salmeida. I usually go by Leo I am a staff software developer at Abe to it and I am one of the maintainers in the RGOSD and RGOR allows projects Thanks, Leo All right, so before we get started I think it's important to understand why we decided to make the RGOSD user interface more extensible in the first place So one of the core tenants of our development philosophy for the RGOSD product has always been focused So we want to prioritize core functionality Without adding a lot of unnecessary cruft and bloat But over time we kind of noticed that more and more people adopted RGOSD and some more unique use cases arose that needed Unique solutions that we couldn't just put into the main project So one of these use cases that we found ourselves in a pretty unique situation to solve was a lot of folks run RGOSD with RGOR rollouts and they wanted more information about their RGOR rollouts at a glance in the user interface But we didn't want to tightly couple RGOSD with RGOR rollouts So to solve this we built extensions To try to keep delivering what we think is a world-class developer experience to folks that just want to use RGOSD by itself But also allowing users with those more complex needs an option to adapt the user interface to meet those needs So there are two sections of today's talk I'm gonna be discussing the first that's gonna that's standard UI extensions and then Leo's gonna go over the second part Which is proxy extensions a different type of extension So first I want to briefly go over each type of extension so that you know what to look for when I give my demo And then in that demo, I'm gonna first show you where each type of extension gets installed to And how you can use them and then I'll move to the main Main subjects of my my part of the presentation So the first is rollouts extension and the timeline extension So I'm I'm pretty excited to show you the timeline extension today It's in development and will be released soon And it takes advantage of an improvement to the extensions extensions mechanism of the UI Which I'll talk a little bit more about later in the presentation and Then after you see these in action, I'm gonna pull back the curtain a little bit And show you exactly where these extensions were installed on my local machine And then I'll talk about how you can install them in a production environment because it is a little bit different And after that will that concludes the demo and we'll talk a little bit about The anatomy of a UI extension and see you what API is our go see our go city exposes For you to inject your own extensions and how it renders data and what data it receives from from the UI Then for Leo's portion of the presentation He's going to demonstrate another type of extension which I mentioned called proxy extensions The example of that here is the metrics extension And then after his demo he's going to go into some detail about how these extensions work both With a basic example and then a more complex real-world example that is what they use it into it And then finally if what we talked about today resonated with you We're gonna discuss the next steps and how you can get involved and maybe build your own extensions All right. So like I said, there are four types of extension The first is a resource tab extension The second is a system level extension The third is an application view extension and the fourth is an application tab extension Which is really just a special case of a resource tab extension And with that, I think it makes the most sense to show you guys the where these extensions are in the user interface So I'm going to give a quick demo Alright So this is the RgoC user interface if you're unfamiliar with it What we're looking at here is an overview of our application. This is all the resources in it And this is a rule-outs application So the first place that extensions would get installed is the application tab extension We don't have a good example of an application tab extension to show you today But if you were to install one it would show up here in the application details panel And up here at the top you can see There are multiple tabs and it would essentially just be a new tab So like I said, it's a special case of a resource tab extension I will be showing you that in a little bit. So it might be more sense The second type of extension is a system level extension And that's going to show up over here on the left With these icons and if you're familiar with the RgoC interface You'll know that this cat icon is not usually there and that's because I installed a system level extension So let's take a look at it So system level extensions take up your whole screen and this extension is really simple It uses a public-facing API, external API to get pictures of cats So if I refresh the page there will be a new picture So this is really useful for things like maybe adding documentation or configuration That you want at a global level and not at an application level And the reason that I use this API is to demonstrate that you don't actually just have to rely on Data from the RgoCD use interface or API server You can query external APIs and that's really good for things like say you have an internal VPN or corporate VPN And you have some publicly exposed endpoints that are accessible only on the VPN. You don't need to authenticate You could absolutely create an extension that that leverages that data So moving back to our application I'll demonstrate the rollouts extension. So like I said, this is a rollout application And when I started the demo, you might have noticed I had the rollouts dashboard open If you're unfamiliar with this, this is a user interface that gets shipped with Rgo rollouts by default It's really easy to spin up But sometimes you don't want to spin it up locally and you don't want to host it yourself So it would be really useful to have some of this information in the RgoCD interface itself So that's what we did with the rollout extension So if I go back here to the user interface and click on this rollout resource You'll notice that there is an additional tab called more and this is the resource tab extension type that I was discussing earlier So here we have a simplified version of that rollout dashboard that we saw before And this is read only or this specific extension is read only But if I go back here to the dashboard, I can edit the image and I'll show you what happens when we make a change So I update the image here And now if we go back here, you see that the two interfaces match and we're on a pause step But RgoCD is not read only so what we can do is promote this rollout from the resource tree So I'll come back here and click promote full And once I do that if I click here again We can see that the rollout has been promoted and it's gone through each and every one of the steps So that's the rollout extension And like I said, that's an example of a resource tab extension So the final type of extension that I'll demonstrate for you today is called an application view extension And where those show up is up here in the right. So Again, if you're familiar with the UI, you know that there are typically four different types of view So there's the resource tree view, which is what we've been looking at There's the pod view, which is really useful for seeing pods and who owns them Then there's the network view, which is really useful for visualizing network traffic in your application And then there's the list view, which is just a simple list But you'll notice that there's a fifth icon that's not normally there and that is for the timeline extension So this is a brand new extension that I mentioned that's still in development But what this is really good for is giving you out of glance information an overview of what's recently been going on in your application So up at the top we have some just basic metrics of total resources total pods There's one resource out of sync. We have the number of nodes And then on the right we have memory pressure and CPU pressure This is just an average across all nodes if we had more than one. It would be a little bit more useful And actually if I click this button, which is simply for the demo Something's gonna happen to our application and I'll show you what happens what it looks like if Memory pressure and CPU pressure go up. So it just changes color And then down here we have the the meat of the timeline view which is the events timeline So these are kubernetes events that are being passed to the extension And it all looks pretty good here as most of you probably know kubernetes only stores about an hour of events by default So we don't have a ton of them here, but they're enough to make it useful And we can sort by new or sort by old So the oldest one happened about an hour ago We can also filter by warnings only so if you want to just see the warnings that have happened there aren't any right now, but If there were they'd show up when you click that button All right, so that concludes the demo of all the different types of extension But I'd like to show you now how they were installed on my local machine. So if I go over to my terminal here I have The slash TMP slash extensions directory on my local machine up for you And I'll go ahead and run tree to show you what's in it So there are two directories roll out in timeline and that corresponds to the two extensions that you just saw And this is how extensions get hosted. So really at the end of the day The API server just needs to be able to access this slash TMP slash extension directory And each extension must be in its own Uniquely named directory and in that directory we expect a javascript file with the prefix extension It can be called simply extension.js, but we've named them more appropriately here And that's how I'm running it locally. So the API server is running locally and it's simply looking at this directory on my machine But in the real world, you can't really do that your API server will be running in a pod So we need to do something a little bit more complex So here I have an example of an Argo CD server deployment And Leo recently created a new image to make it super simple to install these extensions in a production environment So you'll notice that there's a new init container. That's not typically on an Argos d server deployment And this init container is the extensions installer And all it needs to be able to install this extension is a URL to the bundle that contains the javascript files You can additionally include a checksum if you'd like, but you don't have to And then here's this is where it's really getting mounted to this is a volume out And as I said, it must live in slash TMP slash extensions And this is a shared directory between the Argos d server pod. Sorry Argos d server container And the init container that's essentially just downloading the the tar ball untarring it and moving it into the directory So it makes it really easy to get these installed And that concludes my demo so I'll move back to the presentation So I'd like to talk a little bit about the anatomy of a UI extension and how these actually get registered in the javascript So Argos d's UI Exposes this function register resource extension and a number of others. There are appropriate functions for System level extensions for example or application view extensions. I've chosen this one as an example But it attaches this this function to the window variable the global window variable So when you build an extension, you'll just call window dot register resource extension and pass it these Parameters so the first is a react component. It's pretty straightforward. I'll show you what properties this react component expects in a little bit The second is group and third is kind so for resource resource tab extension This is rendering for a specific type of Kubernetes resource So you do need to specify the group kind for a rollout. That's Argo prods.io slash rollout And then finally we have the tab title So this is going to be the name of the tab in the Argos d user interface and for other types of extensions There's simply a title so for the For the application view extension for example, it'll change the browser tab title among other things So now looking a little bit closer at the actual react component. So this is a standard react component and it accepts a few Different props so the first is application and this is the application Json data the same data that's being used to render the rest of the user interface It just gets passed to the extensions here same with resource for the other types of extension You're not going to be using the resource there won't be a resource but for resource tab extension There will so this is where for the rollout extension The data gets passed there and then there's the application tree So again, this is the exact same json data that the Argos d user interface is using to render that resource tree view And finally we have events. So this is the The data that's powering that timeline extension view that I showed you and as I mentioned is coming soon So it's it's in development and this data will soon be passed to application view extensions So with that I'll pass it over to Leo. All right. Thanks Remington All right, so my part of the presentation I'm going to be talking about proxy extensions Which is not really something really independent from the UI extension that remington just presented He actually works in conjunction. So the first my demo is demonstrating One extension that works with this concept in mind Which is the metrics extension is an extension that we run add into it in all our our clusters So we have more than 300 clusters today running this extension. So let's jump in and See how this looks like. So I recorded this requires quite a bit of infrastructure So I'm gonna run through the through the to the recording. So here I have Argo city running and one application deployed called metrics demo And on the right you have the application itself Running so the the way the application works is pretty simplistic. It just sends Requests to itself and it has the ability to configure the the the percentage of 500 errors that will be returned as well as the Latency so right now as you can see it is configured with five fifty percent of 500 errors and latency of 10 seconds and that's why you see that the red octopuses there in the UI Okay, so here on the left we have a standard I will see the application. It has a rollout resource there is one one replica set deployed and What I'm going to be showing is a resource tab extension, which is a category of extension that Remington mentioned before So if you click the rollout resource, you'll see this new metric step and clicking the metrics tab you'll be Displayed a collection of graphs that is pre-configured. So this actually configured in the back end component of this extension And it allows you to define any Metrics to be extracted from Prometheus So, yeah, you have the latency. So those are metrics that we use that into it, which are the golden signal metrics At the bottom you see pod metrics so CPU and memory and Here at the bottom you see that there is a checkbox That shows thresholds. So here if you hover you see the current Usage of each of the pods belonging to that that that rollout And if you click show thresholds, it will show you the CPU request So this doesn't have CPU limit configured But so it allows you to correlate What is the actual usage and what are you requesting in terms of resource for your application to run? So the idea is allowing different types of correlations. So to show that the next type of correlation this extension Shows you what I'm gonna do. I'm gonna simulate New deployment. So let's say developers worked and they fixed the 500 errors and they reduced the latency to four seconds And the way I'm gonna simulate this I'm just gonna change one of the annotations that we have in this rollout to a different value And when I save this it will trigger a new rollout, right? So you can see now the new replica set got created the nearest a new pod being initiated So once that is done What I'm gonna do is just click promote full and go straight to the end I don't want to go over to each step in this particular rollout All right. So now the rollout is concluded so as I said, I'm simulating a Fixed by the development team and I'm setting the latency to four seconds and If I go and Click back in the rollout resource Let's see what happens now yeah, let's click the metrics extension and Let me pause here for a second now you can you can notice that there's a new icon displaying in the graph and what this Yeah, before that. Sorry, you can already see that the graph was it is displaying that the latency was reduced and This new this new icon what it relates to it it will bring the the Kubernetes event So every Kubernetes event related to your rollout will be displayed. So that's the next correlation that this Particular plug in will allow consumers and users to see so they can correlate when specific Kubernetes event have happened In their application lifecycle and that concludes the metrics extension demo As I said, we run this in production today adding to it in more than 300 clusters so let's see Let's do a dip dive, right and Understand what what is happening behind the scenes here as I said before the proxy extension is Actually working in conjunction with the UI extension. So the UI extension the way it works it will It can communicate with Argo CD API server in every single Operation provided by Argo CD API server can be Leveraged to build any UI extension today. We don't need to use proxy extension But in some cases like in the metrics extension We need to retrieve map this metric data the data points come from Prometheus, right? So we don't have that available in Argo CD API. So the idea here is here is extending the Argo CD API so it will proxy requests from What's going on? Oh That's not a good idea No Java version, please Sorry about that all right and All right, so let's simulate what happens when a request is sent from the UI Extension to the proxy extension. So when a request reaches the API server The first layer that it reaches in the API server in this authentic is this authentication middleware and The authentication middleware Responsibility is to authenticate that request it does so by delegating that task to the session manager Which lives in a different layer inside Argo CD code wave and The request is delegated to the YDC provider pre-configured in your Argo CD instance and that is If that that validates the token and if everything is fine the request is sent back to the authentication middleware And it's handed over to the proxy handler. So the proxy handler The first task it does is is authorized that request and it does so by leveraging the Argo CD or back model So it will Extract information from the user and from from from the incoming request And it will provide to this or back layer in Argo CD and which Which is powered by Casmin and once this policy is enforced then the request is is Sent over to the backend, but before that there's one additional thing that happens is the sanitization So there are some sensitive data that is removed from from the request and Yeah, at the very end the request is finally sent to the backend service. So let's see Very hypothetical scenario if someone wants to build an Argo CD extension that Leverages a proxy extension and let's see how that would look like in terms of requests, right? So the UI part of the extension would have to send a request to the API server That looks like this. So the API server host Slash extensions slash the name of the extension and then whatever that Endpoint will be able to handle. So in this case, I'm exemplifying this using htbb and So if you are familiar with htbb anything slash anything will just return everything that was sent In in the in the request so it will return in the response everything it was sent with the headers and things So it's good for testing especially proxy tools so When that request gets sent then the proxy extension handler will identify that this request is It needs to be handled by the proxy Handler and the name of the extension is htbb And it has an internal configuration that htbb extension needs to be forwarded to this particular URL here Which is which lives outside of the cluster htbb.org So it depends that anything and all the headers that are sent if it's supposed to request it it also sends the the request by and It really works as as a reverse proxy Okay, so let's see what it takes to configure this This htbb in hypothetical extension in Argo CD. So the first thing That needs to be done is enabling the feature. So this is still in alpha So the feature was implemented into in Argo CD 2.7 So if you have Argo CD 2.7 and later you're already able to use and leverage this feature But you have to enable first and you do so by editing or patching this config map Argo CD CMD params CM and Enabling this feature flag. Okay. So the next step is As I said that all the requests to the to the To the back-end service needs to be authorized first and it does so by as I said leveraging our our back model and It will look like this. So the the configuration to enable this htbb Extension to be to be To be authorized need we need to have a proxy policy that looks like this So here what I'm doing. I'm just configuring that read only role To invoke the extension htbb with name htbb and the policy is allowed Okay, once this is ready and applied the last piece of configuration is adding a new entry in the Argo CD CM config map That looks like this. There's a new attribute that was introduced called extension.config which accepts a YAML object in it and Basically, what we do you can configure a list of extensions in it and what we have here is the htbb extension configured targeting back-end service pointing to this specific URL Let's say the back-end requires authentication. So we also allow a configuration to define headers so in this case and this is Something similar that that we use that into it as well. So we are able to define Arbitrary headers here So you can if you if you if you need to define additional headers you can and you can also reference Argo CD secrets So if you're familiar without how our city secrets work if you use this a syntax here It allows to Argo CD will inject that secret from the Argo CD secret So you don't have to add this secret right in the config map because it's a terrible thing to do Alright, let's move on. So this was a Very very simplistic use case. Let me go into something a little bit more complex which is exactly what we have add into it and Yeah, let me explain how the the metrics extension actually works in our company. So We have the deployment model in Argo CD where we have Argo CD instances Sinking clusters remotely, right? So we have more than 300 clusters in the company and 40 Argo CD instances sinking On the and sharing the load over those 300 clusters So in this case, we will have Argo CD applications configure with a destination With different destinations throws the same Argo CD instance will have a collection of applications and each one of them Can be deployed in a different cluster, right? So So the way the the the metrics extension work It needs it needs some additional in a slightly more complex configuration Because in order to retrieve the metric from that particular application, the Prometheus metric actually lives in the same cluster Where the application is deployed? So I cannot deploy the back end part of the metrics extension in the same server Argo CD runs Because the metrics won't be available there. So we need to deploy the the metric server in every single cluster That we sync with Argo CD so In the way this works is that Every request that is sent to the to the to the extension handler It will be required to It will always be made on the context of a an application slash namespace slash project So with that in mind so then the proxy extension can then inspect to which application that Particular request is related to and retrieve the application resource see the destination cluster where that cluster is starting to and then proc user use the Dedicated proxy that will forward the request to that particular cluster. So let's see how this configuration looks like in real life So I don't know if you noticed the service part of the extension accepts an array So here I'm defining a metrics extension as the name of the extension and It has multiple service multiple back-end services and in the in the service Object you can define and you this additional attribute called cluster and you can provide the cluster name and the cluster The server URL for that the for that cluster and the way it works So the every time this config map is saved if you're using Argo CD 2.9 That was released a few days ago. This will be automatically build building a Approxied registry so you don't have to restart the API server anymore and the way it works Argo CD API server will keep this proxy registry in memory it with a list of All proxies for each cluster that it syncs with so that's how it works to Retrieve the the metrics from specific cluster. Okay, so that wraps up my part of the proxy extensions I'll hand back to Remington to conclude the talk. Thanks, Leo All right Great. Well if what we said today resonated with any of you We would love it if you created your own extension The best way to get started with that is to look at the documentation all of the links that we mentioned today are available Via the QR code here But if you're not willing to create your own extension, but you have some ideas for some we would love to hear from you So reach out to us on the Argo CD slack channel Or on the Argo CD github open an issue or create a discussion and give us your thoughts So I think we have a few minutes for some questions. I think there's some microphones in the center Just real quick. So why would you use the metrics extension instead of a Grafana dashboard? Yeah, yeah, the idea is not to compete with Grafana. We also have that internally so our intention was to make that Because as I said, we use the golden signals, right? And our intention was to show that dashboard close to the developers So the developers already they're using Argo CD to debug issues and we wanted to provide easy way to correlate Kubernetes events and also requests and resource consumption For for a specific application. So that's what that was our intention The intention was never compete with Grafana. This is a much more mature project sure sure and then real quick I sounds like there's very few extensions right now Like that ecosystem. You said there's only two extensions right now. No, there's very few is that very few. Yes, correct Yeah, yeah, yeah, so the only that we have developed are the rollouts extension and the timeline extension I guess the metrics extension as well. So yes, very few But yeah, if you have ideas for Thank you First kudos on live demo. That's awesome. They worked a question on the the metrics for example Obviously that was super excited to try it. I haven't tried it yet But I was wondering it looks like it's a fixed window, right? Maybe it's 15 minutes or one hour Whatever it is. I was wondering if the extensions allow for Controls where you can pass in parameters saying hey, I instead of whatever that time window is I want to extend it Yeah, today the the the metrics extension allows you to define To look back In one hour two hours and six hours. That's the configuration. We have this is totally configurable Because we have internal constraints in the company. We just allow users to look back For this time ranges, but this is also configurable So I didn't show the metrics extension configuration all the possibilities there But there's quite a few and to be very honest with you. We need help documenting it So if you're willing to try it out, please reach out. We can we can help you out Thank you. Thank you for the proxy extensions If I don't need like a unique endpoint per cluster that my Argo CD manages Do I have to like paste the same one for each cluster? I have or is there like a default? If you sync Argo CD with different clusters, you would have to add that that in the extension configuration That's the only way that we can Correlate that particular Argo CD application to which cluster it needs to be Sinked and and and to wear it to retrieve the the the metrics extension So I'm not sure if I understood your question. Yeah 100% The other one was But how much information about like who invoked the extension comes through to the proxy extension I know you get past certain headers about like the application But I was curious to see like if I wanted to look back and say like this Who like invoke this extension? Yeah, that's totally doable because when the request reaches the proxy handler at that point the proxy handler knows It has the cookie session. So this is sent to the UI. So the However, if you want to know that specific information in the extension itself, that is today not Part of the request. So what all we provide to the back ends to the back-end service is The the the application that Extension is related to the project and the namespace. So the actual user is not sent over to the To the proxy to the back-end service. Sorry Is that logged in an event somewhere? If that is logged logged in like or like sent out as a Kubernetes event No, I don't think it is no not today All right. I think that is time. So thank you everyone for attending