Skip to content

Commit

Permalink
Merge branch 'onboarding-page' of https://github.com/flipt-io/flipt i…
Browse files Browse the repository at this point in the history
…nto onboarding-page

* 'onboarding-page' of https://github.com/flipt-io/flipt:
  docs(examples): added example how to run flipt behind nginx (#2726)
  chore(deps): bump github.com/moby/buildkit in /_tools (#2728)
  feat: UI refs pt1 (#2727)
  • Loading branch information
markphelps committed Feb 1, 2024
2 parents e7e8369 + 1ce134d commit 3ee20d6
Show file tree
Hide file tree
Showing 11 changed files with 192 additions and 22 deletions.
6 changes: 3 additions & 3 deletions _tools/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ require (
github.com/chavacava/garif v0.0.0-20221024190013-b3ef35877348 // indirect
github.com/containerd/containerd v1.7.11 // indirect
github.com/containerd/log v0.1.0 // indirect
github.com/containerd/typeurl v1.0.2 // indirect
github.com/containerd/typeurl/v2 v2.1.1 // indirect
github.com/cpuguy83/go-md2man/v2 v2.0.3 // indirect
github.com/curioswitch/go-reassign v0.2.0 // indirect
github.com/daixiang0/gci v0.9.1 // indirect
Expand Down Expand Up @@ -110,7 +110,7 @@ require (
github.com/kisielk/errcheck v1.6.3 // indirect
github.com/kisielk/gotool v1.0.0 // indirect
github.com/kkHAIKE/contextcheck v1.1.3 // indirect
github.com/klauspost/compress v1.17.0 // indirect
github.com/klauspost/compress v1.17.2 // indirect
github.com/klauspost/pgzip v1.2.5 // indirect
github.com/kulti/thelper v0.6.3 // indirect
github.com/kunwardeep/paralleltest v1.0.6 // indirect
Expand All @@ -131,7 +131,7 @@ require (
github.com/mgechev/revive v1.2.5 // indirect
github.com/mitchellh/go-homedir v1.1.0 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/moby/buildkit v0.11.4 // indirect
github.com/moby/buildkit v0.12.5 // indirect
github.com/moby/term v0.5.0 // indirect
github.com/moricho/tparallel v0.2.1 // indirect
github.com/morikuni/aec v1.0.0 // indirect
Expand Down
13 changes: 7 additions & 6 deletions _tools/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -125,8 +125,8 @@ github.com/containerd/containerd v1.7.11 h1:lfGKw3eU35sjV0aG2eYZTiwFEY1pCzxdzicH
github.com/containerd/containerd v1.7.11/go.mod h1:5UluHxHTX2rdvYuZ5OJTC5m/KJNs0Zs9wVoJm9zf5ZE=
github.com/containerd/log v0.1.0 h1:TCJt7ioM2cr/tfR8GPbGf9/VRAX8D2B4PjzCpfX540I=
github.com/containerd/log v0.1.0/go.mod h1:VRRf09a7mHDIRezVKTRCrOq78v577GXq3bSa3EhrzVo=
github.com/containerd/typeurl v1.0.2 h1:Chlt8zIieDbzQFzXzAeBEF92KhExuE4p9p92/QmY7aY=
github.com/containerd/typeurl v1.0.2/go.mod h1:9trJWW2sRlGub4wZJRTW83VtbOLS6hwcDZXTn6oPz9s=
github.com/containerd/typeurl/v2 v2.1.1 h1:3Q4Pt7i8nYwy2KmQWIw2+1hTvwTE/6w9FqcttATPO/4=
github.com/containerd/typeurl/v2 v2.1.1/go.mod h1:IDp2JFvbwZ31H8dQbEIY7sDl2L3o3HZj1hsSQlywkQ0=
github.com/cpuguy83/go-md2man/v2 v2.0.3 h1:qMCsGGgs+MAzDFyp9LpAe1Lqy/fY/qCovCm0qnXZOBM=
github.com/cpuguy83/go-md2man/v2 v2.0.3/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o=
github.com/creack/pty v1.1.18 h1:n56/Zwd5o6whRC5PMGretI4IdRLlmBXYNjScPaBgsbY=
Expand Down Expand Up @@ -384,8 +384,8 @@ github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/kkHAIKE/contextcheck v1.1.3 h1:l4pNvrb8JSwRd51ojtcOxOeHJzHek+MtOyXbaR0uvmw=
github.com/kkHAIKE/contextcheck v1.1.3/go.mod h1:PG/cwd6c0705/LM0KTr1acO2gORUxkSVWyLJOFW5qoo=
github.com/klauspost/compress v1.17.0 h1:Rnbp4K9EjcDuVuHtd0dgA4qNuv9yKDYKK1ulpJwgrqM=
github.com/klauspost/compress v1.17.0/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/compress v1.17.2 h1:RlWWUY/Dr4fL8qk9YG7DTZ7PDgME2V4csBXA8L/ixi4=
github.com/klauspost/compress v1.17.2/go.mod h1:ntbaceVETuRiXiv4DpjP66DpAtAGkEQskQzEyD//IeE=
github.com/klauspost/pgzip v1.2.5 h1:qnWYvvKqedOF2ulHpMG72XQol4ILEJ8k2wwRl/Km8oE=
github.com/klauspost/pgzip v1.2.5/go.mod h1:Ch1tH69qFZu15pkjo5kYi6mth2Zzwzt50oCQKQE9RUs=
github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
Expand Down Expand Up @@ -444,8 +444,8 @@ github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG
github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0=
github.com/mitchellh/mapstructure v1.5.0 h1:jeMsZIYE/09sWLaz43PL7Gy6RuMjD2eJVyuac5Z2hdY=
github.com/mitchellh/mapstructure v1.5.0/go.mod h1:bFUtVrKA4DC2yAKiSyO/QUcy7e+RRV2QTWOzhPopBRo=
github.com/moby/buildkit v0.11.4 h1:mleVHr+n7HUD65QNUkgkT3d8muTzhYUoHE9FM3Ej05s=
github.com/moby/buildkit v0.11.4/go.mod h1:P5Qi041LvCfhkfYBHry+Rwoo3Wi6H971J2ggE+PcIoo=
github.com/moby/buildkit v0.12.5 h1:RNHH1l3HDhYyZafr5EgstEu8aGNCwyfvMtrQDtjH9T0=
github.com/moby/buildkit v0.12.5/go.mod h1:YGwjA2loqyiYfZeEo8FtI7z4x5XponAaIWsWcSjWwso=
github.com/moby/term v0.5.0 h1:xt8Q1nalod/v7BqbG21f8mQPqH+xAaC9C3N3wfWbVP0=
github.com/moby/term v0.5.0/go.mod h1:8FzsFHVUBGZdbDsJw/ot+X+d5HLUbvklYLJ9uGfcI3Y=
github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q=
Expand Down Expand Up @@ -1086,6 +1086,7 @@ google.golang.org/protobuf v1.24.0/go.mod h1:r/3tXBNzIEhYS9I1OUVjXDlt8tc493IdKGj
google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.27.1/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
google.golang.org/protobuf v1.32.0 h1:pPC6BG5ex8PDFnkbrGU3EixyhKcQ2aDuBS36lqK/C7I=
google.golang.org/protobuf v1.32.0/go.mod h1:c6P6GXX6sHbq/GpV6MGZEdwhWPcYBgnhAHhKbcUYpos=
gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
Expand Down
31 changes: 31 additions & 0 deletions examples/proxy/docker-compose.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
version: "3"

services:
flipt:
image: flipt/flipt:latest
environment:
- FLIPT_LOG_LEVEL=warn
- FLIPT_STORAGE_TYPE=local
- FLIPT_STORAGE_LOCAL_PATH=/opt
- FLIPT_META_TELEMETRY_ENABLED=false
networks:
- flipt_network
volumes:
- ./features.yml:/opt/features.yml:ro
healthcheck:
test: wget --no-verbose --tries=1 --spider http://localhost:8080/health || exit 1

nginx:
image: nginx:alpine
ports:
- "9999:80"
networks:
- flipt_network
volumes:
- ./nginx.conf:/etc/nginx/conf.d/default.conf:ro
depends_on:
flipt:
condition: service_healthy

networks:
flipt_network:
5 changes: 5 additions & 0 deletions examples/proxy/features.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace: default
flags:
- key: example
name: Example
description: An example flag
33 changes: 33 additions & 0 deletions examples/proxy/nginx.conf
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
server {
listen 80;
gzip on;
gzip_static on;
gzip_types text/plain text/css application/json text/javascript;
location / {
add_header Content-Type text/html;
return 200 '<html><body style="text-align:center"><a href="/flipt/">Go to Flipt</a></body></html>';
}
location /flipt {
proxy_pass http://flipt:8080/;
# proxy settings
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Accept-Encoding "";
proxy_buffering on;
gzip on;

# rewrite
rewrite ^/flipt/(.*) /$1 break;

# modify response
sub_filter_once off;
sub_filter_types text/javascript text/html;
sub_filter "/favicon.svg" "/flipt/favicon.svg";
sub_filter "assets/" "flipt/assets/";
sub_filter "/api/v1" "/flipt/api/v1";
sub_filter "/auth/v1" "/flipt/auth/v1";
sub_filter "/evaluate/v1" "/flipt/evaluate/v1";
sub_filter "/meta" "/flipt/meta";
}
}
5 changes: 3 additions & 2 deletions ui/src/app/console/Console.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import {
generateCurlCommand,
getErrorMessage
} from '~/utils/helpers';
import { selectCurrentRef } from '~/app/refs/refsSlice';

function ResetOnNamespaceChange({ namespace }: { namespace: INamespace }) {
const { resetForm } = useFormikContext();
Expand Down Expand Up @@ -65,7 +66,7 @@ export default function Console() {
const { setSuccess } = useSuccess();

const namespace = useSelector(selectCurrentNamespace);

const ref = useSelector(selectCurrentRef);
const { data, error } = useListFlagsQuery(namespace.key);

useEffect(() => {
Expand Down Expand Up @@ -121,7 +122,7 @@ export default function Console() {
context: parsed
};

evaluateV2(namespace.key, flag.key, flag.type, rest)
evaluateV2(ref, namespace.key, flag.key, flag.type, rest)
.then((resp) => {
setHasEvaluationError(false);
setResponse(JSON.stringify(resp, null, 2));
Expand Down
4 changes: 3 additions & 1 deletion ui/src/app/namespaces/namespacesSlice.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ import { RootState } from '~/store';
import { LoadingStatus } from '~/types/Meta';
import { INamespace, INamespaceBase, INamespaceList } from '~/types/Namespace';
import { baseQuery } from '~/utils/redux-rtk';
const namespaceKey = 'namespace';

export const namespaceKey = 'namespace';

interface INamespacesState {
namespaces: { [key: string]: INamespace };
Expand Down Expand Up @@ -112,4 +113,5 @@ export const {
useDeleteNamespaceMutation,
useUpdateNamespaceMutation
} = namespaceApi;

export default namespacesSlice.reducer;
31 changes: 31 additions & 0 deletions ui/src/app/refs/refsSlice.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
import { createSelector, createSlice } from '@reduxjs/toolkit';
import { RootState } from '~/store';

export const refsKey = 'refs';
interface IRefState {
currentRef?: string;
}

const initialState: IRefState = {
currentRef: undefined
};

export const refsSlice = createSlice({
name: 'refs',
initialState,
reducers: {
currentRefChanged: (state, action) => {
const ref = action.payload;
state.currentRef = ref;
}
}
});

export const { currentRefChanged } = refsSlice.actions;

export const selectCurrentRef = createSelector(
[(state: RootState) => state.refs.currentRef],
(ref) => ref
);

export default refsSlice.reducer;
8 changes: 6 additions & 2 deletions ui/src/data/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -114,13 +114,17 @@ export async function evaluate(
//
// evaluateV2
export async function evaluateV2(
ref: string | undefined,
namespaceKey: string,
flagKey: string,
flagType: FlagType,
values: any
) {
const route = flagType === FlagType.BOOLEAN ? '/boolean' : '/variant';

let route = flagType === FlagType.BOOLEAN ? '/boolean' : '/variant';
if (ref) {
const q = new URLSearchParams({ reference: ref }).toString();
route += '?' + q;
}
const body = {
namespaceKey,
flagKey: flagKey,
Expand Down
29 changes: 27 additions & 2 deletions ui/src/store.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import {
import { authProvidersApi } from '~/app/auth/authApi';
import {
namespaceApi,
namespaceKey,
namespacesSlice
} from '~/app/namespaces/namespacesSlice';
import { flagsApi } from './app/flags/flagsApi';
Expand All @@ -20,11 +21,10 @@ import {
import { segmentTag, segmentsApi } from './app/segments/segmentsApi';
import { tokensApi } from './app/tokens/tokensApi';
import { LoadingStatus } from './types/Meta';
import { refsKey, refsSlice } from './app/refs/refsSlice';

const listenerMiddleware = createListenerMiddleware();

const namespaceKey = 'namespace';

listenerMiddleware.startListening({
matcher: isAnyOf(
preferencesSlice.actions.themeChanged,
Expand All @@ -49,6 +49,25 @@ listenerMiddleware.startListening({
);
}
});

listenerMiddleware.startListening({
matcher: isAnyOf(refsSlice.actions.currentRefChanged),
effect: (_action, api) => {
// save to local storage
localStorage.setItem(
refsKey,
(api.getState() as RootState).refs.currentRef || ''
);

// reset internal cache
api.dispatch(namespaceApi.util.resetApiState());
api.dispatch(flagsApi.util.resetApiState());
api.dispatch(segmentsApi.util.resetApiState());
api.dispatch(rolloutsApi.util.resetApiState());
api.dispatch(rulesApi.util.resetApiState());
}
});

/*
* It could be anti-pattern but it feels like the right thing to do.
* The namespacesSlice holds the namespaces globally and doesn't refetch them
Expand Down Expand Up @@ -89,10 +108,15 @@ const preferencesState = JSON.parse(
localStorage.getItem(preferencesKey) || '{}'
);

const currentRef = localStorage.getItem(refsKey) || undefined;

const currentNamespace = localStorage.getItem(namespaceKey) || 'default';

export const store = configureStore({
preloadedState: {
refs: {
currentRef
},
preferences: preferencesState,
namespaces: {
namespaces: {},
Expand All @@ -102,6 +126,7 @@ export const store = configureStore({
}
},
reducer: {
refs: refsSlice.reducer,
namespaces: namespacesSlice.reducer,
preferences: preferencesSlice.reducer,
meta: metaSlice.reducer,
Expand Down
49 changes: 43 additions & 6 deletions ui/src/utils/redux-rtk.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
import { fetchBaseQuery } from '@reduxjs/toolkit/query/react';
import {
BaseQueryFn,
FetchArgs,
FetchBaseQueryError,
fetchBaseQuery
} from '@reduxjs/toolkit/query/react';
import { apiURL, checkResponse, defaultHeaders } from '~/data/api';

type CustomFetchFn = (
url: RequestInfo,
options: RequestInit | undefined
Expand All @@ -17,7 +21,40 @@ export const customFetchFn: CustomFetchFn = async (url, options) => {
return response;
};

export const baseQuery = fetchBaseQuery({
baseUrl: apiURL,
fetchFn: customFetchFn
});
export const baseQuery: BaseQueryFn<
string | FetchArgs,
unknown,
FetchBaseQueryError
> = async (args, api, extraOptions) => {
return fetchBaseQuery({
baseUrl: apiURL,
fetchFn: async (url, options) => {
const state = api.getState();
// @ts-ignore
const ref = state?.refs?.currentRef;
if (ref) {
const req = url instanceof Request ? url : new Request(url);
const q = new URLSearchParams({ reference: ref }).toString();
const blob = req.headers.get('Content-Type')
? req.blob()
: Promise.resolve(undefined);
url = await blob.then(
(body) =>
new Request(req.url + '?' + q, {
method: req.method,
headers: req.headers,
body: body,
referrer: req.referrer,
referrerPolicy: req.referrerPolicy,
mode: req.mode,
credentials: req.credentials,
cache: req.cache,
redirect: req.redirect,
integrity: req.integrity
})
);
}
return customFetchFn(url, options);
}
})(args, api, extraOptions);
};

0 comments on commit 3ee20d6

Please sign in to comment.