Replace gitlab-shell generator functions with helm data
This MR is broken down into the following MRs:
- !66 (merged): Helm facility refactoring and query interface
- !67 (merged): Custom Matcher for testing satisfactory replacement of generator functions
- !70 (merged): GitLab Custom Resource wrapper
- TBA: Replacing GitLab shell generator functions with Helm template
Summary
This MR replaces generator functions for GitLab Shell resources with objects that are created using Helm template. In order to do that, this MR also provides a set of tools and utilities that can be generalized and used to replace other generator functions. In that sense it overlaps with !61 (closed) but as it takes a bottom-up approach. It starts with solving the problem of "replacing generator functions" of one specific component, i.e. GitLab Shell, and tries to generalize its solution to other components.
Related issues
This MR closes #34 (closed). It overlaps with #33 (closed) and covers most of its scope. It needs #18 (closed) to function properly. Once finished, it paves the way to work on other similar issues, i.e. "Replace Xyz generator functions with Helm template".
Overview
This MR has multiple pieces, each of which can be a candidate for a separate MR. But they are all needed for the solution to work. Therefore they are bundled here together. Here are the pieces:
- Refactored
Template
: It has been broken down into three parts,Builder
for building the template (Builder pattern),Template
itself, which is trimmed down and now is an object container with selector and editor methods, andQuery
interface which provides semi-fluent methods to select objects fromTemplate
(Facade pattern). - Caching
Query
implementation: A basic implementation ofQuery
interface with caching is provided. This implementation is integrated with the refactoredTemplate
implementation. Considering the frequent calls toTemplate
in reconcile loop, the caching can improve the performance significantly. - Single-instance of
Template
: Rendering GitLab Chart is time consuming. TheGetTemplate
method is added to ensure that it only happens once when operator process is initializing (Singlton pattern). This method reads the required parameters, e.g. location of the Chart, values, release name, etc., from environment variables. So it can be configured not only inside the container but in the CI build as well. - GitLab Custom Resource wrapper (TBA): This wrapper interface guards the operator implementation against the future changes to GitLab Custom Resource (Adapter pattern).
- Replacement matcher: Last but not least, the custom
SatisfyReplacement
matcher can be used to programmatically test the generator function replacement. A basic implementation of the matcher is provided.
Further work
- More query methods for different object types and criteria must be added to
Query
interface. The existing methods can be used as a template. Therefore it is going to be a fairly straightforward task. - More cases must be added to
SatisfyReplacement
matcher to cover different object types. The definition of "satisfactory replacement" must be clarified. For example, at the moment, a strict definition of satisfactory for Deployment objects fails the test case. See the caveats for more discussion on this.
Example usage
Here is how ShellDeployment
generator function is used like this:
shell := gitlabctl.ShellDeployment(cr)
See controllers/gitlab_controller.go#L582
.
The replacement will look like this:
shell := template.Query().DeploymentByComponent("gitlab-shell")
And to verify that if the replacement works, it can tested like this:
generated := gitlabctl.ShellDeployment(gitlab)
templated := template.Query().DeploymentByComponent("gitlab-shell")
Expect(templated).NotTo(BeNil())
Expect(templated).To(SatisfyReplacement(generated))
Caveats
The objects that are created with generator functions are not exactly similar to the ones that are build with Helm template, mostly because GitLab Chart uses a different convention. Here are a few examples:
- Generator functions use a
app.kubernetes.io/*
labels. - Generator functions use different names for components, e.g.
gitlab-shell
is namedshell
. - Some of the details of object specs differ between the the generator functions and template, for example
securityContext
Not all of these differences are important, but some are. That is why a clear definition of satisfactory replacement is needed. The difference that are important need manual override.