flipt-io / flipt Goto Github PK
View Code? Open in Web Editor NEWEnterprise-ready, GitOps enabled, CloudNative feature management solution
Home Page: https://flipt.io
License: GNU General Public License v3.0
Enterprise-ready, GitOps enabled, CloudNative feature management solution
Home Page: https://flipt.io
License: GNU General Public License v3.0
The next release of go will probably enable modules by default. We should update Flipt to remain current and use modules.
I previously tried to do this and ran into some issues with GRPC or GRPC Gateway (I can't remember), so I would like to try again and document any issues if there are still any blockers.
It seems grpc-go should support modules just fine: https://github.com/grpc/grpc-go#installation
Going to try the approach here: https://blog.callr.tech/migrating-from-dep-to-go-1.11-modules/
Describe the solution you'd like
Would like to support evaluation caching for rule based evaluation. IE https://flipt.dev/concepts/#evaluation
This would behave similarly to what was added in #6, but would likely be more complex since there are multiple entities that need to be cached (segments, distributions, rules, variants, etc) and invalidated.
One approach is to just cache the evaluation result and not the actual individual actors (noted above), but would have to come up with a scheme to invalidate this cached result if any of the above changed.
Maybe not a top priority right now...but do you think there's a way to batch-evaluate a set of flags?
I plan to use the REST API instead of grpc—so like, it'd be nice if I could send a single request with a set of flags to be evaluated instead of 1 request per flag. Just to avoid all the roundtrips.
Thoughts?
Would like a better logo and favicon but I'm not good at design
Something that represents feature flagging? flags? toggles?
Is your feature request related to a problem? Please describe.
I need to toggle a feature in response to a certain parameter, e.g. I have 5 admin emails and if the API call sends one of them in the validate call, the feature should be toggled on by responding with true.
Currently I create a segment for each with the constraint email to be equal and the flag returns true for these segments. But setting several emails to the segment as constraints, since it checks if the given email is equal to all of them does not work. Only if just one email is provided.
Describe the solution you'd like
Maybe set the option of the segment from always match all to be switchable to match one of. That way, I would only need to create one segment, give them all the emails as constraints and if the email matches one of the constraints, its in that segment and the feature flag would return true.
Additional context
I really enjoy your work and it is a great help. Thank you.
I have multiple databases (aka tenant) since I developed a multi-tenancy system, every tenant is a customer who owns a site https://[tenant_name].mysystem.com, how can I smoothly toggle features for a specific tenant using Flipt?
Case: I have 10 000 (and increasing) variants for one flag. In my code i wan't manualy write code for each variant key. I want get variant contain json with variant data. Example variant json:
{
"color": "black",
"discount": 3,
"category_id": 24
}
And in my code write one code when handle json from variant instead if/else/switch for each variant.
Add a Heroku button to allow for someone to easily standup an example app in Heroku:
Great project. I'd like to contribute, do you have features that you have in mind? If so, it would be great if you can create issues so contributors can jump in.
I'd like to be able to export all flags, variants, segments, constraints and rules to a file (YAML/TOML/your favorite ML).
This would allow storing all configuration in source control as well as provide a simple way to backup data.
I'd also like to be able to import previously exported data
I'm thinking this would require two new commands flipt import
and flipt export
with options for the file name and type (yaml/toml/json/etc).
It could make sense to add an option to drop all existing data before importing by providing a -drop
or -delete
option such as https://github.com/Unleash/unleash/blob/master/docs/import-export.md
Is your feature request related to a problem? Please describe.
Currently logs only go to STDOUT, would be great to support logging to the filesystem
Describe the solution you'd like
Support logging to file in configs
Is your feature request related to a problem? Please describe.
Add some end to end UI tests to verify that changes do not break the Flipt UI and that users see the expected results.
Describe the solution you'd like
Perhaps something like testcafe? I dont know much about the 'modern' e2e Javascript testing frameworks.. but I know things I DO NOT WANT:
❌ No ❌ :
Additional context
Something that could capture screenshots when tests fail would be nice too for local development
Initial settings:
I request evaluate:
{
"flag_key": "demo",
"entity_id": "1"
}
and gets:
{
"requestId": "fe7c640a-8715-4a08-87d3-cfdb8d014f6d",
"entityId": "1",
"match": true,
"flagKey": "demo",
"segmentKey": "non-registered-visitors",
"timestamp": "2019-11-24T10:33:43.123944900Z",
"value": "three",
"requestDurationMillis": 0.262
}
Then I modified percentage rollout (set first = 0):
And again request evaluate:
{
"flag_key": "demo",
"entity_id": "1"
}
and gets:
{
"requestId": "dc1939ba-081d-40f5-afbe-d8a3c1136d84",
"entityId": "1",
"flagKey": "demo",
"segmentKey": "non-registered-visitors",
"timestamp": "2019-11-24T10:34:27.103771200Z",
"requestDurationMillis": 0.293
}
Why did the value disappear?
Describe the bug
Using the wonderful auto-population of key fields for flags/segments that was added in #155, I noticed that any extra spaces before/after/between words in the name
field correspond to extra -
's in the key field.
It would be great if we could strip these extra -
s from the key field.
This will allow us to add stricter validation around the key
field on the backend
Version Info
0.10.0
To Reproduce
See gif below ⬇️
Expected behavior
name
field should be trimmed before/after the name which means the key field will not contain extra -
s
foo
should become name: foo
, key: --foo--
will become key: foo
-
in the key:
foo bar
should result in key: foo-bar
, not foo---bar
/cc @aaronraff
I think this query should be ordered by created_at evaluations same as rules
Is your feature request related to a problem? Please describe.
Since my systems already use Etcd as a storage backend, an Etcd backend for Flipt would make it easier to deploy in my environment.
Describe the solution you'd like
I would like an Etcd storage backend, in addition to the PostgreSQL and SQLite options.
Additional context
Adding an Etcd backend will be a shift from the SQL backends currently offered, but hopefully any work towards Etcd would also be useful towards supporting other KV backends, like Redis.
It's not obvious to a user what "on" or "off" does. I would assume they fully turn the feature on or off, but at least the for the on state thats not true.
So here's the question:
Should a flag with "on" and no rules be on? If not, then maybe its at least worth clarifying in the user (help text? something else?) what the behavior is.
Hey @markphelps—great work.
I'm thinking about using flipt for a product I'm developing, however, I am not sure if I'm doing something wrong.
I've created one flag called "test" with a segment that matches on all contexts and a targeting rule on set to 50% and off also set to 50%. I can't seem to get a match: true
or match: false
back from the server.
I add 280 variants to one flag.
I go to Targeting
tab and click New Rule
.
I select A Percentage Rollout
.
Interface draw my 280 variants with fre-filled 0,36%
I click Add Rule
and get error Total percentage cannot exceed 100%.
Because 280 * 0,36 = 100,8
Flipt incorrectly calculated the initial values.
Figure out a way to test Flipt from outside.
Possible options:
flipt
in a separate process and test using the GRPC and/or REST APIsflipt
in a separate process and test via the UI using headless chrome?Add caching layer on the server side to increase evaluation speed.
Should probably be an LRU cache, perhaps something like Groupcache LRU
Should be able to be disabled and maybe swappable for other implementations in the future
MySQL is still a popular DB, so let's support it
Hi! Thanks for the flipt!
I have a need to give specific variant in a limited quantity, for example, 1000.
I would also like to do 2 distribution strategies:
start distributing the variant to everyone with the highest priority until quantity ends.
evenly adding for a certain time, but not more than a given quantity.
For backup the sqlite database I can use flipt export
which pipes to STDOUT. In our k8s environment this looks so:
kubectl exec -it <name of flipt pod> -- /bin/sh -c './flipt export' > export.yaml
... and works like a charm :-)
But now I wonder how to import the the backup since flipt import
wants to read from a file, not from STDIN. I've tried a lot of variants, all ended in Error: requires a file argument
:-(
So it would be great, if I can do a flipt import
to read from STDIN for restoring backups in a docker or k8s environment.
Describe the bug
Adding a flag with a :
character breaks the UI. e.g. foo:bar
I could use an easy way to turn feature flags on and off based on segments.
As an example, my web application has a feature called "projects" that I would like to enable only for users that have subscribed to the "professional" plan. As far as I know, the only way to do that in flipt is to create two variants of the flag ("enabled" and "disabled"), and to map those variants to segments corresponding to the plans ("basic" or "professional").
Having to create those variants is a bit inconvenient as all I really want to do is just switch the flag on or off.
Describe the bug
When requesting a feature flag, with the same request entityId
and payload and given two rules:
released
50% unreleased
unreleased
We get inconsistent match and results over sequential requests.
Version Info
0.10.0
To Reproduce
On a fresh install
released
and unreleased
subscribers
that checks "premium_user": "true"
all users
that match all
subscribers
then serve percentage rollout
-> 50% released
50% unreleased
all users
then serve unreleased
Expected behavior
This is a legitimate use case where we want to progressively roll-out a feature to premium users while keeping it disabled for all others.
The expected behaviour when requesting this feature flag as a subscriber (i.e. "premium_user": "true"
) with the same payload is to have a consistent match on the first rule.
But currently, with the exact same payload (i.e. same entityId
and context
) we get randomly matched on first or second rule, effectively returning an inconsistent variant
released
or unreleased
for one given premium user.
Screenshots
Please note the inconsistent value of fields segmentKey
and value
in the response.
Additional context
Postgres
Dependabot couldn't find a Gopkg.toml for this project.
Dependabot requires a Gopkg.toml to evaluate your project's current Go dependencies. It had expected to find one at the path: /Gopkg.toml
.
If this isn't a Go project, or if it is a library, you may wish to disable updates for it from within Dependabot.
You can mention @dependabot in the comments below to contact the Dependabot team.
Describe the solution you'd like
Add pagination to all table components in UI (ex: defaulting to 15 elements per page)
Additional context
https://buefy.org/documentation/table/#pagination-and-sorting
Is your feature request related to a problem? Please describe.
It would be nice to provide an export
command that allows users to export the current state of their database in a yaml
or json
format.
This would be helpful when debugging issues as I could ask users to attach the contents or subset of their flipt export
data to bug reports.
Describe the solution you'd like
Support flipt export [--format=json | --format=yaml]
to export data to a local file
Additional context
Add any other context or screenshots about the feature request here.
Describe the bug
The variants column in the flags list always says yes, though my assumption is it should only say yes if there are variants attached to a flag.
Version Info
0.13.0
Some dev dependencies are several versions behind. Would like to get them as up to date as possible.
~/workspace/flipt/ui master
❯ yarn outdated
yarn outdated v1.17.3
info Color legend :
"<red>" : Major Update backward-incompatible updates
"<yellow>" : Minor Update backward-compatible features
"<green>" : Patch Update backward-compatible bug fixes
Package Current Wanted Latest Package Type URL
babel-loader 7.1.5 7.1.5 8.0.6 devDependencies https://github.com/babel/babel-loader
copy-webpack-plugin 4.6.0 4.6.0 5.0.3 devDependencies https://github.com/webpack-contrib/copy-webpack-plugin
css-loader 0.28.11 0.28.11 3.0.0 devDependencies https://github.com/webpack-contrib/css-loader
eslint 5.16.0 5.16.0 6.0.1 devDependencies https://eslint.org
eslint-config-prettier 3.6.0 3.6.0 6.0.0 devDependencies https://github.com/prettier/eslint-config-prettier#readme
eslint-config-standard 10.2.1 10.2.1 13.0.1 devDependencies https://github.com/standard/eslint-config-standard
eslint-friendly-formatter 3.0.0 3.0.0 4.0.1 devDependencies https://github.com/royriojas/eslint-friendly-formatter#readme
eslint-loader 1.9.0 1.9.0 2.2.1 devDependencies https://github.com/webpack-contrib/eslint-loader#readme
eslint-plugin-node 5.2.1 5.2.1 9.1.0 devDependencies https://github.com/mysticatea/eslint-plugin-node#readme
eslint-plugin-promise 3.8.0 3.8.0 4.2.1 devDependencies https://github.com/xjamundx/eslint-plugin-promise#readme
eslint-plugin-standard 3.1.0 3.1.0 4.0.0 devDependencies https://github.com/standard/eslint-plugin-standard#readme
file-loader 1.1.11 1.1.11 4.0.0 devDependencies https://github.com/webpack-contrib/file-loader
html-webpack-plugin 2.30.1 2.30.1 3.2.0 devDependencies https://github.com/jantimon/html-webpack-plugin
optimize-css-assets-webpack-plugin 3.2.1 3.2.1 5.0.3 devDependencies http://github.com/NMFR/optimize-css-assets-webpack-plugin
ora 1.4.0 1.4.0 3.4.0 devDependencies https://github.com/sindresorhus/ora#readme
portfinder 1.0.20 1.0.21 1.0.21 devDependencies https://github.com/indexzero/node-portfinder#readme
postcss-import 11.1.0 11.1.0 12.0.1 devDependencies https://github.com/postcss/postcss-import#readme
postcss-loader 2.1.6 2.1.6 3.0.0 devDependencies https://github.com/postcss/postcss-loader#readme
postcss-url 7.3.2 7.3.2 8.0.0 devDependencies https://github.com/postcss/postcss-url#readme
semver 5.7.0 5.7.0 6.2.0 devDependencies https://github.com/npm/node-semver#readme
shelljs 0.7.8 0.7.8 0.8.3 devDependencies http://github.com/shelljs/shelljs
uglifyjs-webpack-plugin 1.3.0 1.3.0 2.1.3 devDependencies https://github.com/webpack-contrib/uglifyjs-webpack-plugin
url-loader 0.5.9 0.5.9 2.0.1 devDependencies https://github.com/webpack-contrib/url-loader
vue-loader 13.7.3 13.7.3 15.7.0 devDependencies https://github.com/vuejs/vue-loader
vue-style-loader 3.1.2 3.1.2 4.1.2 devDependencies https://github.com/vuejs/vue-style-loader#readme
webpack 3.12.0 3.12.0 4.36.1 devDependencies https://github.com/webpack/webpack
webpack-dev-server 2.11.5 2.11.5 3.7.2 devDependencies https://github.com/webpack/webpack-dev-server#readme
Done in 1.07s.
IMO there isn't great documentation on what you can do with variants, segments, rules and distributions.
It might make sense to add more examples that show how this could be used, much like in examples/basic, but examples/targeting
?
Also would be nice if these abilities could somehow be expressed better in diagrams or even just in words, kind of like what LaunchDarkly does with targeting users, but maybe not as verbose.
I think i've stumble upon another issue...so here's what I did:
test
;test
with a constraint: @alwaysMatch IS NOT PRESENT
test
(on, off);test
to be 50% off, 50% on;a
gets 50% and b, c, d, e gets 10% respectively.Issue:
{
"requestId": "1e5aae90-4ea3-4311-be85-91d0d24ca3e4",
"entityId": "3",
"requestContext": {},
"match": true,
"flagKey": "test",
"segmentKey": "test",
"timestamp": "2019-05-11T18:22:53.517088460Z",
"requestDurationMillis": 0.980012
}
I've tested programatically with 100 different IDs, for some reason, it doesn't evaluate to anything with some of them.
State of the world:
sqlite> .tables
constraints flags schema_migrations variants
distributions rules segments
sqlite> select * from flags;
test|test||1|2019-05-11 18:09:34.824808692+00:00|2019-05-11 18:09:34.824808692+00:00
sqlite> select * from rules;
09a3cee0-448a-4100-8d55-b2a68df41eae|test|test|1|2019-05-11 18:22:02.831441605+00:00|2019-05-11 18:22:02.831441605+00:00
sqlite> select * from segments;
test|test||2019-05-11 18:09:39.674672314+00:00|2019-05-11 18:09:39.674672314+00:00
sqlite> select * from distributions;
fe817dd0-fc27-4d30-b0d5-ccd4ea0a3282|09a3cee0-448a-4100-8d55-b2a68df41eae|af3c2070-9692-40b7-9258-608c24a53b8d|50.0|2019-05-11 18:22:02.842112509+00:00|2019-05-11 18:22:02.842112509+00:00
ee4743af-c6fc-4523-b38a-03c1713b7d1b|09a3cee0-448a-4100-8d55-b2a68df41eae|d7049aa6-9906-4e9d-b6e5-9a9be424992a|10.0|2019-05-11 18:22:02.846632236+00:00|2019-05-11 18:22:02.846632236+00:00
c43b7cb4-0c19-4e12-811d-2f4c774cc506|09a3cee0-448a-4100-8d55-b2a68df41eae|e019aff0-df11-40da-878d-5b4293c69f15|10.0|2019-05-11 18:22:02.846011664+00:00|2019-05-11 18:22:02.846011664+00:00
0c4e8daf-9f34-4691-9e6f-23c3a801ff10|09a3cee0-448a-4100-8d55-b2a68df41eae|8fce46af-045b-4b34-a4bb-c362585908f4|10.0|2019-05-11 18:22:02.842992967+00:00|2019-05-11 18:22:02.842992967+00:00
e4072afe-0959-4ab0-970c-106f6ef9754a|09a3cee0-448a-4100-8d55-b2a68df41eae|59e512a4-f486-4b4c-9857-28e4e759fa1d|10.0|2019-05-11 18:22:02.844072062+00:00|2019-05-11 18:22:02.844072062+00:00
sqlite> select * from variants;
af3c2070-9692-40b7-9258-608c24a53b8d|test|a|a||2019-05-11 18:21:28.402943187+00:00|2019-05-11 18:21:28.402943187+00:00
8fce46af-045b-4b34-a4bb-c362585908f4|test|b|b||2019-05-11 18:21:32.100555715+00:00|2019-05-11 18:21:32.100555715+00:00
59e512a4-f486-4b4c-9857-28e4e759fa1d|test|c|c||2019-05-11 18:21:34.568535072+00:00|2019-05-11 18:21:34.568535072+00:00
e019aff0-df11-40da-878d-5b4293c69f15|test|d|d||2019-05-11 18:21:37.8885922+00:00|2019-05-11 18:21:37.8885922+00:00
d7049aa6-9906-4e9d-b6e5-9a9be424992a|test|e|e||2019-05-11 18:21:41.021846003+00:00|2019-05-11 18:21:41.021846003+00:00
https://github.com/getsentry/flipt-grpc-python
just an fyi in case you wanna document it. can add you to the repo.
also added a Makefile which may be useful in other repos?
we're exploring using flipt so this is needed for our eval
Increase aggregate test coverage to > 80%
Describe the bug
User can input any flag key/segment into the url, even those that don't exist, and will be presented with a 'normal looking' view.
We should handle the 404 being returned by the API and show a warning/error message, and probably redirect to the flags index or segments index respectively.
Version Info
Run flipt --version
and paste the output here.
Version: v0.10.1-snapshot
Commit: 7be211afb564df98bcf6a54fb0511733c8f00fe2
Build Date: 2019-11-10T15:41:33Z
Go Version: go1.13.3
To Reproduce
Type http://{flipt_server_url}/#/flags/doesntexist
into browser and hit enter
Expected behavior
Screenshots
Logs
time="2019-11-10T15:42:11Z" level=info msg="finished unary call with code NotFound" error="rpc error: code = NotFound desc = flag \"bar\" not found" grpc.code=NotFound grpc.method=GetFlag grpc.service=flipt.Flipt grpc.start_time="2019-11-10T15:42:11Z" grpc.time_ms=2.185 peer.address="127.0.0.1:51684" server=grpc span.kind=server system=grpc
Re: #41
Add support for external DB storage with Postgres.
db
, ex:db:
url: postgresql://localhost:5432/flipt
And changing the default SQLite config to look something like this:
db:
url: sqlite3:///var/opt/flipt/flipt.db
Or something similar, still on the fence about what would work best here. Feedback would be greatly appreciated!
github.com/Masterminds/squirrel
This may make sense to abstract away the error handling since that is what is most likely to be different between the different databases. We might be able to get away with not changing the actual query logic much at all since squirrel
and Go's sql
lib should do most of the heavy lifting.
Is your feature request related to a problem? Please describe.
Feature, allow evaluate all available flags
Describe the solution you'd like
Querying available flags which is return all flags that fit for current context. Example:
GET /api/v1/evaluate_all
{
"entity_id": "string",
"context": {
"property1": "string",
"property2": "string"
}
}
and returns
{
"entity_id": "string",
"request_context": {
"property1": "string",
"property2": "string"
},
"match_flags": [
{
"key": "string",
"value": "string"
}
]
}
Additional context
Add support for users wanting to use their own HTTPS certs
Describe the bug
When creating a segment with two constraints:
== true
== 'somevalue'
The segment is matched when evaluating a flag with the boolean value only.
Version Info
Run flipt --version
and paste the output here.
Version: 0.8.0
Commit: 0a47977b560085983cd95eb5f31141039df8ecd2
Build Date: 2019-09-30T08:43:15Z
Go Version: go1.13
To Reproduce
isAdmin
, boolean
and == TRUE
customer
, string
and equals acme
flag
with the following contexts:{
"flagKey": "flag",
"entityId": "ca93e3ad-8327-4da6-909c-f5f7b2c9a4f5",
"context": {
"isAdmin": "true"
}
}
Expecting no match
{
"flagKey": "flag",
"entityId": "ca93e3ad-8327-4da6-909c-f5f7b2c9a4f5",
"context": {
"isAdmin": "true",
"customer": "acme"
}
}
Expecting a match
{
"flagKey": "flag",
"entityId": "ca93e3ad-8327-4da6-909c-f5f7b2c9a4f5",
"context": {
"isAdmin": "true",
"customer": "apple"
}
}
Expecting no match
Additional context
When trying to create a variant for a flag where the key is default, I'm getting an error suggesting that the key needs to be unique, despite the no existing variants for the flag. I do have a variant with the key default on another flag though.
I would expect that the keys for variants should be unique per flag rather than globally, since there is no way that these variants can be used across flags.
When creating a new flag/segment/etc, you have to type the name
and key
field before saving as they are both required.
It would be nice if the key
field autopopulated based on the name
fields as they are often closely related.
^ In the above screenshot, it would be nice if key
was autopopulated to foo-bar
Also consider if it makes sense to swap the position of the name
and key
fields in the form
Any plans on expanding this to use external databases, like mysql or postgres? It's the coolest feature flag system I've seen. :)
Version 0.6.0
Binary installed to ~/flipt
Default configuration with exception of the sqlite3 db file located in ~/flipt, and migrations pointing to ~/flipt/config/migrations/sqlite3
Running ./flipt
results in error that ~/flipt/config/migrations/sqlite3 file does not exist.
Copying migrations from this repo into the migrations folder resolves the issue.
The last build to include migrations was 0.4.2.
Is your feature request related to a problem? Please describe.
I'm currently using unleash, but I'm considering flipt. I'm going through the docs and noticed that migrations are kept in the db.migrations.path
config, which points to a local file. There is no indication that migrations are stored locally, but I'd love to be wrong.
Edit: Are these files similar to migration files in rails or are they used to keep track of what migrations have been run? If the former, then I assume the DB does keep track of migrations.
Describe the solution you'd like
A way to store all data in a db, so that I don't need to configure permanent storage for my ECS/Fargate setup.
Additional context
N/A
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.