Since the uw exchange project, uwwi has had a development environment, but it’s been at best a very poor facsimile of the real thing.
More recently, I’ve been pouring time into making it a more realistic environment for testing our core components.
From time to time, we must make changes to the core infrastructure components:
- the domain controllers themselves, whether that’s the operating system, or other significant changes
- fuzzy_kiwi, the account provisioning agent
- slurpee, the group provisioning agent
- subman, the service lifecycle agent
- ilm, the directory synchronization agent
Testing those changes, up until very soon in the future, has been hard, and involved finding test cases within the production environment.v
Of course, some changes are of a nature that you can’t test them in production–which is why a development environment is required.
In fact, there are a slew of ilm changes queued up in my task list which are blocked because I currently have no safe way to test them before implementation.
We plan to upgrade the UWWI DCs to Windows Server 2008 sometime in the coming months, but first, we wanted to test that WS2008 didn’t cause any problems with our core infrastructure components. Would fuzzy_kiwi run on WS2008?
Getting fuzzy_kiwi installed and running in a separate domain instance was an adventure of its own, because there was no existing documentation on getting it running (there is now). But I’ll skip that story. 🙂
However, there are a couple interesting things here: I’ve made some key changes to fuzzy_kiwi so that it is now self-aware of where it is running. If it detects that it is running in our development domain, then it does things differently. Otherwise, it acts normally. In our development domain, fuzzy_kiwi creates accounts disabled and ignores the password it is given. Instead, it asserts its own very long, random password–and each instance has a new random password. That was a trick I’ll get to later. There is also a new feature in fuzzy_kiwi where some accounts can be ‘untouchable’ by kiwi requests. This is needed especially in dogfood where you want the administrators to have different passwords on their accounts and you don’t want those accounts to be disabled. It wouldn’t do to have the only folks who can make changes locked out of that domain. 🙂
Getting back to the random password in our dev environment feature, I made a few interesting discoveries about coding such a thing. I knew from my own math and computer science coursework background that generating truly random numbers was a very difficult thing. And generating a random password is at its heart all about generating random numbers. Without going into the details of the algorithm I used (that wouldn’t be very smart, now would it?), I do want to make a few remarks about some of the building blocks.
Within the .net framework, I came across the System.Random class and its System.Random.Next method as a way of generating random numbers. The class and method are very easy to use, and even give you a way to specify a lower and upper bound on the random integer returned. It wasn’t until I started looking at what it generated that I saw a significant problem with the class: by default, it generates exactly the same sequence of “random” numbers on successive runs (within a suitably short period of time). This is because the algorithm used behind the class focuses on randomness within the sequence it generates–not randomness of what is used to initially generate the sequence. By default, the class “seeds” the sequence by using the tick count of the time you instantiate it. But in practice, that means that there is often duplication on subsequent runs. You can supply your own “seed”, but then you are stuck a circular problem: generating a random seed so you can get a random number.
So I set off looking for something better. And I came across the System.Security.Cryptography.RNGCryptoServiceProvider class and its System.Security.Cryptography.RNGCryptoServiceProvider.GetBytes method. This class is a bit harder to use than System.Random. It requires an array of bytes as a method of data output. Output is a random number from 0-255 (it’s a byte after all), and there’s a slight variant method of .GetNonZeroBytes which outputs random numbers from 1-256. This option doesn’t allow you to ask for lower and upper bounds, so you end up performing modulo operations on the output (assuming you want something smaller than 256) and addition/subtraction to fit your needs. From what I’ve seen the numbers generated are pretty random, and there isn’t duplication on successive runs like with System.Random.
This post is probably beyond what most folks are interested in, but you never know what will be useful, or be a catalyst to generate that critical feedback loop that brings in vitally relevant information. I’m likely to have more technically detailed and arcane posts in a vein similar to this in the future. In an effort to balance this likely trend, I’ll try to keep the more technically heavy content later in the post, and keep the more widely useful and relevant information near the top.