For Etcd, make the address it should listen on configurable via
```
ectd := &Etcd{
Address: &url.URL{Scheme: "http", Host: "localhost:12345"},
}
```
If not specified, it will internally use the `DefaultAddressManager` do
find a free port to listen on.
To make our framework easier to use, we now use a `CertDir` struct
instead of the `CertDirManager` to create and destroy (potentially
temporary) directories.
This `CertDir` holds either one of or both a path to a dir (as string)
and a function which can clean up the directory. In the default case a
temporary directory is created and cleaned up. For any other use case
users can just specify the path to an existing directory or override the
cleanup function.
- Mostly documenting properties of APIServer (for the most part Etcd has
the same properties).
- Adding executable examples, some off which run as additional test
cases.
You no longer have to pass a hostname to initialise the addressmanager.
The DefaultAddressManager always listens on localhost. If you want to
listen on some other interface, you can use a different AddressManager.
We now return an error when stopping of a process times out, before that
resulted in a panic. Now a caller of `Stop()` can catch an handle this
error.
Also, the timeouts for stopping and starting a process is now
configurable, for example by:
```
etcd := &test.APIServer{
StartTimeout: 12 * time.Second,
StopTimeout: 5 * time.Second,
}
```
In both Etcd and APIServer we return a descriptive Error when the
`URL()` method is called before `Start()` and thus the AddressManager is
not yet initialized.
Right now the ControlPlane is actually just a thin layer around
APIServer, this is the oly process we care for right now. Now that we
only have one process to start, we can remove the parallel starting
logic.
In case we bring in more processes again this commit can just be reverted.
We can move all of the logic out of the constructors and psuh them into
`ensureInitialized()` of both APIServer and Etcd.
By doing so, the constructors are actually not needed anymore.
We however kept the constructor for the ControlPlane for convinience.
The APIServer constructor previously required careful configuration. Now
it takes no arguments, and gives you an APIServer that you can
`.Start()`. If you want to configure it, you still can. For example, you
can set the environment variable `TEST_ASSET_KUBE_APISERVER` to the path
to your apiserver binary, or you can override the PathFinder in go code:
```
myAPIServer := test.NewAPIServer()
myAPIServer.PathFinder = func(_ string) string {
return "/path/to/my/apiserver/binary"
}
```
Previously the responsibility of choosing a port that the APIServer
could listen on was left to the caller. Now APIServer delegates that
responsibility to an AddressManager. By default you get a random unused
port on localhost. If you want to customize that behaviour, you can
overwrite the AddressManager:
```
myAPIServer := test.NewAPIServer()
myAPIServer.AddressManager = myAddressManager
```
If this is a common request, then in future we might provide some common
custom AddressManagers.