flagr icon indicating copy to clipboard operation
flagr copied to clipboard

Templates for flag creation

Open sesquipedalian-dev opened this issue 3 years ago • 0 comments

Currently in the flagr API, there is an option to provide a 'template' in the call to create a flag. The flagr UI uses this with a drop-down menu, where there is one option to create a 'simple boolean flag', that comes pre-populated with a segment and variant. All of this is hard-coded to a specific example of this simple boolean flag. I'm wondering if it would be a useful feature to expand the idea of a template.

I'm imagining from the point of view of the flagr UI, the server could send up a list of templates it supports, which would be displayed in the drop-down menu for creating a flag. When you picked a different template than the default one, the UI could have additional input boxes for other fields in the template (e.g. rollout percent of the default segment that gets created). When you submitted the flag creation, it would send the template name and any additional template parameters. I imagine the template being defined basically like a go template (https://golang.org/pkg/text/template/) for the JSON representation of a flag. The server would run through the constituent objects of the flag (segments, variants, tags) and save them all in a big GORM transaction, giving you a flag with some default things set up without the user having to do all those steps manually in the UI.

You'd want the templates to be configurable on the server side so that different users of flagr could set up templates the way they want. This might be a full-fledged resource in the swagger data model, or something loaded from flat files, or maybe just env vars.

Our team was close to implementing something like this for a validation problem we're looking into (we want to be able to require that flags have a certain type of tag when enabled), but it doesn't quite work. Curious about gauging if this would be a useful feature to contribute to the project independent of the use case we had. Here's an experimental branch I was working on: https://github.com/checkr/flagr/tree/sa/flag-template-experiment

Expected Behavior

People running flagr server should be able to configure additional flag templates with different parameters for creating flags. When a user selects a different template from the drop-down on flagr UI's home page, they should be prompted for whatever template variables are supported, and when submitted the server would render the template from there.

Current Behavior

Currently the 'template' idea is just hard-coded to this simple boolean template, and doesn't allow for configuring different templates for different flagr deployments. The UI only has a hard-coded field for description.

Possible Solution

I'm imaging that we would define a simple data structure for templates like so:

type FlagTemplateField struct {
  Name string  // identifier for the field
  UIPlaceholderText string // greyed out placeholder text to display in the UI for filling in this field
  Required boolean // if true the user must fill in this field to use the template
}

type FlagTemplate struct {
  Name string // identifier for the template, this would be the value passed for 'template' in the create flag API
  UIDropDownText string // text to display in the UI drop down explaining this template / maybe a tooltip text also?
  Fields []FlagTemplateField
}

this could be defined in the swagger. We'd also add a generic 'params' field to the flagCreation operation in swagger that's just an arbitrary object type.

Supported templates could be loaded from their JSON representation in an environment variable. The frontend could fetch the available templates with a new generated swagger endpoint for GETting the supported templates. The frontend would use this struct to populate the drop-down list and generate an input field for each FlagTemplateField when the drop-down option is selected. We'd add a new button for executing the flag creation.

The server could use the Go template with the params passed in to the flagCreation operation to generate a JSON representation of a flag. Then you unmarshal into a DB flag object, and create all the dependent objects in the transaction, and finally save the flag (prototype here: https://github.com/checkr/flagr/blob/sa/flag-template-experiment/pkg/handler/crud_flag_creation.go#L45).

Thus you'd get a flag created with whatever default objects you want, as defined by your templates, and users can switch around to a few different templates that you had set up.

Steps to Reproduce (for bugs)

N/A

Context

What our team was trying to solve was that we want enabled flags to always have a tag matching a certain regex format (e.g. JIRA:EPLT) so we can indicate the flag is owned by a particular group in our engineering team. One thought for this was to use the templates to have the user specify the team as an argument to template creation, then have the template create the needed tag. We have a different solution for that we'll open a PR for soon, involving configurable https://github.com/Knetic/govaluate expressions when a flag is enabled or updated in the API.

sesquipedalian-dev avatar Jan 06 '21 04:01 sesquipedalian-dev