 So we're going to go ahead and get started. So by way of introduction, I'm Jonathan Burkan. This is Simon Leung. We both work for IBM as core contributors on Cloud Foundry. So we work on Cloud Foundry every day, contributing code to the open source components. What we're here to talk about today are CLI plugins for the command line interface for Cloud Foundry. So these are sort of a recent development relatively that lets you do interesting things to the CLI. So let's go ahead and jump right in. So what exactly is a Cloud Foundry CLI plugin? So the plugin framework is an extensible framework that we added to the command line interface to allow users, operators, admins, cloud providers, anybody who uses Cloud Foundry to implement novel functionality. So if the CLI, if you want it to do something that it doesn't do yet, or if you want it to do something that maybe isn't really Cloud Foundry specific, but you have a need for, this capability allows you to implement that functionality and distribute that functionality to your users in a way that's very easy to consume. Physically, what it is, is a program that's written in Go that compiles to a GoLang binary that implements the CLI plugin interface. And we have documentation and examples available online, as we'll talk about that in a bit, if you're interested in developing your own. What can they be used for? So they can be used for pretty much anything, our target use cases were for users, admins, and Cloud Foundry developers. For users, it can be used to manage app deployment. So if you want to deploy your app in a funny way, like in easy use cases, blue-green deploy. So you have zero downtime. So you can write a plugin that'll push an app with a different name and then switch traffic over once it's up and running so you don't have any downtime when deploying any versions of things. You could write a plugin that lets you interact with some apps that's running on top of Cloud Foundry. So if to turn things on and off, scale it up, scale it down, push buttons that are specific to your particular app's functionality, you could write a plugin that'll do that. For admins, it lets them automate maybe specific interactions with the Cloud Foundry deployment itself that they use often. So managing quotas, things like that, and maybe things that are specific to your particular to Cloud Foundry deployment. And then our particular use case that we're most familiar with ourselves as Cloud Foundry developers is for developers that use it to work on Cloud Foundry itself. So we use them a lot for testing new features. If there's some new feature that a CLA command hasn't been written for it yet, writing a plugin allows us to rapidly prototype an easy way to interact with that new feature. So more of the people in the development community can use it and try it out before it's finished. And I'm going to cover a couple of use cases of things that we have actually written plugins and used for. And then I'll go over a couple of potential use cases of things you might be interested in writing a plugin for. So one example plugin that we've actually used is CFStackChanger. So for those of you who are not familiar with what a Cloud Foundry stack is, a Cloud Foundry stack is an OS image that a container that your application runs on uses as sort of its base. And that's generally always some flavor of Ubuntu. Anyway, several months back, Lucid, an older version of Ubuntu, was being sunset, meaning that Canonical was no longer going to support it. They were going to stop releasing updates for it. And that was a problem because many, many, many stacks from older times were based on Lucid. And these were still running in production environments. If you don't push a new version of your app, it's still going to have the same old stack. And so every one of these running apps that were still using Lucid on a Cloud Foundry deployment needed to be switched. And then cases of larger Cloud Foundry deployments, this could be hundreds, maybe even thousands of apps. And if you wanted to do this manually, what this would entail would deleting and repushing every instance of every app that was on the entire deployment that was still using this old stack. And that's obviously kind of painful, not really a very optimal solution. So if you wanted to automate that a little bit, you could maybe write a script, but that has its own problems. You're probably going to have information on that script, specific parameters that are particular to your Cloud Foundry deployment. If for some reason your admins are trying to run this on a Linux environment, that's going to cause problems. And it has to be distributed to all these people. So that's easier than doing it manually, but not really ideal. So we were to plug in for it. So our plug-in was called CFStackChanger, very original name. Pretty simple plug-in really only has two commands. One lists all of the apps that are currently running that were still using the old stack. And then we had one that updates them. And there's a little bit of parameters that let you specify specific orgs or spaces, whatnot. And this was easy to distribute. We ran it up on the plug-in repository, which Simon will mention in a minute. It was easy to distribute anywhere that the CLI is capable of running. We had a binary that was easily downloadable and installable. You don't have any dependencies or anything. Anywhere the CLI will run this plug-in will run. And it was simple to use. So both developers in the Cloud Foundry community, as well as admins in several of the companies that actually manage Clouds, Pivotal, IBM, BlueMix, use this plug-in to switch over all of their apps to be running on the new stack. Sort of a one-time use plug-in. But for the use case, it was a pretty good solution. Another plug-in we've used is the V3 CLI plug-in. So for those of you who are not familiar with V3, V3 is the new Cloud Foundry Cloud Controller API that's currently under active development. It features new endpoints, new functionalities, new abstractions, new object types, a whole bunch of new stuff that's coming out, but is currently under active development. So it changes pretty much every day. And before we had a plug-in for it, in order to interact with it, in order to test, when I implemented a new feature, you would have to do it manually. So this would entail writing a whole bunch of core requests by hand that was super painful and basically awful. And in addition, because this is under active development, the API changed pretty much literally every day. You would stop working on something, come back the next day, somebody else would have changed it and you're like, okay, I don't even know how to interact with it, I don't even know how to push an app or whatever. So I'd have to go figure out what changed, and then either keep writing the core requests or if I wrote a script, I'd have to go in and change the script. So that was kind of painful. So we wrote a plug-in that handles it for us. So this is V3 CLI. We implemented basically a dozen commands that are relatively correspond to existing commands in V2, let's you push apps, processes, which are a new thing in V3 tasks, which are a new thing in V3, let's you manipulate them by services to them and so on. And this is much easier, obviously, than writing the core requests manually. And it's easier to update, whereas before if you had a script, you'd have to go figure out what changed, change the script, distribute the script again. Here, because of the infrastructure we've developed to distribute plug-ins, you just uninstall the old version, hold down the new version, it's good to go. Don't need to change anything. Now to extend this into some potential use cases that users and cloud providers might be interested in, the sort of use case that you might be interested in is say you're a Cloud Foundry provider and you're trying to provide some sort of custom functionality to your users. We've provided the infrastructure necessary for you to do that by hosting a repository server, which I will talk about in a moment, on your Cloud Foundry infrastructure. And on that thing you might host plug-ins for your admins to manage your cloud. Maybe some command and control type plug-ins. If you have custom functionality that's specific to your particular Cloud Foundry deployment, you could add plug-ins to interact with that functionality. You could add security plug-ins, say you have some specific needs for security or a specific kind of authentication. You could write a plug-in that handles that, integrate it into the CFCLI that your users are probably already using, and go from there. This will all be accessible straight from the CLI, so it's all nicely contained in one place that your Cloud Foundry users are already using. So now it's great, you know you've got an idea for a plug-in. Now Simon's gonna talk a little bit about how to write a plug-in and how to distribute it to users. Well, thank you Jonathan for showing us what a plug-in is and what does it do for other use cases. Now let's take a look at what does a plug-in look like in code, a closer look. But don't worry, I'm not gonna hear to give you a tutorial on how to write a plug-in. I simply just want to show you how easy it is to create one. So a plug-in, just like Jonathan said, is written in Golang. For some of you might have never seen any GoCo and it can be a little bit intimidating. But in my opinion, it's one of the languages that's easier to read and learn. The syntax itself is a lot like Java and JavaScript and C as well. So for someone who never seen Go, like if you look at the code, at least look familiar. And there are only three simple methods for you to implement to interface with the CFCI. The first one is get metadata. This is where you put all your command names, you declare them, and also you declare the usage tags. These are the tags that you see when you type CF command help. And also there's a run command. The run command contains all the important code. They are the main functionality of your plugins. And the last one is the main. The main basically is just a bootstrapper. Typically it's only a one line code to bootstrap your plug-in. So what we are looking at right now is a complete sample of a plug-in. There's 39 lines of code. And if we take out the standard Go import statement at the top and a lot of curly braces, it's even smaller. And there are three functions. And if we look at, let's say the get metadata, from here you can see like all I did was declare the name of the plug-in and then the version. And down below we have some metadata just for the help usage. And then we have the run function. In here you declare what you implement the functionality of your plug-in. It can be a single line code or a thousand lines code. It all depends on how complex the plug-in is. And at last we have the main. And basically what you do here is you use the start command, the start method that's provided by the framework. What it does is it starts up the plug-in and then you communicate with the Cfsoi and exchange some metadata. And this is it. This is all it is. You make a plug-in, this is all the interface that you have to implement. This is Go code so you can compile it and install into Cfsoi as a plug-in. As for the plug-in framework itself, we do provide you a list of API interface for you to do things with. For example, you can get the current organization, you get the username. And we have API for you to look at, to get the endpoint for some of the CF services. Some of these APIs return a simple string or Boolean and others return your structure and provide you more information to work with. This list actually can cover the most common use case for you. But as you know, like the Cfsoi itself is growing every single day. There's new commands being developed all the time. Last time I trapped, I think there's more than 130 commands in the Cfsoi. And that's why we have, provide you two special commands. The Cfsoi command without terminal output and the Cfsoi command. Both of these commands, they do very similar thing. It allows you to call any Cfsoi command and as a method return output, it returns through the Cfsoi terminal output as a string array. And the difference between these two commands is one of these command will output a string array, echo that back to the terminal and the other one wouldn't. So, at this point, we have talk about how the code is like and you have an idea of what the API interface can do for you. Let's talk about how do we dis-build the Cfsoi plugins. So the two main questions, like when you think about dis-building, it's like how do people learn about your plugin or how do they install them? Is it easy for them to install them? You don't want a bad user experience, right? For Cfsoi, there's actually a few methods for you to install the plugin. The first one is straightforward. If you have the gold binary file, you can just install it right from there. It's simple, it's straightforward, it's easy. But the only problem is the user will somehow have to either download or obtain the binary in advance and in order to do that, they would need to learn about your plugin in the first place. The second way to install is some improvement. It allows the user a lot to download the binary by just providing the URL and the COI will download the plugin binary from URL for you. But the problem remains because the user, in order to know about the URL, the user needs to learn about your plugin. They need to know about it somehow. So it sounds like what we really, really want is some kind of app store on your phone, right? Like a list of, like instead of apps, it's for plugins. So something like this, right, for the CLI and then we have some kind of backend service, server that has a list of plugins that you know about. And the CLI can easily request, say, hey, what do you have while you're tracking? And then the repository can return the list of plugins and say, this is what I have. And then CLI say, can I have one of those plugins that you're hosting? And the repository will provide CLI with the binary. And this is what we want and this is what we created, the plugin repository. Just like the graph earlier I showed you, this is a backend server that the CLI knows how to interact with. It basically holds a list of plugins it knows about and it allows the CLI to find and install the plugin with two simple commands. So what are some of the benefits of using this repository? Well, the first one is simple. It allows the user to find and install the plugin without you leaving CLI contacts. That leads to good user experience. And then multiple reports can be tracked. So by default the CLI come with a single report that is hosted by the CLI. It contains a list of plugins that's shared by the open source community and it's available to the general public for free. But for example, if I'm, let's say, I'm an IBM Brumas user and I know Brumas has a plugin repository that I can use for plugins that's specific to that environment. I can track that, besides tracking the community plugin, I can also track the Brumas plugin and I can simply just add the repository with this command. The CF add plugin repo and then I can name it anything I want and then provide the URL to the Brumas repository. And this also brings us to the next point. Anyone can host a plugin repository. So the plugin repository itself is an open source project. It's developed by the CLI team. The project itself is out of the box ready to use is a Go server, it's written in Go. You can download or clone this repository. Since it's in Go, you can compile it and just run the binary as a standalone program. Or, and the option is like, this is cloud ready. So you can just clone it and push it and tie it into Cloud Foundry and you can run it from there. If you wanna see a sample of the repository in action, you can just go to the URL right here. Right here, http, http, pluginstore, cloudfoundry.org. If you open that link in the browser, you will present you a nice list of plugins that's being tracked by the community repo. And as I said earlier, this thing is ready to use right out of the box. So you can use it as it is, but another option is you can use it as an architecture reference. What you have to do is you have to keep the interface between the CfCLI and the repo, but you can change the repo to add any function that you want, change it any way that you want. And you may ask, why do I want to host a custom repository? So in this last part of the presentation, we're gonna explore some of the use case, why do you want a custom repository? As I mentioned earlier, some of the cloud provider like Brumace, Pwps, they might have their own repository, provide some custom plugins. It looks like something like this. They have a custom repository that hosts public plugins that's available to anyone, but they might also have a backend store that has all the private plugins stored in there, and that's only people that's using the service and access to that. So in order to secure that, they can do something like this. They can have an authentication plugin installed in the CLI, and with this plugin, it issued the request and credentials to the custom repository. After properly authenticated, the repository can go to the backend service and ask for the private plugins and provide that back to the CFCLI. So this function is not available right out of the box with the open source repository. In order to do something like this, you're gonna have to change the code somehow and tailor to your need, so that's why you need to host a custom repository. Another example is maybe you're a cloud provider and you have, in your backend CF, you have divided into different regions. You have Asia, Europe, North America, and each of these regions provide different kind of feature sets to its user, and you only want these feature sets available to the people in a specific region, right? And you don't want a user in North America trying to hit a service and that's intended for Asia and get an error and say, hey, you cannot use this function. If you wanna use it, you're gonna have to move to Asia. That's not good. So what you can do is, you can have a custom repository, and again, we have some kind of authentication plugin that provide credential and location data, and with those data, the custom repo can provide the correct plugin, and if you're using Asia, you will provide Asia CF, you can provide the plugin Asia. So the plugin itself knows how to interface with the correct backend, and this is great because as you roll out more features to each backend, you can simply just update your plugins, and the user doesn't need to go out and download any updates. Everything is transparent to them. As long as they run the command, like the plugin will either update itself or stream the correct plugin back to the CF for them. And with this, it concludes this session of the talk, and to wrap this up, there's a lot of information online available. If you want to learn about plugins, development, or just plugins itself, and also if you want to look at the repository, this is the address. If you have any questions about plugin development or plugins in general, you can reach out to me or Jonathan personally, or you can go to the CLI team on the Slack channel. They're always available. There's always someone available to answer questions. So now if you have any questions, we can answer them, and thank you for being here. I will leave this screen on. Sorry guys, I can't fit here. Could you come up for the microphone? Test, okay. You said we could use that to have some kind of custom login, for example. In our company, it's usually a single sign-ons based on tokens. So could I actually have the used plugins to overwrite the standard CF login to have a token-based one? Because we have PKI cards, and all their certificates for the users are stored on those. Thus, we would just read it out, send it against Cloud Foundry to authenticate. Okay, so unfortunately at this time, we don't allow you to overwrite commands entirely, so you wouldn't be able to re-implement CF login with your own custom thing. You could add, in parallel, CF custom login that would support that, and it would have to be named something different. To add to that, so command overwriting is a feature we heard from different people they want. It helps if you go to the COI repo and file issues that this is a feature request, and this is what I want, and you know people wanting them, then the team might just implement them. Any other questions? Okay, so if you have any question, you know where to find us. Thank you very much. Thank you. Thank you.