mayadata-io / mayadata-io/d-operators
design resource mapped by versions & feature flags
Open
@AmitKumarDas is already working on this.
Since Apr 6, 2020.
dao
design
feature flag
metac
use case
version
- Dominant language
- Go
- Stars
- 10
- Forks
- 6
- PR merge metrics
- No merged PRs in 30d
Description
In this issue I propose a design to build desired k8s resources that can be selected by their versions &/or feature flags.
NOTE: Let us take the case of k8s resource with kind Foo
NOTE: In real world, Foo can be replaced by k8s resource e.g. Deployment, ClusterRole, etc
// the folder structure might look like this
projectroot
|_ controller
|_ my-cool-controller/
|_ reconciler.go
|_ reconciler_test.go
|_ common
|_ selector/
|_ selector.go
|_ resources
|_ foo
|_ foo.go
|_ foo_test.go
|_ types
|_ foo.go
|_ foo_test.go
// in common/selector/selector.go
type TagOperator string
const (
TagOperatorOR TagOperator = "OR"
TagOperatorAND TagOperator = "AND"
)
type Tag struct {
Keys []string
Operator TagOperator
}
type Selection struct {
Version string
FeatureFlag string
Tag Tag
}
type Terms struct {
Versions map[string]bool
FeatureFlags map[string]bool
Tags map[string]bool
}
func (s Selection) IsMatch(terms Terms) bool {
// ...
}
// in resources/foo/foo.go
import (
"project/common/selector"
)
type Config struct {
Selector selector.Selection
DesiredName string
DesiredNamespace string
DesiredLabels map[string]string
DesiredAnnotations map[string]string
}
type Foo struct {
selector selector.Selection
}
func New(config Config) *Foo {
return &Foo {selector: config.Selector}
}
func (f *Foo) IsSelectionMatch(terms selector.Terms) bool {
return f.selector.IsMatch(terms)
}
func (f *Foo) GetDesired() (*unstructured.Unstructured, error) {
fns := []func() (*unstructured.Unstructured, bool) {
f.getDesiredTypeA,
}
for _, fn := range fns {
desired, ok := fn()
if ok {
return desired, nil
}
}
return nil, errors.Errorf("Can't find desired Foo with conf %+v", f.conf)
}
func (f *Foo) getDesiredTypeA() (*unstructured.Unstructured, bool) {
supportedVersions := map[string]bool{
"1.9", true,
}
supportedFeatureFlags := map[string]bool{
"alpha": true,
"beta": true,
"production": true,
}
supportedTags := map[string]bool {
"linux": true,
"ubuntu-18.04": true,
}
terms := selector.Terms{
Versions: supportedVersions,
FeatureFlags: supportedFlags,
Tags: supportedTags,
}
if !f.IsSelectionMatch(terms) {
return nil, false
}
return &unstructured.Unstructured{
Object: map[string]interface{}{
"kind": Foo,
"apiVersion": "example.io/v1alpha1",
},
}, nil
}
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.