diff --git a/CHANGELOG.md b/CHANGELOG.md index 021decd6505..8b77843975a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,21 @@ +# [2024-11-04] (Chart Release 5.7.0) + +## Bug fixes and other updates + + +* galley: Use bulk query when getting all feature configs for a team user (#4325) + + +## Internal changes + + +* Block access to assets.*/minio/ path for public access. (#4297) + +* galley: Delete unused endpoint for getting feature status for multiple teams (#4326) + +* Fix shellcheck problems in all shell scripts (#4220) + + # [2024-10-30] (Chart Release 5.6.0) ## Release notes diff --git a/Makefile b/Makefile index 77a68d9cc10..ea55403761f 100644 --- a/Makefile +++ b/Makefile @@ -250,11 +250,11 @@ add-license: .PHONY: treefmt treefmt: - treefmt -u debug - + treefmt -u debug --walk=git + .PHONY: treefmt-check treefmt-check: - treefmt --fail-on-change -u debug + treefmt --fail-on-change -u debug --walk=git ################################# ## docker targets diff --git a/changelog.d/mk-changelog.sh b/changelog.d/mk-changelog.sh index 550e024738c..d632d5ea863 100755 --- a/changelog.d/mk-changelog.sh +++ b/changelog.d/mk-changelog.sh @@ -6,7 +6,7 @@ shopt -s nullglob DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" getPRNumber() { - git log --reverse --format=%s -- $1 | sed -rn '1 { /\((#.*)\)$/ s|^.*\((#.*)\)$|\1|p; }' | grep "" || + git log --reverse --format=%s -- "$1" | sed -rn '1 { /\((#.*)\)$/ s|^.*\((#.*)\)$|\1|p; }' | grep "" || echo "#PR_NOT_FOUND" } @@ -18,10 +18,12 @@ for d in "$DIR"/*; do if [[ ${#entries[@]} -eq 0 ]]; then continue; fi echo -n "## " + # shellcheck disable=SC1003 sed '$ a\' "$d/.title" echo "" for f in "${entries[@]}"; do - pr=$(getPRNumber $f) + pr=$(getPRNumber "$f") + # shellcheck disable=SC1003 sed -r ' # create a bullet point on the first line 1 { s/^/\* /; } diff --git a/charts/nginx-ingress-services/templates/ingress.yaml b/charts/nginx-ingress-services/templates/ingress.yaml index 633f27e2625..c010af5da53 100644 --- a/charts/nginx-ingress-services/templates/ingress.yaml +++ b/charts/nginx-ingress-services/templates/ingress.yaml @@ -51,9 +51,6 @@ spec: {{- if .Values.webapp.enabled }} - {{ .Values.config.dns.webapp }} {{- end }} -{{- if .Values.fakeS3.enabled }} - - {{ .Values.config.dns.fakeS3 }} -{{- end }} {{- if .Values.teamSettings.enabled }} - {{ .Values.config.dns.teamSettings }} {{- end }} @@ -117,25 +114,6 @@ spec: servicePort: {{ .Values.service.webapp.externalPort }} {{- end }} {{- end }} -{{- if .Values.fakeS3.enabled }} - - host: {{ .Values.config.dns.fakeS3 }} - http: - paths: - - path: / - {{- if $ingressSupportsPathType }} - pathType: Prefix - {{- end }} - backend: - {{- if $apiIsStable }} - service: - name: {{ .Values.service.s3.serviceName }} - port: - number: {{ .Values.service.s3.externalPort }} - {{- else }} - serviceName: {{ .Values.service.s3.serviceName }} - servicePort: {{ .Values.service.s3.externalPort }} - {{- end }} -{{- end }} {{- if .Values.teamSettings.enabled }} - host: {{ .Values.config.dns.teamSettings }} http: diff --git a/charts/nginx-ingress-services/templates/ingress_minio.yaml b/charts/nginx-ingress-services/templates/ingress_minio.yaml new file mode 100644 index 00000000000..e42df51389c --- /dev/null +++ b/charts/nginx-ingress-services/templates/ingress_minio.yaml @@ -0,0 +1,45 @@ +{{- $apiIsStable := eq (include "ingress.isStable" .) "true" -}} +{{- $ingressFieldNotAnnotation := eq (include "ingress.FieldNotAnnotation" .) "true" -}} +{{- $ingressSupportsPathType := eq (include "ingress.supportsPathType" .) "true" -}} +{{- if .Values.fakeS3.enabled }} +# We use a separate ingress for minio because we want to restrict access to /minio/ path +# for security reasons +apiVersion: {{ include "ingress.apiVersion" . }} +kind: Ingress +metadata: + name: minio-ingress + annotations: + {{- if not $ingressFieldNotAnnotation }} + kubernetes.io/ingress.class: "{{ .Values.config.ingressClass }}" + {{- end }} + nginx.ingress.kubernetes.io/server-snippet: | + location /minio/ { + return 403; + } +spec: + {{- if $ingressFieldNotAnnotation }} + ingressClassName: "{{ .Values.config.ingressClass }}" + {{- end }} + tls: + - hosts: + - {{ .Values.config.dns.fakeS3 }} + secretName: {{ include "nginx-ingress-services.getCertificateSecretName" . | quote }} + rules: + - host: {{ .Values.config.dns.fakeS3 }} + http: + paths: + - path: / + {{- if $ingressSupportsPathType }} + pathType: Prefix + {{- end }} + backend: + {{- if $apiIsStable }} + service: + name: {{ .Values.service.s3.serviceName }} + port: + number: {{ .Values.service.s3.externalPort }} + {{- else }} + serviceName: {{ .Values.service.s3.serviceName }} + servicePort: {{ .Values.service.s3.externalPort }} + {{- end }} +{{- end }} diff --git a/deploy/dockerephemeral/init.sh b/deploy/dockerephemeral/init.sh index 676e1b4a106..d80a7cb4c1f 100755 --- a/deploy/dockerephemeral/init.sh +++ b/deploy/dockerephemeral/init.sh @@ -12,7 +12,7 @@ aws configure set aws_secret_access_key dummysecret aws configure set region eu-west-1 # Potentially delete pre-existing tables -echo -n "waiting for dynamo: " +echo "waiting for dynamo: " while (! aws --endpoint-url=http://dynamodb:8000 --cli-connect-timeout=1 dynamodb list-tables); do sleep 1; done diff --git a/hack/bin/cabal-run-tests.sh b/hack/bin/cabal-run-tests.sh index 46a9099ecad..c2ea19287e0 100755 --- a/hack/bin/cabal-run-tests.sh +++ b/hack/bin/cabal-run-tests.sh @@ -14,8 +14,8 @@ fi for cabal in $(find "$TOP_LEVEL" -name "$pattern" | grep -v dist-newstyle); do # This is required because some tests (e.g. golden tests) must be run from # the package root. - cd "$(dirname $cabal)" - package="$(basename ${cabal%.*})" + cd "$(dirname "$cabal")" + package="$(basename "${cabal%.*}")" for test_suite in $(cabal-plan list-bins "$package:test:*" | awk '{print $2}'); do $test_suite "${@:2}" done diff --git a/hack/bin/copy-charts.sh b/hack/bin/copy-charts.sh index b0dfb3bff38..e168e89d5a8 100755 --- a/hack/bin/copy-charts.sh +++ b/hack/bin/copy-charts.sh @@ -9,21 +9,21 @@ CHART=${1:?$USAGE} TOP_LEVEL="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )" CHART_SOURCE=$TOP_LEVEL/charts -CHART_DIST=$TOP_LEVEL/.local/charts +CHART_DEST=$TOP_LEVEL/.local/charts # TODO sanity check folder must exist mkdir -p .local/charts -rm -rf "$CHART_DIST/$CHART" -cp -r "$CHART_SOURCE/$CHART" "$CHART_DIST/" +rm -rf "${CHART_DEST:?}/$CHART" +cp -r "$CHART_SOURCE/$CHART" "$CHART_DEST/" if [ -f "$CHART_SOURCE/$CHART/requirements.yaml" ]; then # very hacky bash, I'm sorry for subpath in $(grep "file://" "$CHART_SOURCE/$CHART/requirements.yaml" | awk '{ print $2 }' | xargs -n 1 | cut -c 8-) do - rm -rf "$CHART_DIST/$CHART/$subpath" - cp -r "$CHART_SOURCE/$CHART/$subpath" "$CHART_DIST/" + rm -rf "${CHART_DEST:?}/$CHART/$subpath" + cp -r "$CHART_SOURCE/$CHART/$subpath" "$CHART_DEST/" done fi -echo "copied $CHART_SOURCE/$CHART (and its local dependencies) to $CHART_DIST/$CHART" +echo "copied $CHART_SOURCE/$CHART (and its local dependencies) to $CHART_DEST/$CHART" diff --git a/hack/bin/create_team_members.sh b/hack/bin/create_team_members.sh index 42740024dcd..1988fbd62cb 100755 --- a/hack/bin/create_team_members.sh +++ b/hack/bin/create_team_members.sh @@ -33,7 +33,7 @@ $ grep code out.log | grep -v email-exists If you are in a hurry, you may want to change the sleep(1) at the end of the invite loop to less than a second. If you want to give up on -the first error, add an exit(1) where we check the $INVIDATION_ID. +the first error, add an exit(1) where we check the INVITATION_ID. " diff --git a/hack/bin/create_test_team_admins.sh b/hack/bin/create_test_team_admins.sh index 625da458b1b..6fffc6ef279 100755 --- a/hack/bin/create_test_team_admins.sh +++ b/hack/bin/create_test_team_admins.sh @@ -51,10 +51,11 @@ fi # Generate users +#shellcheck disable=SC2034 for i in $(seq 1 "$COUNT") do - EMAIL=$(cat /dev/urandom | env LC_CTYPE=C tr -dc a-zA-Z0-9 | head -c 8)"@example.com" - PASSWORD=$(cat /dev/urandom | env LC_CTYPE=C tr -dc a-zA-Z0-9 | head -c 8) + EMAIL=$(env LC_CTYPE=C tr -dc a-zA-Z0-9 < /dev/urandom | head -c 8)"@example.com" + PASSWORD=$(env LC_CTYPE=C tr -dc a-zA-Z0-9 < /dev/urandom | head -c 8) CURL_OUT=$(curl -i -s --show-error \ -XPOST "$BRIG_HOST/i/users" \ diff --git a/hack/bin/create_test_team_members.sh b/hack/bin/create_test_team_members.sh index 6a55f4a1b0c..417253b94f3 100755 --- a/hack/bin/create_test_team_members.sh +++ b/hack/bin/create_test_team_members.sh @@ -84,7 +84,7 @@ END=$((COUNT + START - 1)) for i in $(seq "$START" "$END") do EMAIL='w'$(printf "%03d" "$i")"@$TARGET_EMAIL_DOMAIN" - PASSWORD=$(cat /dev/urandom | env LC_CTYPE=C tr -dc a-zA-Z0-9 | head -c 8) + PASSWORD=$(env LC_CTYPE=C tr -dc a-zA-Z0-9 < /dev/urandom | head -c 8) # Generate the invitation @@ -125,7 +125,7 @@ do if [ "$TEAM" != "$TEAM_UUID" ]; then echo "unexpected error: user got assigned to no / the wrong team?!" - echo ${CURL_OUT} + echo "${CURL_OUT}" exit 1 fi diff --git a/hack/bin/create_test_team_scim.sh b/hack/bin/create_test_team_scim.sh index 552b4e15c1f..fcbb4498b53 100755 --- a/hack/bin/create_test_team_scim.sh +++ b/hack/bin/create_test_team_scim.sh @@ -45,8 +45,8 @@ if [ "$#" -ne 0 ]; then fi -ADMIN_EMAIL=$(cat /dev/urandom | env LC_CTYPE=C tr -dc a-zA-Z0-9 | head -c 8)"@example.com" -ADMIN_PASSWORD=$(cat /dev/urandom | env LC_CTYPE=C tr -dc a-zA-Z0-9 | head -c 8) +ADMIN_EMAIL=$(env LC_CTYPE=C tr -dc a-zA-Z0-9 < /dev/urandom | head -c 8)"@example.com" +ADMIN_PASSWORD=$(env LC_CTYPE=C tr -dc a-zA-Z0-9 < /dev/urandom | head -c 8) CURL_OUT=$(curl -i -s --show-error \ -XPOST "$BRIG_HOST/i/users" \ @@ -61,23 +61,23 @@ BEARER=$(curl -X POST \ --header 'Content-Type: application/json' \ --header 'Accept: application/json' \ -d '{"email":"'"$ADMIN_EMAIL"'","password":"'"$ADMIN_PASSWORD"'"}' \ - $BRIG_HOST/login'?persist=false' | jq -r .access_token) + "$BRIG_HOST"/login'?persist=false' | jq -r .access_token) SCIM_TOKEN_FULL=$(curl -X POST \ --header "Authorization: Bearer $BEARER" \ --header 'Content-Type: application/json;charset=utf-8' \ --header 'Z-User: '"$ADMIN_UUID" \ - -d '{ "description": "test '"`date`"'", "password": "'"$ADMIN_PASSWORD"'" }' \ - $SPAR_HOST/scim/auth-tokens) + -d '{ "description": "test '"$(date)"'", "password": "'"$ADMIN_PASSWORD"'" }' \ + "$SPAR_HOST/scim/auth-tokens") -SCIM_TOKEN=$(echo $SCIM_TOKEN_FULL | jq -r .token) -SCIM_TOKEN_ID=$(echo $SCIM_TOKEN_FULL | jq -r .info.id) +SCIM_TOKEN=$(echo "$SCIM_TOKEN_FULL" | jq -r .token) +SCIM_TOKEN_ID=$(echo "$SCIM_TOKEN_FULL" | jq -r .info.id) # Create regular user via team invitation -REGULAR_USER_EMAIL=$(cat /dev/urandom | env LC_CTYPE=C tr -dc a-zA-Z0-9 | head -c 8)"@example.com" -REGULAR_USER_PASSWORD=$(cat /dev/urandom | env LC_CTYPE=C tr -dc a-zA-Z0-9 | head -c 8) +REGULAR_USER_EMAIL=$(env LC_CTYPE=C tr -dc a-zA-Z0-9 < /dev/urandom | head -c 8)"@example.com" +REGULAR_USER_PASSWORD=$(env LC_CTYPE=C tr -dc a-zA-Z0-9 < /dev/urandom | head -c 8) CURL_OUT_INVITATION=$(curl -i -s --show-error \ -XPOST "$BRIG_HOST/teams/$TEAM_UUID/invitations" \ -H'Content-type: application/json' \ @@ -122,7 +122,7 @@ REGULAR_TEAM_MEMBER_UUID=$(echo "$CURL_OUT" | tail -1 | sed 's/.*\"id\":\"\([a-z # Create user via SCIM invitation -scimUserName=$(cat /dev/urandom | env LC_CTYPE=C tr -dc a-zA-Z0-9 | head -c 8) +scimUserName=$(env LC_CTYPE=C tr -dc a-zA-Z0-9 < /dev/urandom | head -c 8) scimUserDisplayName="Display of $scimUserName" scimUserEmail="$scimUserName@example.com" scimUserExternalId="$scimUserEmail" @@ -156,7 +156,7 @@ CURL_OUT_SCIM_POST=$(curl --location --request POST "$SPAR_HOST/scim/v2/Users" \ --header "Authorization: Bearer $SCIM_TOKEN" \ -d "$SCIM_USER") -SCIM_USER_UUID=$(echo $CURL_OUT_SCIM_POST | jq -r .id) +SCIM_USER_UUID=$(echo "$CURL_OUT_SCIM_POST" | jq -r .id) SCIM_USER_INVITATION_ID=$(curl --location -G "$BRIG_HOST/i/teams/invitations/by-email?" \ --header 'Content-Type: application/json' \ @@ -170,17 +170,7 @@ SCIM_USER_INVITATION_CODE=$(curl --silent --show-error \ -XGET "$BRIG_HOST/i/teams/invitation-code?team=$TEAM_UUID&invitation_id=$SCIM_USER_INVITATION_ID" | jq -r .code ) -scimUserPassword=$(cat /dev/urandom | env LC_CTYPE=C tr -dc a-zA-Z0-9 | head -c 8) - -REGISTER_ACCEPT=$(cat < /dev/null && pwd ) +cd "$SCRIPT_DIR/../../.local/charts" + +for chart in "$@"; do ../../hack/bin/update.sh "$chart" helm package "$chart" done helm repo index . -python3 -m http.server $HELM_SERVER_PORT +python3 -m http.server "$HELM_SERVER_PORT" diff --git a/hack/bin/set-chart-image-version.sh b/hack/bin/set-chart-image-version.sh index d133007e4a9..f975d00eb6a 100755 --- a/hack/bin/set-chart-image-version.sh +++ b/hack/bin/set-chart-image-version.sh @@ -2,7 +2,7 @@ USAGE="$0 ..." docker_tag=${1?$USAGE} -charts=${@:2} +charts=${*:2} TOP_LEVEL="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../.." && pwd )" CHARTS_DIR="$TOP_LEVEL/.local/charts" diff --git a/hack/bin/set-helm-chart-version.sh b/hack/bin/set-helm-chart-version.sh index 00b838642e5..b53b1857308 100755 --- a/hack/bin/set-helm-chart-version.sh +++ b/hack/bin/set-helm-chart-version.sh @@ -24,8 +24,7 @@ function write_versions() { # update all dependencies, if any if [ -a requirements.yaml ]; then sed -e "s/ version: \".*\"/ version: \"$target_version\"/g" requirements.yaml > "$tempfile" && mv "$tempfile" requirements.yaml - deps=( $(helm dependency list | grep -v NAME | awk '{print $1}') ) - for dep in "${deps[@]}"; do + for dep in $(helm dependency list | grep -v NAME | awk '{print $1}'); do if [ -d "$CHARTS_DIR/$dep" ] && [ "$chart" != "$dep" ]; then (cd "$CHARTS_DIR/$dep" && write_versions "$target_version") fi diff --git a/hack/bin/upload-helm-charts-s3.sh b/hack/bin/upload-helm-charts-s3.sh index c2843622f90..434c8986476 100755 --- a/hack/bin/upload-helm-charts-s3.sh +++ b/hack/bin/upload-helm-charts-s3.sh @@ -114,10 +114,11 @@ cd "$TOP_LEVEL_DIR" # If ./upload-helm-charts-s3.sh is run with a parameter, only synchronize one chart if [ -n "$chart_dir" ] && [ -d "$chart_dir" ]; then - chart_name=$(basename $chart_dir) + chart_name=$(basename "$chart_dir") echo "only syncing $chart_name" charts=( "$chart_name" ) else + #shellcheck disable=SC2207 charts=( $(make -s -C "$TOP_LEVEL_DIR" echo-release-charts) ) # See Makefile/ CHARTS_RELEASE FUTUREWORK #charts=( $(find $CHART_DIR/ -maxdepth 1 -type d | sed -n "s=$CHART_DIR/\(.\+\)=\1 =p") ) @@ -176,7 +177,7 @@ if [[ "$reindex" == "1" ]]; then else # update local cache with newly pushed charts helm repo update - printf "\n--> Not reindexing by default. Pass the --reindex flag in case the index.yaml is incomplete. See all wire charts using \n helm search repo $REPO_NAME/ -l\n\n" + printf "\n--> Not reindexing by default. Pass the --reindex flag in case the index.yaml is incomplete. See all wire charts using \n helm search repo %s/ -l\n\n" "$REPO_NAME" fi diff --git a/integration/test/Test/FeatureFlags/SearchVisibilityInbound.hs b/integration/test/Test/FeatureFlags/SearchVisibilityInbound.hs index 55d40c5c2f7..c1ef7a5d3ca 100644 --- a/integration/test/Test/FeatureFlags/SearchVisibilityInbound.hs +++ b/integration/test/Test/FeatureFlags/SearchVisibilityInbound.hs @@ -1,24 +1,10 @@ module Test.FeatureFlags.SearchVisibilityInbound where import qualified API.Galley as Public -import qualified API.GalleyInternal as Internal import SetupHelpers import Test.FeatureFlags.Util import Testlib.Prelude -testFeatureNoConfigMultiSearchVisibilityInbound :: (HasCallStack) => App () -testFeatureNoConfigMultiSearchVisibilityInbound = do - (_owner1, team1, _) <- createTeam OwnDomain 0 - (_owner2, team2, _) <- createTeam OwnDomain 0 - - assertSuccess =<< Internal.setTeamFeatureStatus OwnDomain team2 "searchVisibilityInbound" "enabled" - - response <- Internal.getFeatureStatusMulti OwnDomain "searchVisibilityInbound" [team1, team2] - - statuses <- response.json %. "default_status" >>= asList - length statuses `shouldMatchInt` 2 - statuses `shouldMatchSet` [object ["team" .= team1, "status" .= "disabled"], object ["team" .= team2, "status" .= "enabled"]] - testSearchVisibilityInboundInternal :: (HasCallStack) => APIAccess -> App () testSearchVisibilityInboundInternal access = do let featureName = "searchVisibilityInbound" diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Galley.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Galley.hs index bdae90491ca..5ea262e42cb 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/Galley.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/Galley.hs @@ -39,7 +39,6 @@ import Wire.API.Provider.Service (ServiceRef) import Wire.API.Routes.Features import Wire.API.Routes.Internal.Brig.EJPD import Wire.API.Routes.Internal.Galley.ConversationsIntra -import Wire.API.Routes.Internal.Galley.TeamFeatureNoConfigMulti import Wire.API.Routes.Internal.Galley.TeamsIntra import Wire.API.Routes.MultiVerb import Wire.API.Routes.Named @@ -82,8 +81,6 @@ type IFeatureAPI = :<|> IFeatureStatusLockStatusPut MlsE2EIdConfig :<|> IFeatureStatusLockStatusPut MlsMigrationConfig :<|> IFeatureStatusLockStatusPut EnforceFileDownloadLocationConfig - -- special endpoints - :<|> IFeatureNoConfigMultiGet SearchVisibilityInboundConfig -- all feature configs :<|> Named "feature-configs-internal" @@ -359,19 +356,6 @@ type IFeatureStatusLockStatusPut cfg = :> Put '[JSON] LockStatusResponse ) -type FeatureNoConfigMultiGetBase featureName = - Summary - (AppendSymbol "Get team feature status in bulk for feature " (FeatureSymbol featureName)) - :> "features-multi-teams" - :> FeatureSymbol featureName - :> ReqBody '[JSON] TeamFeatureNoConfigMultiRequest - :> Post '[JSON] (TeamFeatureNoConfigMultiResponse featureName) - -type IFeatureNoConfigMultiGet f = - Named - '("igetmulti", f) - (FeatureNoConfigMultiGetBase f) - type IFederationAPI = Named "get-federation-status" diff --git a/libs/wire-api/src/Wire/API/Routes/Internal/Galley/TeamFeatureNoConfigMulti.hs b/libs/wire-api/src/Wire/API/Routes/Internal/Galley/TeamFeatureNoConfigMulti.hs index 9f96c0b024c..8bb68c6eb38 100644 --- a/libs/wire-api/src/Wire/API/Routes/Internal/Galley/TeamFeatureNoConfigMulti.hs +++ b/libs/wire-api/src/Wire/API/Routes/Internal/Galley/TeamFeatureNoConfigMulti.hs @@ -16,9 +16,7 @@ -- with this program. If not, see . module Wire.API.Routes.Internal.Galley.TeamFeatureNoConfigMulti - ( TeamFeatureNoConfigMultiRequest (..), - TeamFeatureNoConfigMultiResponse (..), - TeamStatus (..), + ( TeamStatus (..), ) where @@ -29,30 +27,6 @@ import Data.Schema import Imports import Wire.API.Team.Feature qualified as Public -newtype TeamFeatureNoConfigMultiRequest = TeamFeatureNoConfigMultiRequest - { teams :: [TeamId] - } - deriving (Show, Eq) - deriving (A.ToJSON, A.FromJSON, S.ToSchema) via Schema TeamFeatureNoConfigMultiRequest - -instance ToSchema TeamFeatureNoConfigMultiRequest where - schema = - object "TeamFeatureNoConfigMultiRequest" $ - TeamFeatureNoConfigMultiRequest - <$> teams .= field "teams" (array schema) - -newtype TeamFeatureNoConfigMultiResponse cfg = TeamFeatureNoConfigMultiResponse - { teamsStatuses :: [TeamStatus cfg] - } - deriving (Show, Eq) - deriving (A.ToJSON, A.FromJSON, S.ToSchema) via Schema (TeamFeatureNoConfigMultiResponse cfg) - -instance ToSchema (TeamFeatureNoConfigMultiResponse cfg) where - schema = - object "TeamFeatureNoConfigMultiResponse" $ - TeamFeatureNoConfigMultiResponse - <$> teamsStatuses .= field "default_status" (array schema) - data TeamStatus cfg = TeamStatus { team :: TeamId, status :: Public.FeatureStatus diff --git a/libs/wire-api/test/golden/gentests.sh b/libs/wire-api/test/golden/gentests.sh index cff8c340c87..af1d4596bc5 100644 --- a/libs/wire-api/test/golden/gentests.sh +++ b/libs/wire-api/test/golden/gentests.sh @@ -11,7 +11,8 @@ set -e set -o pipefail -export GOLDEN_TMPDIR=$(mktemp -d) +GOLDEN_TMPDIR=$(mktemp -d) +export GOLDEN_TMPDIR export GOLDEN_TESTDIR="test/unit/Test/Wire/API/Golden/Generated" # trap cleanup EXIT @@ -149,7 +150,7 @@ mkdir -p "$GOLDEN_TESTDIR" mkdir -p "$GOLDEN_TMPDIR/dump" stack build --fast --test --bench --no-run-benchmarks wire-api | - while read module section; do + while read -r module section; do echo -ne "\033[KProcessing module $module...\r" { echo "{-# OPTIONS_GHC -Wno-unused-imports #-}" @@ -194,10 +195,10 @@ for module in "$GOLDEN_TESTDIR"/*; do -e '/^import/d' \ -e "/^module/ r $dump" \ "$module" - ormolu -m inplace -c ${EXTS[@]/#/'-o '} "$module" + ormolu -m inplace -c "${EXTS[@]/#/'-o '}" "$module" done -ormolu -m inplace -c ${EXTS[@]/#/'-o '} "$GOLDEN_TESTDIR.hs" +ormolu -m inplace -c "${EXTS[@]/#/'-o '}" "$GOLDEN_TESTDIR.hs" ( cd ../.. && headroom run -a -s libs/wire-api/test/unit/Test/Wire/API/Golden/ ) # build one final time diff --git a/services/brig/federation-tests.sh b/services/brig/federation-tests.sh index 7a37655048e..09a9597d868 100755 --- a/services/brig/federation-tests.sh +++ b/services/brig/federation-tests.sh @@ -44,4 +44,4 @@ AWS_REGION="$(kubectl get deployment -n "$NAMESPACE" brig -o json | jq -r '.spec export AWS_REGION # shellcheck disable=SC2086 -telepresence --namespace "$NAMESPACE" --also-proxy=cassandra-ephemeral ${alsoProxyOptions[*]} --run bash -c "./dist/brig-integration -p federation-end2end-user -i i.yaml -s b.yaml" +telepresence --namespace "$NAMESPACE" --also-proxy=cassandra-ephemeral "${alsoProxyOptions[@]}" --run bash -c "./dist/brig-integration -p federation-end2end-user -i i.yaml -s b.yaml" diff --git a/services/galley/src/Galley/API/Internal.hs b/services/galley/src/Galley/API/Internal.hs index 411ad8fe295..eecc5ad3031 100644 --- a/services/galley/src/Galley/API/Internal.hs +++ b/services/galley/src/Galley/API/Internal.hs @@ -284,8 +284,6 @@ featureAPI = <@> mkNamedAPI @'("ilock", MlsE2EIdConfig) (updateLockStatus @MlsE2EIdConfig) <@> mkNamedAPI @'("ilock", MlsMigrationConfig) (updateLockStatus @MlsMigrationConfig) <@> mkNamedAPI @'("ilock", EnforceFileDownloadLocationConfig) (updateLockStatus @EnforceFileDownloadLocationConfig) - -- special endpoints - <@> mkNamedAPI @'("igetmulti", SearchVisibilityInboundConfig) getFeatureMulti -- all features <@> mkNamedAPI @"feature-configs-internal" (maybe getAllTeamFeaturesForServer getAllTeamFeaturesForUser) diff --git a/services/galley/src/Galley/API/Teams/Features.hs b/services/galley/src/Galley/API/Teams/Features.hs index 01edafee051..53a5eb888d8 100644 --- a/services/galley/src/Galley/API/Teams/Features.hs +++ b/services/galley/src/Galley/API/Teams/Features.hs @@ -18,8 +18,7 @@ -- with this program. If not, see . module Galley.API.Teams.Features - ( getFeatureMulti, - setFeature, + ( setFeature, setFeatureInternal, patchFeatureInternal, getAllTeamFeaturesForTeam, diff --git a/services/galley/src/Galley/API/Teams/Features/Get.hs b/services/galley/src/Galley/API/Teams/Features/Get.hs index d4d448fd700..9ad936175ae 100644 --- a/services/galley/src/Galley/API/Teams/Features/Get.hs +++ b/services/galley/src/Galley/API/Teams/Features/Get.hs @@ -21,7 +21,6 @@ module Galley.API.Teams.Features.Get ( getFeature, getFeatureInternal, - getFeatureMulti, getAllTeamFeaturesForServer, getAllTeamFeaturesForTeam, getAllTeamFeaturesForUser, @@ -142,20 +141,6 @@ getFeatureInternal tid = do assertTeamExists tid getFeatureForTeam tid -getFeatureMulti :: - forall cfg r. - ( GetFeatureConfig cfg, - ComputeFeatureConstraints cfg r, - Member (Input Opts) r, - Member TeamFeatureStore r - ) => - Multi.TeamFeatureNoConfigMultiRequest -> - Sem r (Multi.TeamFeatureNoConfigMultiResponse cfg) -getFeatureMulti (Multi.TeamFeatureNoConfigMultiRequest tids) = do - cfgs <- getFeatureForMultiTeam @cfg tids - let xs = uncurry toTeamStatus <$> cfgs - pure $ Multi.TeamFeatureNoConfigMultiResponse xs - toTeamStatus :: TeamId -> LockableFeature cfg -> Multi.TeamStatus cfg toTeamStatus tid feat = Multi.TeamStatus tid feat.status @@ -246,7 +231,9 @@ getAllTeamFeaturesForUser :: Sem r AllTeamFeatures getAllTeamFeaturesForUser uid = do mTid <- getTeamAndCheckMembership uid - hsequence' $ hcpure (Proxy @(GetAllTeamFeaturesForUserConstraints r)) $ Comp $ getFeatureForTeamUser uid mTid + case mTid of + Nothing -> hsequence' $ hcpure (Proxy @(GetAllTeamFeaturesForUserConstraints r)) $ Comp $ getFeatureForUser uid + Just tid -> getAllTeamFeatures tid getSingleFeatureForUser :: forall cfg r. @@ -282,22 +269,6 @@ getFeatureForTeam tid = do defFeature dbFeature -getFeatureForMultiTeam :: - forall cfg r. - ( GetFeatureConfig cfg, - ComputeFeatureConstraints cfg r, - Member TeamFeatureStore r, - Member (Input Opts) r - ) => - [TeamId] -> - Sem r [(TeamId, LockableFeature cfg)] -getFeatureForMultiTeam tids = do - defFeature <- getFeatureForServer - features <- getDbFeatureMulti tids - for features $ \(tid, dbFeature) -> do - feat <- computeFeature @cfg tid defFeature dbFeature - pure (tid, feat) - getFeatureForTeamUser :: forall cfg r. ( GetFeatureConfig cfg, diff --git a/services/galley/src/Galley/Cassandra/TeamFeatures.hs b/services/galley/src/Galley/Cassandra/TeamFeatures.hs index 55bb2a9b840..04a5ab8f3ab 100644 --- a/services/galley/src/Galley/Cassandra/TeamFeatures.hs +++ b/services/galley/src/Galley/Cassandra/TeamFeatures.hs @@ -19,7 +19,6 @@ module Galley.Cassandra.TeamFeatures ( interpretTeamFeatureStoreToCassandra, - getDbFeatureMulti, getAllTeamFeaturesForServer, ) where @@ -38,7 +37,6 @@ import Imports import Polysemy import Polysemy.Input import Polysemy.TinyLog -import UnliftIO.Async (pooledMapConcurrentlyN) import Wire.API.Team.Feature interpretTeamFeatureStoreToCassandra :: @@ -52,9 +50,6 @@ interpretTeamFeatureStoreToCassandra = interpret $ \case TFS.GetDbFeature sing tid -> do logEffect "TeamFeatureStore.GetFeatureConfig" embedClient $ getDbFeature sing tid - TFS.GetDbFeatureMulti sing tids -> do - logEffect "TeamFeatureStore.GetFeatureConfigMulti" - embedClient $ getDbFeatureMulti sing tids TFS.SetDbFeature sing tid feat -> do logEffect "TeamFeatureStore.SetFeatureConfig" embedClient $ setDbFeature sing tid feat @@ -65,15 +60,6 @@ interpretTeamFeatureStoreToCassandra = interpret $ \case logEffect "TeamFeatureStore.GetAllTeamFeatures" embedClient $ getAllDbFeatures tid -getDbFeatureMulti :: - forall cfg m. - (MonadClient m, MonadUnliftIO m) => - FeatureSingleton cfg -> - [TeamId] -> - m [(TeamId, DbFeature cfg)] -getDbFeatureMulti proxy = - pooledMapConcurrentlyN 8 (\tid -> getDbFeature proxy tid <&> (tid,)) - getDbFeature :: (MonadClient m) => FeatureSingleton cfg -> TeamId -> m (DbFeature cfg) getDbFeature = $(featureCases [|fetchFeature|]) diff --git a/services/galley/src/Galley/Effects/TeamFeatureStore.hs b/services/galley/src/Galley/Effects/TeamFeatureStore.hs index a7773e1fe7f..b756ff9281f 100644 --- a/services/galley/src/Galley/Effects/TeamFeatureStore.hs +++ b/services/galley/src/Galley/Effects/TeamFeatureStore.hs @@ -27,10 +27,6 @@ data TeamFeatureStore m a where FeatureSingleton cfg -> TeamId -> TeamFeatureStore m (DbFeature cfg) - GetDbFeatureMulti :: - FeatureSingleton cfg -> - [TeamId] -> - TeamFeatureStore m [(TeamId, DbFeature cfg)] SetDbFeature :: FeatureSingleton cfg -> TeamId -> @@ -51,12 +47,6 @@ getDbFeature :: Sem r (DbFeature cfg) getDbFeature tid = send (GetDbFeature featureSingleton tid) -getDbFeatureMulti :: - (Member TeamFeatureStore r, IsFeatureConfig cfg) => - [TeamId] -> - Sem r [(TeamId, DbFeature cfg)] -getDbFeatureMulti tids = send (GetDbFeatureMulti featureSingleton tids) - setDbFeature :: (Member TeamFeatureStore r, IsFeatureConfig cfg) => TeamId -> diff --git a/services/nginz/nginz_reload.sh b/services/nginz/nginz_reload.sh index 0ed14d7444e..ff91a2a0b1c 100755 --- a/services/nginz/nginz_reload.sh +++ b/services/nginz/nginz_reload.sh @@ -19,15 +19,17 @@ watches=${WATCH_PATHS:-"/etc/wire/nginz/upstreams"} # only react on changes to upstreams.conf cfg=upstreams.conf -echo "Setting up watches for ${watches[@]}" +echo "Setting up watches for ${watches[*]}" { echo "nginx PID: $nginx_pid" + #shellcheck disable=SC2068 inotifywait -m -e moved_to -e modify,move,create,delete -m --format '%f' \ - ${watches[@]} | while read file; do \ - if [ $file == $cfg ]; then \ + ${watches[@]} | while read -r file; do \ + if [ "$file" == "$cfg" ]; then \ echo "Config file update detected"; \ nginx -t "$@"; \ + # shellcheck disable=SC2181 if [ $? -ne 0 ]; then \ echo "ERROR: New configuration is invalid!!"; \ else \ diff --git a/services/spar/test-scim-suite/mk_collection.sh b/services/spar/test-scim-suite/mk_collection.sh index 8e397c30e8c..38191024645 100755 --- a/services/spar/test-scim-suite/mk_collection.sh +++ b/services/spar/test-scim-suite/mk_collection.sh @@ -3,9 +3,9 @@ set -e setup_js_jsonlines=$(mktemp /tmp/setup_inline_XXXXXXX.json) -cat ./setup.js | python3 -c ' +python3 -c ' import sys, json; print(json.dumps(sys.stdin.read().splitlines())) -' > $setup_js_jsonlines +' > "$setup_js_jsonlines" < ./setup.js -jq --slurpfile setup_inline "$setup_js_jsonlines" -f ./update.jq $1 +jq --slurpfile setup_inline "$setup_js_jsonlines" -f ./update.jq "$1" diff --git a/services/spar/test-scim-suite/run.sh b/services/spar/test-scim-suite/run.sh index 71edb155b29..af1febc3668 100755 --- a/services/spar/test-scim-suite/run.sh +++ b/services/spar/test-scim-suite/run.sh @@ -10,32 +10,37 @@ SCIM_TEST_SUITE_BRIG_PORT=8082 function create_team_and_scim_token { TOP_LEVEL="$( cd "$( dirname "${BASH_SOURCE[0]}" )/../../.." && pwd )" - IFS=',' read -r -a creds <<< $($TOP_LEVEL/hack/bin/create_test_team_admins.sh -c) + IFS=',' read -r -a creds <<< "$("$TOP_LEVEL/hack/bin/create_test_team_admins.sh" -c)" BRIG_HOST="http://$SCIM_TEST_SUITE_BRIG_HOST:$SCIM_TEST_SUITE_BRIG_PORT" WIRE_ADMIN_UUID=${creds[0]} WIRE_ADMIN=${creds[1]} WIRE_PASSWD=${creds[2]} - export BEARER=$(curl -X POST \ - --header 'Content-Type: application/json' \ - --header 'Accept: application/json' \ - -d '{"email":"'"$WIRE_ADMIN"'","password":"'"$WIRE_PASSWD"'"}' \ - $BRIG_HOST/login'?persist=false' | jq -r .access_token) + BEARER=$(curl -X POST \ + --header 'Content-Type: application/json' \ + --header 'Accept: application/json' \ + -d '{"email":"'"$WIRE_ADMIN"'","password":"'"$WIRE_PASSWD"'"}' \ + $BRIG_HOST/login'?persist=false' | jq -r .access_token) + + export BEARER SPAR_HOST="http://$SCIM_TEST_SUITE_SPAR_HOST:$SCIM_TEST_SUITE_SPAR_PORT" - export SCIM_TOKEN_FULL=$(curl -X POST \ + SCIM_TOKEN_FULL=$(curl -X POST \ --header "Authorization: Bearer $BEARER" \ --header 'Content-Type: application/json;charset=utf-8' \ --header 'Z-User: '"$WIRE_ADMIN_UUID" \ - -d '{ "description": "test '"`date`"'", "password": "'"$WIRE_PASSWD"'" }' \ + -d '{ "description": "test '"$(date)"'", "password": "'"$WIRE_PASSWD"'" }' \ $SPAR_HOST/scim/auth-tokens) + export SCIM_TOKEN_FULL - export SCIM_TOKEN=$(echo $SCIM_TOKEN_FULL | jq -r .token) - export SCIM_TOKEN_ID=$(echo $SCIM_TOKEN_FULL | jq -r .info.id) + SCIM_TOKEN=$(echo "$SCIM_TOKEN_FULL" | jq -r .token) + export SCIM_TOKEN + SCIM_TOKEN_ID=$(echo "$SCIM_TOKEN_FULL" | jq -r .info.id) + export SCIM_TOKEN_ID - echo $SCIM_TOKEN + echo "$SCIM_TOKEN" } function create_env_file { diff --git a/services/spar/test-scim-suite/runsuite.sh b/services/spar/test-scim-suite/runsuite.sh index 51661704242..aab8e408cf4 100755 --- a/services/spar/test-scim-suite/runsuite.sh +++ b/services/spar/test-scim-suite/runsuite.sh @@ -1,5 +1,4 @@ -#!/usr/bin/env nix-shell -#!nix-shell shell.nix -i bash +#!/usr/bin/env bash set -e @@ -9,5 +8,5 @@ if [[ "$INTEGRATION_SKIP_SCIM_SUITE" -eq 1 ]]; then exit 0 fi -make collection -C $SOURCE_DIR -$SOURCE_DIR/run.sh +make collection -C "$SOURCE_DIR" +"$SOURCE_DIR/run.sh" diff --git a/tools/db/move-team/dump_merge_teams.sh b/tools/db/move-team/dump_merge_teams.sh index 28be2ef437a..33cb229781c 100644 --- a/tools/db/move-team/dump_merge_teams.sh +++ b/tools/db/move-team/dump_merge_teams.sh @@ -6,12 +6,12 @@ set -eu dir="$1" script=$( - for row in $(cat "$1/galley.team" | jq '.[0]' | uniq); do + for row in $(jq '.[0]' < "$1/galley.team" | uniq); do echo "s/$row/\"e09f7a63-b5d4-4db4-a3c1-18bddf3df7fc\"/g;" done ) -for f in $dir/*; do - echo $f - sed -e "$script" -i $f +for f in "$dir"/*; do + echo "$f" + sed -e "$script" -i "$f" done diff --git a/tools/nginz_disco/nginz_disco.sh b/tools/nginz_disco/nginz_disco.sh index 44b96e192cb..c5960d2c6cd 100755 --- a/tools/nginz_disco/nginz_disco.sh +++ b/tools/nginz_disco/nginz_disco.sh @@ -19,6 +19,7 @@ function valid_ipv4() { if [[ $ip =~ ^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$ ]]; then OIFS=$IFS IFS='.' + # shellcheck disable=SC2206 ip=($ip) IFS=$OIFS [[ ${ip[0]} -le 255 && ${ip[1]} -le 255 \ @@ -40,16 +41,20 @@ function valid_ipv6() { function upstream() { name=$1 port=${2:-'8080'} - ips=$(dig +short +retries=3 +search ${name} | sort) + ips=$(dig +short +retries=3 +search "${name}" | sort) unset servers - for ip in ${ips[@]}; do - if valid_ipv4 $ip || valid_ipv6 $ip; then + IFS=$' \t\n' + for ip in $ips; do + if valid_ipv4 "$ip" || valid_ipv6 "$ip"; then servers+=("\n\t server ${ip}:${port} max_fails=3 weight=100;") fi done; + # shellcheck disable=SC2128 if [ -n "$servers" ]; then + # shellcheck disable=SC2068,SC2116,SC2059 printf "upstream ${name} { \n\t least_conn; \n\t keepalive 32; $(echo ${servers[@]}) \n}\n" >> ${new} else + # shellcheck disable=SC2059 printf "upstream ${name} { \n\t least_conn; \n\t keepalive 32; \n\t server localhost:${port} down;\n}\n" >> ${new} fi } @@ -58,6 +63,7 @@ function routing_disco() { ivl=$(echo | awk '{ srand(); printf("%f", 1.5 + rand() * 1.5) }') upstreams=$(cat "$upstream_list") + # shellcheck disable=SC2206 upstreams=( $upstreams ) [[ -f $old ]] || touch -d "1970-01-01" $old @@ -74,8 +80,8 @@ function routing_disco() { rm -f $new - echo done, sleeping $ivl - sleep $ivl + echo done, sleeping "$ivl" + sleep "$ivl" } while true; do diff --git a/tools/ormolu.sh b/tools/ormolu.sh index de3e4fc73b6..7058e51517b 100755 --- a/tools/ormolu.sh +++ b/tools/ormolu.sh @@ -68,7 +68,7 @@ echo "language extensions are taken from the resp. cabal files" FAILURES=0 if [ -t 1 ]; then - : ${ORMOLU_CONDENSE_OUTPUT:=1} + : "${ORMOLU_CONDENSE_OUTPUT:=1}" fi if [ "$f" = "all" ] || [ "$f" = "" ]; then @@ -81,8 +81,6 @@ count=$( echo "$files" | sed '/^\s*$/d' | wc -l ) echo "Checking $count file(s)…" for hsfile in $files; do - FAILED=0 - # run in background so that we can detect Ctrl-C properly ormolu --mode $ARG_ORMOLU_MODE --check-idempotence "$hsfile" & wait $! && err=0 || err=$? diff --git a/tools/rebase-onto-formatter.sh b/tools/rebase-onto-formatter.sh index 1196fad8a35..50987d3ecf5 100755 --- a/tools/rebase-onto-formatter.sh +++ b/tools/rebase-onto-formatter.sh @@ -99,7 +99,7 @@ echo "Running the script now. This might take a while..." set -x # edit every commit Ci, adding new commits representing f at Ci and it's inverse g -git rebase $BASE_COMMIT~1 --exec "$FORMATTING_COMMAND && git commit -am format && git revert HEAD --no-edit" +git rebase "$BASE_COMMIT"~1 --exec "$FORMATTING_COMMAND && git commit -am format && git revert HEAD --no-edit" # drop last commit (do not revert formatting at the end of the branch) git reset HEAD~1 --hard @@ -110,14 +110,15 @@ git reset HEAD~1 --hard # Ci=$(git rev-parse HEAD~1); git reset --soft HEAD~3; git commit --reuse-message $Ci # We do an interactive rebase, but instead of editing the commit sequence manually, # we use sed for that, inserting an `exec` command after every 3 commits. +# shellcheck disable=SC2016 GIT_SEQUENCE_EDITOR='sed -i -e "4~3s/^\(pick \S* format\)$/\1\nexec Ci=\$(git rev-parse HEAD~1); git reset --soft HEAD~3; git commit --reuse-message \$Ci/"' \ - git rebase --interactive $BASE_COMMIT + git rebase --interactive "$BASE_COMMIT" # rebase onto TARGET_COMMIT. # Annoyingly, we still have this first "format" commit that should already be # part of the TARGET_COMMIT. So we drop it. GIT_SEQUENCE_EDITOR='sed -i "1s/pick/drop/"' \ - git rebase --interactive $BASE_COMMIT --onto $TARGET_COMMIT + git rebase --interactive "$BASE_COMMIT" --onto "$TARGET_COMMIT" echo "Done." echo "Please check that the history looks as it should and all expected commits are there." diff --git a/tools/sftd_disco/sftd_disco.sh b/tools/sftd_disco/sftd_disco.sh index 63a603df963..0834a85195e 100755 --- a/tools/sftd_disco/sftd_disco.sh +++ b/tools/sftd_disco/sftd_disco.sh @@ -12,13 +12,11 @@ old="/etc/wire/sftd-disco/sft_servers_all.json" new="${old}.new" function valid_entry() { - local line=$1 # TODO sanity check that this is real dig output return 0 } function valid_url() { - local url=$1 #TODO basic sanity check return 0 } @@ -30,23 +28,23 @@ function valid_url() { # this file can then be served from nginx running besides sft function upstream() { name=$1 - port=${2:-'8585'} - entries=$(dig +short +retries=3 +search SRV ${name} | sort) + entries=$(dig +short +retries=3 +search SRV "${name}" | sort) unset servers comma="" - IFS=$'\n' - for entry in ${entries[@]}; do + IFS=$' \t\n' + for entry in $entries; do if valid_entry "$entry"; then sft_host_port=$(echo "$entry" | awk '{print $4":"$3}') - sft_url=$(curl -s http://$sft_host_port/sft/url | xargs) + sft_url=$(curl -s http://"$sft_host_port"/sft/url | xargs) if valid_url "$sft_url"; then - servers+=(${comma}'"'${sft_url}'"') + servers+=("$comma"'"'"$sft_url"'"') comma="," fi fi done + # shellcheck disable=SC2128 if [ -n "$servers" ]; then - echo '{"sft_servers_all": ['${servers[@]}']}' | jq >${new} + echo '{"sft_servers_all": ['"${servers[*]}"']}' | jq >${new} else printf "" >>${new} fi @@ -68,10 +66,10 @@ function routing_disco() { rm -f $new - echo done, sleeping $ivl - sleep $ivl + echo done, sleeping "$ivl" + sleep "$ivl" } while true; do - routing_disco $srv_name + routing_disco "$srv_name" done diff --git a/treefmt.toml b/treefmt.toml index 6d5723fc9ef..847bdbb793f 100644 --- a/treefmt.toml +++ b/treefmt.toml @@ -18,38 +18,6 @@ command = "shellcheck" includes = ["*.sh"] excludes = [ "dist-newstyle/", - "services/nginz/third_party/", - "libs/wire-api/test/golden/gentests.sh", - "changelog.d/mk-changelog.sh", - "hack/bin/diff-failure.sh", - "hack/bin/python3.sh", - "hack/bin/cabal-run-tests.sh", - "hack/bin/integration-teardown-federation.sh", - "hack/bin/integration-setup-federation.sh", - "hack/bin/serve-charts.sh", - "hack/bin/cabal-install-artefacts.sh", - "hack/bin/helm-template.sh", - "hack/bin/set-chart-image-version.sh", - "hack/bin/copy-charts.sh", - "hack/bin/set-helm-chart-version.sh", - "hack/bin/integration-spring-cleaning.sh", - "hack/bin/upload-helm-charts-s3.sh", - "hack/bin/integration-test-logs.sh", - "services/nginz/nginz_reload.sh", - "services/spar/test-scim-suite/mk_collection.sh", - "services/spar/test-scim-suite/runsuite.sh", - "services/spar/test-scim-suite/run.sh", - "services/brig/federation-tests.sh", - "hack/bin/create_test_team_members.sh", - "hack/bin/create_test_team_scim.sh", - "hack/bin/create_test_user.sh", - "hack/bin/create_team_members.sh", - "hack/bin/register_idp_internal.sh", - "hack/bin/create_test_team_admins.sh", - "deploy/dockerephemeral/init.sh", - "tools/nginz_disco/nginz_disco.sh", - "tools/rebase-onto-formatter.sh", - "tools/sftd_disco/sftd_disco.sh", - "tools/ormolu.sh", - "tools/db/move-team/dump_merge_teams.sh" + "services/nginz/third_party/*", + "services/restund/*", ]