Go in the .NET Company: How to Save Some Time
And here it is, the moment has come. You are focusing on your work and coming up with 'definitely that' idea capable of solving the problem. And then, you start working on it. What could go wrong? Only the sound of an incoming message on Slack. Sounds familiar, doesn't it?
You open the message and see:
Or, something like this:
Not a big deal. It's easy and takes only a few moments to open a VPN server admin panel and press a button or to create a personal developer’s domain. Let's get back to the idea. Which idea? I've been working on a routine task and forgot something important. Oh well, I don't have any idea anymore. That’s end.
Just kidding, no worries.
Actually, it all started with domains, so may lead to a quite logical question: why not use ngrok or any existing service like it?
Well, first of all, we want the traffic to go only through our own trusted servers. Secondly, by default, all development services have disallowed index robots.txt, authentication, and a few other things enabled. This is done on the gateway server to avoid the human factor. And thirdly, using the company's domain is more pleasant.
Directing a domain to a developer's computer isn't really complicated. We have a wildcard record at the DNS level pointing to our gateway, and we can get the developer's IP address from the VPN server admin panel (or simply ask them). The rest is to create a correct config on the load balancer, which is also a reverse proxy server, and voila — it's done! But:
- Created configurations can become outdated. The domain is required now, but not after some time. However, it still sticks out there, someone can access it, and at best, get a timeout. If not the default IIS page.
- The developer may need full-SSL mode, when a secure connection is present on all hosts that traffic passes through (see the picture). It is a mandatory condition for the operation of payment gateway and Azure AD connect, for example.
- If you ask the developer, if the domain is still in use, it will turn out that it's always used for something. And when it lays idle, it is especially needed.
It's already clear that to accomplish what seems like a simple task, we have lots of things to do and even more to keep in mind. 3-4 domains configured like this typically take as much time as playing a big round of table tennis. Oops, sorry, I meant as much time as completing a very important business task. It literally screams for automation!
The first step is the definition of what the application should and shouldn't provide. The bot should allow a developer to create a load balancer configuration by submitting a request and storing the configuration details in a database with a creation date. Thirteen days after creation, the bot notifies the user that the domain will be deleted, and on the 14th day, the configuration removed, and the user notified. The bot also has to allow the user to modify proxy parameters (like authorization on/off, full-SSL mode, etc.) but not the domain name. Finally, if 14 days are not enough, the bot can provide an option to extend the domain lifetime.
As a DevOps engineer, not a developer, I code in Go. Let the developers write in .NET. How does it work? We use the Slack Events API. RTM is no longer recommended, and that's the way it is. We filter only mentions of the bot, everything else is irrelevant. Then the command processor comes into play. If a command is recognized, the bot executes it, otherwise, it mysteriously remains silent (we later added a help text output).
We check who sent us the message, take the first letter of their name and surname. They will be the domain name. So, for example, a domain for user John Doe would look like j-doe.ukad.dev. We perform the necessary checks. For example, we know all the addresses of office networks and check if the address belongs to these networks. The most common mistake, as practice has shown, is that the user enters the wrong IP address. Then we proceed with the algorithm, with some modifications, nothing interesting.
We named the bot Ooops. Originally it was supposed to be Ops, because of operations, and then, oops, something went wrong. Here is how the message looks like:
Thus, we made a solution that frees developers from waiting for the admin department to become available and create a domain for them while not sacrificing security. It's been working in our company for about a year in this form. Even the bug with the repeated notification wasn't particularly concerning.
The notification about the upcoming domain deletion was sent twice: one day before the deletion, and the next day at the moment of deletion. But very few people were concerned about it, as the logic was working. In fact, what bothered users more was the time format. It was the standard time format in Go, without any transformations. And for some reason, everyone paid attention to it. I added it to the backlog and forgot about it for a year.
About a year later, I realized that the situation repeated itself, but with VPN configurations. At that time, the war began, and most of the users changed their work computers. Then, on the fly, I added the logic of sending a link to the VPN configuration in a private message to the user upon request. Fortunately, our VPN server has an API and an ability of generating one-time links individually for each user.
We sent the link in private messages and the notification about the sent link displays in the thread. We prioritize security.
In such a state, the bot would have remained indefinitely if one of the developers doesn't write the following to me:
It turns out that I forgot about Markdown formatting when I was writing the bot. If you copy text from somewhere that has formatting, and then paste it into Slack, Slack retains the formatting. In Markdown, it looks like this: *bold*, _italic_, ~strikethrough~. And naturally, the message sent to the bot looked like this: <@U123456> create *127.0.0.1*, where U123456 is the bot user's ID in Slack.
Later, I discovered that it's impossible to fully fix this bug within the bot itself because the framework does not provide direct access to the complete message. It has its own command processor where I can retrieve message parameters, but not the entire message itself. In other words, it is possible to fix the problem when the message comes in the form of <@U123456> create *127.0.0.1*. However, even if the command itself is formatted too, the fix will not work. For example, in this case: <@U123456> *create 127.0.0.1*.
To fix this bug, I created a pull request in the framework repository. It wasn't too hard: I added options to remove formatting characters from the message. Additionally, I refactored the bot code a bit, made short commands aliases for their full forms, fixed the display of time from the "go" format to the local format, and added the ability to change the service port on the developer's computer. Previously, only standard ports 80/443 were available. And, of course, I didn't forget about myself and added a couple of commands for the VPN server that are only available to administrative users.
So there we have it, folks! With Ooops bot, we can save a boatload of time. It's amazing how a little bit of automation can go a long way in making our lives easier. And yes, we use Go in the .NET company. Who says we can't mix different technologies and make them work together? With the right tools and mindset, anything is possible. And, the most important! Now the routine doesn't distract me from pure creativity and brilliant ideas.
Author: Bogdan Kosarevskyi
DevOps at UKAD
CI/CD processes update. Step 1: Planning and Preparations
In 2020, it was almost impossible to find a project without IaC, microservices, blockchain, VR, and other stuff from the description, as well as without AWS, Azure, or GCloud mentioned in the tech stack...
Headless CMS for beginners
If you're into web development or doing business online, you may know about content management systems. Now, we want to speak about the cutting-edge solution related to this field — Headless CMS. To be more specific, we also reviewed Contentful, Storyblock, and Strapi, as the most popular portals UKAD works with
- Headless CMS
- CMS Development