Merge branch 'main' into jackw/nx-task-orchestration

This commit is contained in:
Jack Westbrook
2024-02-14 14:33:27 +01:00
77 changed files with 2149 additions and 911 deletions
+3
View File
@@ -956,6 +956,9 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "18"],
[0, 0, 0, "Unexpected any. Specify a different type.", "19"]
],
"packages/grafana-ui/src/components/Splitter/Splitter.tsx:5381": [
[0, 0, 0, "Do not use any type assertions.", "0"]
],
"packages/grafana-ui/src/components/StatsPicker/StatsPicker.story.tsx:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
+152 -148
View File
@@ -2,8 +2,8 @@
-- PostgreSQL database dump
--
-- Dumped from database version 12.2 (Debian 12.2-2.pgdg100+1)
-- Dumped by pg_dump version 12.2 (Debian 12.2-2.pgdg100+1)
-- Dumped from database version 16.1
-- Dumped by pg_dump version 16.1
SET statement_timeout = 0;
SET lock_timeout = 0;
@@ -386,7 +386,7 @@ CREATE TABLE public.component_config (
id character varying(36) NOT NULL,
component_id character varying(36) NOT NULL,
name character varying(255) NOT NULL,
value character varying(4000)
value text
);
@@ -488,7 +488,8 @@ CREATE TABLE public.event_entity (
session_id character varying(255),
event_time bigint,
type character varying(255),
user_id character varying(255)
user_id character varying(255),
details_json_long_value text
);
@@ -1097,7 +1098,7 @@ ALTER TABLE public.resource_scope OWNER TO keycloak;
CREATE TABLE public.resource_server (
id character varying(36) NOT NULL,
allow_rs_remote_mgmt boolean DEFAULT false NOT NULL,
policy_enforce_mode character varying(15) NOT NULL,
policy_enforce_mode smallint NOT NULL,
decision_strategy smallint DEFAULT 1 NOT NULL
);
@@ -1132,8 +1133,8 @@ CREATE TABLE public.resource_server_policy (
name character varying(255) NOT NULL,
description character varying(255),
type character varying(255) NOT NULL,
decision_strategy character varying(20),
logic character varying(20),
decision_strategy smallint,
logic smallint,
resource_server_id character varying(36) NOT NULL,
owner character varying(255)
);
@@ -1484,7 +1485,6 @@ bfbcc1e9-f129-4336-a0cd-b6960a811bd9 \N direct-grant-validate-password master 5f
5a2470c4-3136-4cf0-8383-e74a413ccd48 \N direct-grant-validate-otp master 99865746-4232-46f0-84b5-20952fe9eb51 0 20 f \N \N
47c96943-ad68-4d93-afff-ff54fc86eb0b \N registration-page-form master 1695e7d2-ad80-4502-8479-8121a6e2a2f0 0 10 t 8fb96669-d28d-4173-a8f4-dc24d41c7d27 \N
a6678624-1bd4-4793-bfac-68551cf0ac7c \N registration-user-creation master 8fb96669-d28d-4173-a8f4-dc24d41c7d27 0 20 f \N \N
5b45827d-5dfd-4152-a99e-373cb975ef87 \N registration-profile-action master 8fb96669-d28d-4173-a8f4-dc24d41c7d27 0 40 f \N \N
5a2fb70d-63ae-4604-b37c-ae043d6a900d \N registration-password-action master 8fb96669-d28d-4173-a8f4-dc24d41c7d27 0 50 f \N \N
0b06a30e-daa7-498a-9fdb-899abbf36450 \N registration-recaptcha-action master 8fb96669-d28d-4173-a8f4-dc24d41c7d27 3 60 f \N \N
b6ab0b5d-8184-4609-bb81-da8413dfb858 \N reset-credentials-choose-user master 954b046d-2b24-405e-84ee-c44ffe603df2 0 10 f \N \N
@@ -1511,11 +1511,6 @@ d600bb67-e258-44be-8f69-f1bae9c35a0f \N idp-username-password-form master ca3a36
90cc39a9-cddb-49bd-b9f5-d64d03341333 \N auth-otp-form master a7d23655-efbb-4950-8ab6-50dbc85681a0 0 20 f \N \N
b0634301-594e-42db-9736-6c90ebbeb8b2 \N http-basic-authenticator master 57c56583-d91c-4399-bd15-05a1a17d48c1 0 10 f \N \N
34fa4d44-716b-4b2a-b98e-aa9748154292 \N docker-http-basic-authenticator master 032b05cf-0007-44da-a370-b42039f6b762 0 10 f \N \N
4838277a-46ea-4d95-bd86-d8dc6fdce352 \N no-cookie-redirect master 1c7af06b-3085-46c3-849c-34c67f581b9e 0 10 f \N \N
59a349ee-20ce-42d8-b20b-8f902c09742d \N \N master 1c7af06b-3085-46c3-849c-34c67f581b9e 0 20 t 85c00992-77dd-4262-8744-a9dd8521e98e \N
d9b5fa46-6595-4406-9841-2c0720dbf644 \N basic-auth master 85c00992-77dd-4262-8744-a9dd8521e98e 0 10 f \N \N
3a4ee6f1-1528-47c7-aeda-f317248b3b93 \N basic-auth-otp master 85c00992-77dd-4262-8744-a9dd8521e98e 3 20 f \N \N
014847fc-06df-4ddf-a8f2-deeb0f1eb59a \N auth-spnego master 85c00992-77dd-4262-8744-a9dd8521e98e 3 30 f \N \N
b46bc4f6-2fe5-44d5-b47f-36880742cf50 \N auth-cookie grafana a38aeb47-f27e-4e68-82ff-7cc7371a47a7 2 10 f \N \N
6cec48cc-066a-4e3e-8158-85351bfa4c27 \N auth-spnego grafana a38aeb47-f27e-4e68-82ff-7cc7371a47a7 3 20 f \N \N
63c55c5a-ad11-4f83-9d6e-d8ca2efcaf66 \N identity-provider-redirector grafana a38aeb47-f27e-4e68-82ff-7cc7371a47a7 2 25 f \N \N
@@ -1530,7 +1525,6 @@ b46bc4f6-2fe5-44d5-b47f-36880742cf50 \N auth-cookie grafana a38aeb47-f27e-4e68-8
d87abeef-9f1d-46f5-9f36-acd7eaf21a72 \N direct-grant-validate-otp grafana b3491338-0630-4232-97e7-a518c254b248 0 20 f \N \N
4f204bab-0311-44b4-80b6-37d23fd0fd5a \N registration-page-form grafana 9d02badd-cb1c-4655-bf5e-f888861433ff 0 10 t c3ed2ad1-cfb4-49fa-8c75-cf5047527c68 \N
2d4ee446-623c-42a0-8d4a-9f6c4f7f28ec \N registration-user-creation grafana c3ed2ad1-cfb4-49fa-8c75-cf5047527c68 0 20 f \N \N
d806effc-dd17-4468-9a98-4e1c2f9e799d \N registration-profile-action grafana c3ed2ad1-cfb4-49fa-8c75-cf5047527c68 0 40 f \N \N
306fa749-c191-43c6-bf04-0eb6d3d02732 \N registration-password-action grafana c3ed2ad1-cfb4-49fa-8c75-cf5047527c68 0 50 f \N \N
7de9bbee-eb3d-4f3e-a134-e7e8d4a6df25 \N registration-recaptcha-action grafana c3ed2ad1-cfb4-49fa-8c75-cf5047527c68 3 60 f \N \N
8a31d18e-1622-4eac-8eff-9434fa9cade3 \N reset-credentials-choose-user grafana 3085fb68-fc1f-4e1c-a8be-33fb45194b04 0 10 f \N \N
@@ -1557,11 +1551,6 @@ b8ce6905-73eb-493b-9ce1-408ec55e3c46 \N conditional-user-configured grafana 21fb
54d7692d-c0e3-40ef-9ef9-d9e8227d618d \N auth-otp-form grafana 21fbd70a-286f-431a-abc4-fbf6590fcdc3 0 20 f \N \N
3722f24d-6ffb-4b20-a481-1fd8a17afdf6 \N http-basic-authenticator grafana ba53abf5-9a64-4371-810b-67378eb3d781 0 10 f \N \N
a700b05f-a61d-4eeb-ad75-1a3df05ed429 \N docker-http-basic-authenticator grafana 95e02703-f5bc-4e04-8bef-f6adc2d8173f 0 10 f \N \N
035c4f94-03a6-4101-a729-f3c01ee4c490 \N no-cookie-redirect grafana f397495e-d073-4ef1-babf-569a338db596 0 10 f \N \N
29f310db-b302-44b2-9182-4b91648cbabf \N \N grafana f397495e-d073-4ef1-babf-569a338db596 0 20 t 56c40f89-4d69-46fd-bb18-d6c01808d2af \N
4e7d257c-e013-4597-a44d-b186a85606af \N basic-auth grafana 56c40f89-4d69-46fd-bb18-d6c01808d2af 0 10 f \N \N
2ba05817-a59f-4e72-a565-f3b4591390dc \N basic-auth-otp grafana 56c40f89-4d69-46fd-bb18-d6c01808d2af 3 20 f \N \N
5db9c781-6718-4674-a833-9a4ac3e8212e \N auth-spnego grafana 56c40f89-4d69-46fd-bb18-d6c01808d2af 3 30 f \N \N
5f032dbb-bd37-425b-af1e-ba555c7a8245 \N \N grafana b478ecfb-db7e-4797-a245-8fc3b4dec884 1 30 t b3491338-0630-4232-97e7-a518c254b248 \N
\.
@@ -1589,8 +1578,6 @@ ca3a3600-552c-4849-9a9d-826c8aa3e646 Verify Existing Account by Re-authenticatio
a7d23655-efbb-4950-8ab6-50dbc85681a0 First broker login - Conditional OTP Flow to determine if the OTP is required for the authentication master basic-flow f t
57c56583-d91c-4399-bd15-05a1a17d48c1 saml ecp SAML ECP Profile Authentication Flow master basic-flow t t
032b05cf-0007-44da-a370-b42039f6b762 docker auth Used by Docker clients to authenticate against the IDP master basic-flow t t
1c7af06b-3085-46c3-849c-34c67f581b9e http challenge An authentication flow based on challenge-response HTTP Authentication Schemes master basic-flow t t
85c00992-77dd-4262-8744-a9dd8521e98e Authentication Options Authentication options. master basic-flow f t
a38aeb47-f27e-4e68-82ff-7cc7371a47a7 browser browser based authentication grafana basic-flow t t
c53e357f-e276-43aa-b36c-46366a7ffd35 forms Username, password, otp and other auth forms. grafana basic-flow f t
cf4831e9-3e1d-452e-984e-e6d4d9eeafb5 Browser - Conditional OTP Flow to determine if the OTP is required for the authentication grafana basic-flow f t
@@ -1609,8 +1596,6 @@ df86516c-dcb1-41a8-877e-eb8805bcac8c User creation or linking Flow for the exist
21fbd70a-286f-431a-abc4-fbf6590fcdc3 First broker login - Conditional OTP Flow to determine if the OTP is required for the authentication grafana basic-flow f t
ba53abf5-9a64-4371-810b-67378eb3d781 saml ecp SAML ECP Profile Authentication Flow grafana basic-flow t t
95e02703-f5bc-4e04-8bef-f6adc2d8173f docker auth Used by Docker clients to authenticate against the IDP grafana basic-flow t t
f397495e-d073-4ef1-babf-569a338db596 http challenge An authentication flow based on challenge-response HTTP Authentication Schemes grafana basic-flow t t
56c40f89-4d69-46fd-bb18-d6c01808d2af Authentication Options Authentication options. grafana basic-flow f t
\.
@@ -1840,6 +1825,7 @@ d30340a8-630b-416e-8c93-3ccf932d34f3 false display.on.consent.screen
d30340a8-630b-416e-8c93-3ccf932d34f3 false include.in.token.scope
a96603aa-e6db-4b3e-8baa-679c75ccfc8f false display.on.consent.screen
a96603aa-e6db-4b3e-8baa-679c75ccfc8f false include.in.token.scope
c61f5b19-c17e-49a1-91b8-a0296411b928 gui.order
\.
@@ -1979,6 +1965,7 @@ a8698f4f-5fa1-4baa-be05-87d03052af49 c61f5b19-c17e-49a1-91b8-a0296411b928 f
169f1dea-80f0-4a99-8509-9abb70ab0a5c a5bb3a5f-fd26-4be6-9557-26e20a03d33d f
169f1dea-80f0-4a99-8509-9abb70ab0a5c d6ffe9fc-a03c-4496-85dc-dbb5e7754587 f
169f1dea-80f0-4a99-8509-9abb70ab0a5c c61f5b19-c17e-49a1-91b8-a0296411b928 f
09b79548-8426-4c0e-8e0b-7488467532c7 c61f5b19-c17e-49a1-91b8-a0296411b928 t
\.
@@ -2086,6 +2073,7 @@ d47557df-07ff-4cae-bedd-b584c0697852 f95566ed-b955-4668-88fc-e7413fd98615 allowe
2ae4acc4-c6d6-4d2f-92c6-3a222a7d078a 28d2466c-5af6-4786-a8a2-c25d6cb4833f allowed-protocol-mapper-types oidc-sha256-pairwise-sub-mapper
880a35e4-65a1-4697-836d-fbc46641d676 28d2466c-5af6-4786-a8a2-c25d6cb4833f allowed-protocol-mapper-types oidc-full-name-mapper
b087e631-754f-4c03-8cfc-354c7e7456fe 28d2466c-5af6-4786-a8a2-c25d6cb4833f allowed-protocol-mapper-types oidc-usermodel-property-mapper
258b8704-0587-4208-996f-96627992e370 80af2f23-4a51-498a-a011-732cf9cfa8f8 priority 100
079e63d4-0862-4e63-a62f-1a168cbbc25c 28d2466c-5af6-4786-a8a2-c25d6cb4833f allowed-protocol-mapper-types saml-user-property-mapper
da61fbc2-7533-4bc1-b0c4-357db9f108e4 28d2466c-5af6-4786-a8a2-c25d6cb4833f allowed-protocol-mapper-types oidc-address-mapper
37a4be58-26b0-4d4a-9c41-a89b27fc25f6 28d2466c-5af6-4786-a8a2-c25d6cb4833f allowed-protocol-mapper-types saml-user-attribute-mapper
@@ -2112,7 +2100,6 @@ bb8c28ca-bb74-4a07-82c3-8293354517be 9877acf2-e1cc-4038-a3c2-75db29b432e0 secret
64ea89c8-a2ce-4d2d-896d-aa49e7ca9fcc 9877acf2-e1cc-4038-a3c2-75db29b432e0 kid 7d80efc5-222b-4b6d-9b99-c3b516a59733
bec1483f-75e7-46e8-916c-102db4cbefb5 80af2f23-4a51-498a-a011-732cf9cfa8f8 certificate MIICnTCCAYUCBgF+u1ir8jANBgkqhkiG9w0BAQsFADASMRAwDgYDVQQDDAdncmFmYW5hMB4XDTIyMDIwMjE2NDkxN1oXDTMyMDIwMjE2NTA1N1owEjEQMA4GA1UEAwwHZ3JhZmFuYTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAKg5kB303DkDs5jSW1b7b7kvKfxIJorHD+7wPz2TcisfTu7rchrqAJiR/HtsPICyAw1h5ef8fGgCJf/k0z00osl/COvK8iHUdvGUnubuKUXaVwlbyaTnnyjSMUAkx+67OCrkY9B2drtZrtVc+fwnggqCsCkpoXg97tcUyfPlcUJnanxsYbirZ5KH+/e+x1jlsuBiwxascmB4IoT/zJknk5l1IVXmSOiDgqhzKRfHhVlRijOlfKyCn/EDtiv7wyQTP9wvd97zGPJqkkF2yNxueMftJsgGkF6+CZMY71BioOWAt2V8OwI32b/1v30DhtBmKdoUNGpEeCjSk91zzZqTFZUCAwEAATANBgkqhkiG9w0BAQsFAAOCAQEABlW64QxuREB81VMGsyhj4Q5RykFaVuD5O8YlwUpmVfAVLzb0Drf54Kn4bnpnckKyYV+T+HsN4QXt81UE41xH0Aai2H3vrGH+PJf6aLPCDE+jpMqtN3n6IgImJXJPL8upMfhhWDv4nkM4uynEwWupzmrKi4oJuTETSMktJby4o6//XWnCzCVMoAGFJU4gtjBUzOMLW26zD+yc+BuUtfR3HzItVHSZKQSNSFO0kVS68RgrER8qJw07z3BOJ2bPpPM0PYyEngGMaowz/T6lI32ymGMWYMAnslthS1KAW9xcTBwnrW1nMhe5a0LPxIktys/wJtxIHZLc5sOddGT4xYklLg==
48e8b904-1393-43a4-aaa1-30e2d9634b36 80af2f23-4a51-498a-a011-732cf9cfa8f8 privateKey MIIEowIBAAKCAQEAqDmQHfTcOQOzmNJbVvtvuS8p/EgmiscP7vA/PZNyKx9O7utyGuoAmJH8e2w8gLIDDWHl5/x8aAIl/+TTPTSiyX8I68ryIdR28ZSe5u4pRdpXCVvJpOefKNIxQCTH7rs4KuRj0HZ2u1mu1Vz5/CeCCoKwKSmheD3u1xTJ8+VxQmdqfGxhuKtnkof7977HWOWy4GLDFqxyYHgihP/MmSeTmXUhVeZI6IOCqHMpF8eFWVGKM6V8rIKf8QO2K/vDJBM/3C933vMY8mqSQXbI3G54x+0myAaQXr4JkxjvUGKg5YC3ZXw7AjfZv/W/fQOG0GYp2hQ0akR4KNKT3XPNmpMVlQIDAQABAoIBAF3kEt3FZoyj1j97WOOJXmf7PPHDy081n1z61jEl9FjBFqse2gbPiBmfkU3JsVMbB70WYN1D/KOIX3EdZBELKbhQoMgJ826SSPi4vJ+jWYHVRTLB+h+B70E3X6mvXa+O6uB1rIgTNl2Gxp/rTtM/scLwAiZXR/n2hzGgNr9b1gT7D7kyCUIKDiJsQed2pA6ZbSDNTQQDE2qeN/Rr/+VV4XRuIIdBXn+Brap8ihjx4Gnn/SDBKM3MZoacwgS+9CZNhLjs8Ou4xD+KyitbbGGY4ZK/ZW2eSAH4ra8vVGTDK6bJrMTAE/73A23Evp/sKtRkFqcNumJ3rCykcAJorDUK48ECgYEA0TpkTwK6f2a72ncmw7Xzy4zdu+FdkI9PzWmS4IrbYOYRwsRMQLowsUPIdtU0EMrs7PRl1dSQa3/kAnw5J8wogkqVf4dJ3/lb/N5qtsjHP87N35QMXnMdE/BC6o7t5e+iRoHMloAuSBonGC9uBn1UeHWrNeLCB8+upJoSEBKbEQ0CgYEAzdSoKL4CJo31gVEqoJFPzPemsYGmV6Zl1Vj8mqMbQd8wcJoSJWbNV/3sfpIqdvOJOXQrzm+LYIbhhUnS3ZlGBmFsqUtC7dw3AqLg53msCyJLxmCIib0m/ONCY9qczV4OkUM6HVAdgzmMqqhk5ZB70IdUyStn2meqXKXLGFlLJKkCgYEAuizHTTcUVIFJ7x/PMp8ZjKqQM7pZ02Rykkm7FGr6wsJ2U2TwpTgIU/QI0RTt+3NWV5MxepBm4gEvFrcK9MrJ0QYk+RGdPttYay5Ors8B3Vlb//Jw/ypXWYKVSLpeHhiZwTuGnPT6OdZrqy2pLcUgAQBTlONt3B2FPZqLMBoeOZECgYBuCwm0bpF7x13AO4LMwaOmc6jdMfGa3s2G2MKEcjt6ZjbhnJ2i/Wk/Z/RuXvrxCZcN7nwVLDGZ88LSnftsmiuD8cZEZIZt4NRQRoBzgOtoMHfOoYGeElCr11yBQjme2nBzXTvOvCxrIfOAsfLvgOWRQSklPF2TuOSuD72bUPIJsQKBgBbeb8rIXKRRFC3A0IkKm8C51gG8mMgPdxZMKKuVhpb6D8B5aPh+WW44yNOpn7LInYI4jzf3Kv+kcj0PNH3nFaplnyCGFfmUIg27SAsRcrJcTlXtIKooZw6oPU+dQfAo11suArVAVD6OQc/7z99VoIpLN0cUHfS/g0H1dx/r/32o
258b8704-0587-4208-996f-96627992e370 80af2f23-4a51-498a-a011-732cf9cfa8f8 priority 100
12cd94c5-bd7e-4a5c-95e2-256b0bcf14bd 261e38de-3e1f-40a3-9200-f5aac1975701 allowed-protocol-mapper-types oidc-address-mapper
f33b34f1-3793-4786-a281-b286fce52f45 261e38de-3e1f-40a3-9200-f5aac1975701 allowed-protocol-mapper-types saml-role-list-mapper
d056c1de-9aa1-46a0-a644-fafb33088967 261e38de-3e1f-40a3-9200-f5aac1975701 allowed-protocol-mapper-types saml-user-property-mapper
@@ -2226,11 +2213,11 @@ b4c89bc8-3945-4963-80b5-3da62e8c54ad 18a7066b-fe71-410e-9581-69f78347ec29
--
COPY public.credential (id, salt, type, user_id, created_date, user_label, secret_data, credential_data, priority) FROM stdin;
d4b2c483-1dd3-47f6-86bf-42548009918d \N password 74e29604-ff35-42bb-a26d-4d0b81ef0917 1643820449817 \N {"value":"Hou7HlbGvohOx6II0VSCP4BIGI4Cyzy+BcXbPUQe/kaMQzNU77kH2pOKZ236UPfkiCyOLe7A3oS0afExA+ymAQ==","salt":"urXvCw0KdWf9s74km4G+lA==","additionalParameters":{}} {"hashIterations":27500,"algorithm":"pbkdf2-sha256","additionalParameters":{}} 10
cb2bd4ed-94b8-4259-bcaa-9250c3fb28d3 \N password 6db3c5e5-b84b-4f9d-a7a8-8d05b03c929d 1657026827644 \N {"value":"q3Z59Nh/5bdezDEpCwEbMPu8d+VgJ5WetafXkR8l0FlsTTkSDQgW+j6GaM3seJR93p3/jCxyfsvZl062d1pq7w==","salt":"ohuHnjLnwF9dBZ38DRJJWg==","additionalParameters":{}} {"hashIterations":27500,"algorithm":"pbkdf2-sha256","additionalParameters":{}} 10
b58e1964-6466-40b2-879c-982b724d7f9c \N password 88692d07-bb9a-46cf-844c-7ff5c529cd04 1657026904515 \N {"value":"+/0zWjiJyE3+dCOEf0SO6G3n1/LsFAVoDAZREKTfN4vQ5xJH8srJoCjxcgb+bI1crMr8gknDlFyGRy7CpYn2VQ==","salt":"v/2okNt3wGOZz+x4DjOCDQ==","additionalParameters":{}} {"hashIterations":27500,"algorithm":"pbkdf2-sha256","additionalParameters":{}} 10
3ff7dd8f-a299-4b51-bf5d-99665ccfd313 \N password 8f58cbec-6e40-4bab-bff0-1c5ff899fe2e 1657026943075 \N {"value":"nMYodMJMiq/J8g9vRPktGc7WSWnOKr6leMDZX4p9K9KgAUYeXFDSu+d29PWWn0rFn93dL0PNdIdHWNQhfkIDMg==","salt":"rmi9WLHgarmIXGukecSIig==","additionalParameters":{}} {"hashIterations":27500,"algorithm":"pbkdf2-sha256","additionalParameters":{}} 10
c9582964-cfdd-49a1-99fb-847604b0c78c \N password 1a85b7e0-4baa-420b-89f8-1cea43a540dd 1662480997923 \N {"value":"ViNTHbpBUNdtH1qGSlip7WFI8Z9lvcGQdbL8Yw48zUgB46jVFbD1eNrOw68p3ovDwfDCIJKm34EFNbw9/uzHSg==","salt":"Z9P8RfnrQwCn0xUTpWC2DQ==","additionalParameters":{}} {"hashIterations":27500,"algorithm":"pbkdf2-sha256","additionalParameters":{}} 10
b58e1964-6466-40b2-879c-982b724d7f9c \N password 88692d07-bb9a-46cf-844c-7ff5c529cd04 1657026904515 \N {"value":"L/GNO2HAU90A/ajXqyZyujncf+GfJiLWzNVTIDAVj1k=","salt":"L6WsIapZ+hKo0809G6c6SA==","additionalParameters":{}} {"hashIterations":27500,"algorithm":"pbkdf2-sha256","additionalParameters":{}} 10
d4b2c483-1dd3-47f6-86bf-42548009918d \N password 74e29604-ff35-42bb-a26d-4d0b81ef0917 1643820449817 \N {"value":"GweNaTEq3+hCqr5bBhnfqUd0oAiv8G4eUBkQUqtqiTI=","salt":"z64RYF8zRJz9ko0KDrIPxw==","additionalParameters":{}} {"hashIterations":27500,"algorithm":"pbkdf2-sha256","additionalParameters":{}} 10
3ff7dd8f-a299-4b51-bf5d-99665ccfd313 \N password 8f58cbec-6e40-4bab-bff0-1c5ff899fe2e 1657026943075 \N {"value":"81KWe14rtsbn3SS6YbWzBy2SvBQhmH+0MDHkK7aXCbo=","salt":"CnzQUkkAMD1tPk1KFDDm1w==","additionalParameters":{}} {"hashIterations":27500,"algorithm":"pbkdf2-sha256","additionalParameters":{}} 10
\.
@@ -2239,118 +2226,125 @@ c9582964-cfdd-49a1-99fb-847604b0c78c \N password 1a85b7e0-4baa-420b-89f8-1cea43a
--
COPY public.databasechangelog (id, author, filename, dateexecuted, orderexecuted, exectype, md5sum, description, comments, tag, liquibase, contexts, labels, deployment_id) FROM stdin;
authn-3.4.0.CR1-refresh-token-max-reuse glavoie@gmail.com META-INF/jpa-changelog-authz-3.4.0.CR1.xml 2022-02-02 16:47:26.706593 49 EXECUTED \N addColumn tableName=REALM \N 3.5.4 \N \N 3820445829
1.0.0.Final-KEYCLOAK-5461 sthorger@redhat.com META-INF/jpa-changelog-1.0.0.Final.xml 2022-02-02 16:47:26.017844 1 EXECUTED \N createTable tableName=APPLICATION_DEFAULT_ROLES; createTable tableName=CLIENT; createTable tableName=CLIENT_SESSION; createTable tableName=CLIENT_SESSION_ROLE; createTable tableName=COMPOSITE_ROLE; createTable tableName=CREDENTIAL; createTable tab... \N 3.5.4 \N \N 3820445829
1.0.0.Final-KEYCLOAK-5461 sthorger@redhat.com META-INF/db2-jpa-changelog-1.0.0.Final.xml 2022-02-02 16:47:26.03122 2 MARK_RAN \N createTable tableName=APPLICATION_DEFAULT_ROLES; createTable tableName=CLIENT; createTable tableName=CLIENT_SESSION; createTable tableName=CLIENT_SESSION_ROLE; createTable tableName=COMPOSITE_ROLE; createTable tableName=CREDENTIAL; createTable tab... \N 3.5.4 \N \N 3820445829
1.1.0.Beta1 sthorger@redhat.com META-INF/jpa-changelog-1.1.0.Beta1.xml 2022-02-02 16:47:26.06085 3 EXECUTED \N delete tableName=CLIENT_SESSION_ROLE; delete tableName=CLIENT_SESSION; delete tableName=USER_SESSION; createTable tableName=CLIENT_ATTRIBUTES; createTable tableName=CLIENT_SESSION_NOTE; createTable tableName=APP_NODE_REGISTRATIONS; addColumn table... \N 3.5.4 \N \N 3820445829
1.1.0.Final sthorger@redhat.com META-INF/jpa-changelog-1.1.0.Final.xml 2022-02-02 16:47:26.065284 4 EXECUTED \N renameColumn newColumnName=EVENT_TIME, oldColumnName=TIME, tableName=EVENT_ENTITY \N 3.5.4 \N \N 3820445829
4.8.0-KEYCLOAK-8835 sguilhen@redhat.com META-INF/jpa-changelog-4.8.0.xml 2022-02-02 16:47:26.928034 70 EXECUTED \N addNotNullConstraint columnName=SSO_MAX_LIFESPAN_REMEMBER_ME, tableName=REALM; addNotNullConstraint columnName=SSO_IDLE_TIMEOUT_REMEMBER_ME, tableName=REALM \N 3.5.4 \N \N 3820445829
1.2.0.Beta1 psilva@redhat.com META-INF/jpa-changelog-1.2.0.Beta1.xml 2022-02-02 16:47:26.130908 5 EXECUTED \N delete tableName=CLIENT_SESSION_ROLE; delete tableName=CLIENT_SESSION_NOTE; delete tableName=CLIENT_SESSION; delete tableName=USER_SESSION; createTable tableName=PROTOCOL_MAPPER; createTable tableName=PROTOCOL_MAPPER_CONFIG; createTable tableName=... \N 3.5.4 \N \N 3820445829
1.2.0.Beta1 psilva@redhat.com META-INF/db2-jpa-changelog-1.2.0.Beta1.xml 2022-02-02 16:47:26.133863 6 MARK_RAN \N delete tableName=CLIENT_SESSION_ROLE; delete tableName=CLIENT_SESSION_NOTE; delete tableName=CLIENT_SESSION; delete tableName=USER_SESSION; createTable tableName=PROTOCOL_MAPPER; createTable tableName=PROTOCOL_MAPPER_CONFIG; createTable tableName=... \N 3.5.4 \N \N 3820445829
1.2.0.RC1 bburke@redhat.com META-INF/jpa-changelog-1.2.0.CR1.xml 2022-02-02 16:47:26.183318 7 EXECUTED \N delete tableName=CLIENT_SESSION_ROLE; delete tableName=CLIENT_SESSION_NOTE; delete tableName=CLIENT_SESSION; delete tableName=USER_SESSION_NOTE; delete tableName=USER_SESSION; createTable tableName=MIGRATION_MODEL; createTable tableName=IDENTITY_P... \N 3.5.4 \N \N 3820445829
1.2.0.RC1 bburke@redhat.com META-INF/db2-jpa-changelog-1.2.0.CR1.xml 2022-02-02 16:47:26.186858 8 MARK_RAN \N delete tableName=CLIENT_SESSION_ROLE; delete tableName=CLIENT_SESSION_NOTE; delete tableName=CLIENT_SESSION; delete tableName=USER_SESSION_NOTE; delete tableName=USER_SESSION; createTable tableName=MIGRATION_MODEL; createTable tableName=IDENTITY_P... \N 3.5.4 \N \N 3820445829
1.2.0.Final keycloak META-INF/jpa-changelog-1.2.0.Final.xml 2022-02-02 16:47:26.19172 9 EXECUTED \N update tableName=CLIENT; update tableName=CLIENT; update tableName=CLIENT \N 3.5.4 \N \N 3820445829
1.3.0 bburke@redhat.com META-INF/jpa-changelog-1.3.0.xml 2022-02-02 16:47:26.242162 10 EXECUTED \N delete tableName=CLIENT_SESSION_ROLE; delete tableName=CLIENT_SESSION_PROT_MAPPER; delete tableName=CLIENT_SESSION_NOTE; delete tableName=CLIENT_SESSION; delete tableName=USER_SESSION_NOTE; delete tableName=USER_SESSION; createTable tableName=ADMI... \N 3.5.4 \N \N 3820445829
1.4.0 bburke@redhat.com META-INF/jpa-changelog-1.4.0.xml 2022-02-02 16:47:26.275929 11 EXECUTED \N delete tableName=CLIENT_SESSION_AUTH_STATUS; delete tableName=CLIENT_SESSION_ROLE; delete tableName=CLIENT_SESSION_PROT_MAPPER; delete tableName=CLIENT_SESSION_NOTE; delete tableName=CLIENT_SESSION; delete tableName=USER_SESSION_NOTE; delete table... \N 3.5.4 \N \N 3820445829
1.4.0 bburke@redhat.com META-INF/db2-jpa-changelog-1.4.0.xml 2022-02-02 16:47:26.278548 12 MARK_RAN \N delete tableName=CLIENT_SESSION_AUTH_STATUS; delete tableName=CLIENT_SESSION_ROLE; delete tableName=CLIENT_SESSION_PROT_MAPPER; delete tableName=CLIENT_SESSION_NOTE; delete tableName=CLIENT_SESSION; delete tableName=USER_SESSION_NOTE; delete table... \N 3.5.4 \N \N 3820445829
1.5.0 bburke@redhat.com META-INF/jpa-changelog-1.5.0.xml 2022-02-02 16:47:26.287616 13 EXECUTED \N delete tableName=CLIENT_SESSION_AUTH_STATUS; delete tableName=CLIENT_SESSION_ROLE; delete tableName=CLIENT_SESSION_PROT_MAPPER; delete tableName=CLIENT_SESSION_NOTE; delete tableName=CLIENT_SESSION; delete tableName=USER_SESSION_NOTE; delete table... \N 3.5.4 \N \N 3820445829
1.6.1_from15 mposolda@redhat.com META-INF/jpa-changelog-1.6.1.xml 2022-02-02 16:47:26.299798 14 EXECUTED \N addColumn tableName=REALM; addColumn tableName=KEYCLOAK_ROLE; addColumn tableName=CLIENT; createTable tableName=OFFLINE_USER_SESSION; createTable tableName=OFFLINE_CLIENT_SESSION; addPrimaryKey constraintName=CONSTRAINT_OFFL_US_SES_PK2, tableName=... \N 3.5.4 \N \N 3820445829
1.6.1_from16-pre mposolda@redhat.com META-INF/jpa-changelog-1.6.1.xml 2022-02-02 16:47:26.302088 15 MARK_RAN \N delete tableName=OFFLINE_CLIENT_SESSION; delete tableName=OFFLINE_USER_SESSION \N 3.5.4 \N \N 3820445829
1.6.1_from16 mposolda@redhat.com META-INF/jpa-changelog-1.6.1.xml 2022-02-02 16:47:26.303889 16 MARK_RAN \N dropPrimaryKey constraintName=CONSTRAINT_OFFLINE_US_SES_PK, tableName=OFFLINE_USER_SESSION; dropPrimaryKey constraintName=CONSTRAINT_OFFLINE_CL_SES_PK, tableName=OFFLINE_CLIENT_SESSION; addColumn tableName=OFFLINE_USER_SESSION; update tableName=OF... \N 3.5.4 \N \N 3820445829
1.6.1 mposolda@redhat.com META-INF/jpa-changelog-1.6.1.xml 2022-02-02 16:47:26.306641 17 EXECUTED \N empty \N 3.5.4 \N \N 3820445829
1.7.0 bburke@redhat.com META-INF/jpa-changelog-1.7.0.xml 2022-02-02 16:47:26.338791 18 EXECUTED \N createTable tableName=KEYCLOAK_GROUP; createTable tableName=GROUP_ROLE_MAPPING; createTable tableName=GROUP_ATTRIBUTE; createTable tableName=USER_GROUP_MEMBERSHIP; createTable tableName=REALM_DEFAULT_GROUPS; addColumn tableName=IDENTITY_PROVIDER; ... \N 3.5.4 \N \N 3820445829
1.8.0 mposolda@redhat.com META-INF/jpa-changelog-1.8.0.xml 2022-02-02 16:47:26.381463 19 EXECUTED \N addColumn tableName=IDENTITY_PROVIDER; createTable tableName=CLIENT_TEMPLATE; createTable tableName=CLIENT_TEMPLATE_ATTRIBUTES; createTable tableName=TEMPLATE_SCOPE_MAPPING; dropNotNullConstraint columnName=CLIENT_ID, tableName=PROTOCOL_MAPPER; ad... \N 3.5.4 \N \N 3820445829
1.8.0-2 keycloak META-INF/jpa-changelog-1.8.0.xml 2022-02-02 16:47:26.390165 20 EXECUTED \N dropDefaultValue columnName=ALGORITHM, tableName=CREDENTIAL; update tableName=CREDENTIAL \N 3.5.4 \N \N 3820445829
authz-3.4.0.CR1-resource-server-pk-change-part1 glavoie@gmail.com META-INF/jpa-changelog-authz-3.4.0.CR1.xml 2022-02-02 16:47:26.679075 45 EXECUTED \N addColumn tableName=RESOURCE_SERVER_POLICY; addColumn tableName=RESOURCE_SERVER_RESOURCE; addColumn tableName=RESOURCE_SERVER_SCOPE \N 3.5.4 \N \N 3820445829
1.8.0 mposolda@redhat.com META-INF/db2-jpa-changelog-1.8.0.xml 2022-02-02 16:47:26.392862 21 MARK_RAN \N addColumn tableName=IDENTITY_PROVIDER; createTable tableName=CLIENT_TEMPLATE; createTable tableName=CLIENT_TEMPLATE_ATTRIBUTES; createTable tableName=TEMPLATE_SCOPE_MAPPING; dropNotNullConstraint columnName=CLIENT_ID, tableName=PROTOCOL_MAPPER; ad... \N 3.5.4 \N \N 3820445829
1.8.0-2 keycloak META-INF/db2-jpa-changelog-1.8.0.xml 2022-02-02 16:47:26.395652 22 MARK_RAN \N dropDefaultValue columnName=ALGORITHM, tableName=CREDENTIAL; update tableName=CREDENTIAL \N 3.5.4 \N \N 3820445829
1.9.0 mposolda@redhat.com META-INF/jpa-changelog-1.9.0.xml 2022-02-02 16:47:26.40969 23 EXECUTED \N update tableName=REALM; update tableName=REALM; update tableName=REALM; update tableName=REALM; update tableName=CREDENTIAL; update tableName=CREDENTIAL; update tableName=CREDENTIAL; update tableName=REALM; update tableName=REALM; customChange; dr... \N 3.5.4 \N \N 3820445829
1.9.1 keycloak META-INF/jpa-changelog-1.9.1.xml 2022-02-02 16:47:26.414344 24 EXECUTED \N modifyDataType columnName=PRIVATE_KEY, tableName=REALM; modifyDataType columnName=PUBLIC_KEY, tableName=REALM; modifyDataType columnName=CERTIFICATE, tableName=REALM \N 3.5.4 \N \N 3820445829
1.9.1 keycloak META-INF/db2-jpa-changelog-1.9.1.xml 2022-02-02 16:47:26.416193 25 MARK_RAN \N modifyDataType columnName=PRIVATE_KEY, tableName=REALM; modifyDataType columnName=CERTIFICATE, tableName=REALM \N 3.5.4 \N \N 3820445829
1.9.2 keycloak META-INF/jpa-changelog-1.9.2.xml 2022-02-02 16:47:26.437367 26 EXECUTED \N createIndex indexName=IDX_USER_EMAIL, tableName=USER_ENTITY; createIndex indexName=IDX_USER_ROLE_MAPPING, tableName=USER_ROLE_MAPPING; createIndex indexName=IDX_USER_GROUP_MAPPING, tableName=USER_GROUP_MEMBERSHIP; createIndex indexName=IDX_USER_CO... \N 3.5.4 \N \N 3820445829
9.0.1-KEYCLOAK-12579-recreate-constraints keycloak META-INF/jpa-changelog-9.0.1.xml 2022-02-02 16:47:26.981645 84 MARK_RAN \N addUniqueConstraint constraintName=SIBLING_NAMES, tableName=KEYCLOAK_GROUP \N 3.5.4 \N \N 3820445829
authz-2.0.0 psilva@redhat.com META-INF/jpa-changelog-authz-2.0.0.xml 2022-02-02 16:47:26.481647 27 EXECUTED \N createTable tableName=RESOURCE_SERVER; addPrimaryKey constraintName=CONSTRAINT_FARS, tableName=RESOURCE_SERVER; addUniqueConstraint constraintName=UK_AU8TT6T700S9V50BU18WS5HA6, tableName=RESOURCE_SERVER; createTable tableName=RESOURCE_SERVER_RESOU... \N 3.5.4 \N \N 3820445829
authz-2.5.1 psilva@redhat.com META-INF/jpa-changelog-authz-2.5.1.xml 2022-02-02 16:47:26.484459 28 EXECUTED \N update tableName=RESOURCE_SERVER_POLICY \N 3.5.4 \N \N 3820445829
2.1.0-KEYCLOAK-5461 bburke@redhat.com META-INF/jpa-changelog-2.1.0.xml 2022-02-02 16:47:26.523006 29 EXECUTED \N createTable tableName=BROKER_LINK; createTable tableName=FED_USER_ATTRIBUTE; createTable tableName=FED_USER_CONSENT; createTable tableName=FED_USER_CONSENT_ROLE; createTable tableName=FED_USER_CONSENT_PROT_MAPPER; createTable tableName=FED_USER_CR... \N 3.5.4 \N \N 3820445829
2.2.0 bburke@redhat.com META-INF/jpa-changelog-2.2.0.xml 2022-02-02 16:47:26.532066 30 EXECUTED \N addColumn tableName=ADMIN_EVENT_ENTITY; createTable tableName=CREDENTIAL_ATTRIBUTE; createTable tableName=FED_CREDENTIAL_ATTRIBUTE; modifyDataType columnName=VALUE, tableName=CREDENTIAL; addForeignKeyConstraint baseTableName=FED_CREDENTIAL_ATTRIBU... \N 3.5.4 \N \N 3820445829
2.3.0 bburke@redhat.com META-INF/jpa-changelog-2.3.0.xml 2022-02-02 16:47:26.541837 31 EXECUTED \N createTable tableName=FEDERATED_USER; addPrimaryKey constraintName=CONSTR_FEDERATED_USER, tableName=FEDERATED_USER; dropDefaultValue columnName=TOTP, tableName=USER_ENTITY; dropColumn columnName=TOTP, tableName=USER_ENTITY; addColumn tableName=IDE... \N 3.5.4 \N \N 3820445829
2.4.0 bburke@redhat.com META-INF/jpa-changelog-2.4.0.xml 2022-02-02 16:47:26.545809 32 EXECUTED \N customChange \N 3.5.4 \N \N 3820445829
2.5.0 bburke@redhat.com META-INF/jpa-changelog-2.5.0.xml 2022-02-02 16:47:26.549823 33 EXECUTED \N customChange; modifyDataType columnName=USER_ID, tableName=OFFLINE_USER_SESSION \N 3.5.4 \N \N 3820445829
2.5.0-unicode-oracle hmlnarik@redhat.com META-INF/jpa-changelog-2.5.0.xml 2022-02-02 16:47:26.55176 34 MARK_RAN \N modifyDataType columnName=DESCRIPTION, tableName=AUTHENTICATION_FLOW; modifyDataType columnName=DESCRIPTION, tableName=CLIENT_TEMPLATE; modifyDataType columnName=DESCRIPTION, tableName=RESOURCE_SERVER_POLICY; modifyDataType columnName=DESCRIPTION,... \N 3.5.4 \N \N 3820445829
2.5.0-unicode-other-dbs hmlnarik@redhat.com META-INF/jpa-changelog-2.5.0.xml 2022-02-02 16:47:26.567305 35 EXECUTED \N modifyDataType columnName=DESCRIPTION, tableName=AUTHENTICATION_FLOW; modifyDataType columnName=DESCRIPTION, tableName=CLIENT_TEMPLATE; modifyDataType columnName=DESCRIPTION, tableName=RESOURCE_SERVER_POLICY; modifyDataType columnName=DESCRIPTION,... \N 3.5.4 \N \N 3820445829
2.5.0-duplicate-email-support slawomir@dabek.name META-INF/jpa-changelog-2.5.0.xml 2022-02-02 16:47:26.570727 36 EXECUTED \N addColumn tableName=REALM \N 3.5.4 \N \N 3820445829
2.5.0-unique-group-names hmlnarik@redhat.com META-INF/jpa-changelog-2.5.0.xml 2022-02-02 16:47:26.578396 37 EXECUTED \N addUniqueConstraint constraintName=SIBLING_NAMES, tableName=KEYCLOAK_GROUP \N 3.5.4 \N \N 3820445829
2.5.1 bburke@redhat.com META-INF/jpa-changelog-2.5.1.xml 2022-02-02 16:47:26.581391 38 EXECUTED \N addColumn tableName=FED_USER_CONSENT \N 3.5.4 \N \N 3820445829
3.0.0 bburke@redhat.com META-INF/jpa-changelog-3.0.0.xml 2022-02-02 16:47:26.584204 39 EXECUTED \N addColumn tableName=IDENTITY_PROVIDER \N 3.5.4 \N \N 3820445829
3.2.0-fix keycloak META-INF/jpa-changelog-3.2.0.xml 2022-02-02 16:47:26.585877 40 MARK_RAN \N addNotNullConstraint columnName=REALM_ID, tableName=CLIENT_INITIAL_ACCESS \N 3.5.4 \N \N 3820445829
3.2.0-fix-with-keycloak-5416 keycloak META-INF/jpa-changelog-3.2.0.xml 2022-02-02 16:47:26.587657 41 MARK_RAN \N dropIndex indexName=IDX_CLIENT_INIT_ACC_REALM, tableName=CLIENT_INITIAL_ACCESS; addNotNullConstraint columnName=REALM_ID, tableName=CLIENT_INITIAL_ACCESS; createIndex indexName=IDX_CLIENT_INIT_ACC_REALM, tableName=CLIENT_INITIAL_ACCESS \N 3.5.4 \N \N 3820445829
3.2.0-fix-offline-sessions hmlnarik META-INF/jpa-changelog-3.2.0.xml 2022-02-02 16:47:26.591561 42 EXECUTED \N customChange \N 3.5.4 \N \N 3820445829
3.2.0-fixed keycloak META-INF/jpa-changelog-3.2.0.xml 2022-02-02 16:47:26.669981 43 EXECUTED \N addColumn tableName=REALM; dropPrimaryKey constraintName=CONSTRAINT_OFFL_CL_SES_PK2, tableName=OFFLINE_CLIENT_SESSION; dropColumn columnName=CLIENT_SESSION_ID, tableName=OFFLINE_CLIENT_SESSION; addPrimaryKey constraintName=CONSTRAINT_OFFL_CL_SES_P... \N 3.5.4 \N \N 3820445829
3.3.0 keycloak META-INF/jpa-changelog-3.3.0.xml 2022-02-02 16:47:26.673701 44 EXECUTED \N addColumn tableName=USER_ENTITY \N 3.5.4 \N \N 3820445829
authz-3.4.0.CR1-resource-server-pk-change-part2-KEYCLOAK-6095 hmlnarik@redhat.com META-INF/jpa-changelog-authz-3.4.0.CR1.xml 2022-02-02 16:47:26.681987 46 EXECUTED \N customChange \N 3.5.4 \N \N 3820445829
authz-3.4.0.CR1-resource-server-pk-change-part3-fixed glavoie@gmail.com META-INF/jpa-changelog-authz-3.4.0.CR1.xml 2022-02-02 16:47:26.683661 47 MARK_RAN \N dropIndex indexName=IDX_RES_SERV_POL_RES_SERV, tableName=RESOURCE_SERVER_POLICY; dropIndex indexName=IDX_RES_SRV_RES_RES_SRV, tableName=RESOURCE_SERVER_RESOURCE; dropIndex indexName=IDX_RES_SRV_SCOPE_RES_SRV, tableName=RESOURCE_SERVER_SCOPE \N 3.5.4 \N \N 3820445829
authz-3.4.0.CR1-resource-server-pk-change-part3-fixed-nodropindex glavoie@gmail.com META-INF/jpa-changelog-authz-3.4.0.CR1.xml 2022-02-02 16:47:26.702743 48 EXECUTED \N addNotNullConstraint columnName=RESOURCE_SERVER_CLIENT_ID, tableName=RESOURCE_SERVER_POLICY; addNotNullConstraint columnName=RESOURCE_SERVER_CLIENT_ID, tableName=RESOURCE_SERVER_RESOURCE; addNotNullConstraint columnName=RESOURCE_SERVER_CLIENT_ID, ... \N 3.5.4 \N \N 3820445829
3.4.0 keycloak META-INF/jpa-changelog-3.4.0.xml 2022-02-02 16:47:26.734467 50 EXECUTED \N addPrimaryKey constraintName=CONSTRAINT_REALM_DEFAULT_ROLES, tableName=REALM_DEFAULT_ROLES; addPrimaryKey constraintName=CONSTRAINT_COMPOSITE_ROLE, tableName=COMPOSITE_ROLE; addPrimaryKey constraintName=CONSTR_REALM_DEFAULT_GROUPS, tableName=REALM... \N 3.5.4 \N \N 3820445829
3.4.0-KEYCLOAK-5230 hmlnarik@redhat.com META-INF/jpa-changelog-3.4.0.xml 2022-02-02 16:47:26.78037 51 EXECUTED \N createIndex indexName=IDX_FU_ATTRIBUTE, tableName=FED_USER_ATTRIBUTE; createIndex indexName=IDX_FU_CONSENT, tableName=FED_USER_CONSENT; createIndex indexName=IDX_FU_CONSENT_RU, tableName=FED_USER_CONSENT; createIndex indexName=IDX_FU_CREDENTIAL, t... \N 3.5.4 \N \N 3820445829
3.4.1 psilva@redhat.com META-INF/jpa-changelog-3.4.1.xml 2022-02-02 16:47:26.783989 52 EXECUTED \N modifyDataType columnName=VALUE, tableName=CLIENT_ATTRIBUTES \N 3.5.4 \N \N 3820445829
3.4.2 keycloak META-INF/jpa-changelog-3.4.2.xml 2022-02-02 16:47:26.786619 53 EXECUTED \N update tableName=REALM \N 3.5.4 \N \N 3820445829
3.4.2-KEYCLOAK-5172 mkanis@redhat.com META-INF/jpa-changelog-3.4.2.xml 2022-02-02 16:47:26.788788 54 EXECUTED \N update tableName=CLIENT \N 3.5.4 \N \N 3820445829
4.0.0-KEYCLOAK-6335 bburke@redhat.com META-INF/jpa-changelog-4.0.0.xml 2022-02-02 16:47:26.794881 55 EXECUTED \N createTable tableName=CLIENT_AUTH_FLOW_BINDINGS; addPrimaryKey constraintName=C_CLI_FLOW_BIND, tableName=CLIENT_AUTH_FLOW_BINDINGS \N 3.5.4 \N \N 3820445829
4.0.0-CLEANUP-UNUSED-TABLE bburke@redhat.com META-INF/jpa-changelog-4.0.0.xml 2022-02-02 16:47:26.799493 56 EXECUTED \N dropTable tableName=CLIENT_IDENTITY_PROV_MAPPING \N 3.5.4 \N \N 3820445829
4.0.0-KEYCLOAK-6228 bburke@redhat.com META-INF/jpa-changelog-4.0.0.xml 2022-02-02 16:47:26.810686 57 EXECUTED \N dropUniqueConstraint constraintName=UK_JKUWUVD56ONTGSUHOGM8UEWRT, tableName=USER_CONSENT; dropNotNullConstraint columnName=CLIENT_ID, tableName=USER_CONSENT; addColumn tableName=USER_CONSENT; addUniqueConstraint constraintName=UK_JKUWUVD56ONTGSUHO... \N 3.5.4 \N \N 3820445829
4.0.0-KEYCLOAK-5579-fixed mposolda@redhat.com META-INF/jpa-changelog-4.0.0.xml 2022-02-02 16:47:26.861332 58 EXECUTED \N dropForeignKeyConstraint baseTableName=CLIENT_TEMPLATE_ATTRIBUTES, constraintName=FK_CL_TEMPL_ATTR_TEMPL; renameTable newTableName=CLIENT_SCOPE_ATTRIBUTES, oldTableName=CLIENT_TEMPLATE_ATTRIBUTES; renameColumn newColumnName=SCOPE_ID, oldColumnName... \N 3.5.4 \N \N 3820445829
authz-4.0.0.CR1 psilva@redhat.com META-INF/jpa-changelog-authz-4.0.0.CR1.xml 2022-02-02 16:47:26.877018 59 EXECUTED \N createTable tableName=RESOURCE_SERVER_PERM_TICKET; addPrimaryKey constraintName=CONSTRAINT_FAPMT, tableName=RESOURCE_SERVER_PERM_TICKET; addForeignKeyConstraint baseTableName=RESOURCE_SERVER_PERM_TICKET, constraintName=FK_FRSRHO213XCX4WNKOG82SSPMT... \N 3.5.4 \N \N 3820445829
authz-4.0.0.Beta3 psilva@redhat.com META-INF/jpa-changelog-authz-4.0.0.Beta3.xml 2022-02-02 16:47:26.881203 60 EXECUTED \N addColumn tableName=RESOURCE_SERVER_POLICY; addColumn tableName=RESOURCE_SERVER_PERM_TICKET; addForeignKeyConstraint baseTableName=RESOURCE_SERVER_PERM_TICKET, constraintName=FK_FRSRPO2128CX4WNKOG82SSRFY, referencedTableName=RESOURCE_SERVER_POLICY \N 3.5.4 \N \N 3820445829
authz-4.2.0.Final mhajas@redhat.com META-INF/jpa-changelog-authz-4.2.0.Final.xml 2022-02-02 16:47:26.886177 61 EXECUTED \N createTable tableName=RESOURCE_URIS; addForeignKeyConstraint baseTableName=RESOURCE_URIS, constraintName=FK_RESOURCE_SERVER_URIS, referencedTableName=RESOURCE_SERVER_RESOURCE; customChange; dropColumn columnName=URI, tableName=RESOURCE_SERVER_RESO... \N 3.5.4 \N \N 3820445829
authz-4.2.0.Final-KEYCLOAK-9944 hmlnarik@redhat.com META-INF/jpa-changelog-authz-4.2.0.Final.xml 2022-02-02 16:47:26.890482 62 EXECUTED \N addPrimaryKey constraintName=CONSTRAINT_RESOUR_URIS_PK, tableName=RESOURCE_URIS \N 3.5.4 \N \N 3820445829
4.2.0-KEYCLOAK-6313 wadahiro@gmail.com META-INF/jpa-changelog-4.2.0.xml 2022-02-02 16:47:26.893518 63 EXECUTED \N addColumn tableName=REQUIRED_ACTION_PROVIDER \N 3.5.4 \N \N 3820445829
4.3.0-KEYCLOAK-7984 wadahiro@gmail.com META-INF/jpa-changelog-4.3.0.xml 2022-02-02 16:47:26.895621 64 EXECUTED \N update tableName=REQUIRED_ACTION_PROVIDER \N 3.5.4 \N \N 3820445829
4.6.0-KEYCLOAK-7950 psilva@redhat.com META-INF/jpa-changelog-4.6.0.xml 2022-02-02 16:47:26.89756 65 EXECUTED \N update tableName=RESOURCE_SERVER_RESOURCE \N 3.5.4 \N \N 3820445829
4.6.0-KEYCLOAK-8377 keycloak META-INF/jpa-changelog-4.6.0.xml 2022-02-02 16:47:26.908059 66 EXECUTED \N createTable tableName=ROLE_ATTRIBUTE; addPrimaryKey constraintName=CONSTRAINT_ROLE_ATTRIBUTE_PK, tableName=ROLE_ATTRIBUTE; addForeignKeyConstraint baseTableName=ROLE_ATTRIBUTE, constraintName=FK_ROLE_ATTRIBUTE_ID, referencedTableName=KEYCLOAK_ROLE... \N 3.5.4 \N \N 3820445829
4.6.0-KEYCLOAK-8555 gideonray@gmail.com META-INF/jpa-changelog-4.6.0.xml 2022-02-02 16:47:26.912693 67 EXECUTED \N createIndex indexName=IDX_COMPONENT_PROVIDER_TYPE, tableName=COMPONENT \N 3.5.4 \N \N 3820445829
4.7.0-KEYCLOAK-1267 sguilhen@redhat.com META-INF/jpa-changelog-4.7.0.xml 2022-02-02 16:47:26.915771 68 EXECUTED \N addColumn tableName=REALM \N 3.5.4 \N \N 3820445829
4.7.0-KEYCLOAK-7275 keycloak META-INF/jpa-changelog-4.7.0.xml 2022-02-02 16:47:26.924465 69 EXECUTED \N renameColumn newColumnName=CREATED_ON, oldColumnName=LAST_SESSION_REFRESH, tableName=OFFLINE_USER_SESSION; addNotNullConstraint columnName=CREATED_ON, tableName=OFFLINE_USER_SESSION; addColumn tableName=OFFLINE_USER_SESSION; customChange; createIn... \N 3.5.4 \N \N 3820445829
authz-7.0.0-KEYCLOAK-10443 psilva@redhat.com META-INF/jpa-changelog-authz-7.0.0.xml 2022-02-02 16:47:26.93061 71 EXECUTED \N addColumn tableName=RESOURCE_SERVER \N 3.5.4 \N \N 3820445829
8.0.0-adding-credential-columns keycloak META-INF/jpa-changelog-8.0.0.xml 2022-02-02 16:47:26.933771 72 EXECUTED \N addColumn tableName=CREDENTIAL; addColumn tableName=FED_USER_CREDENTIAL \N 3.5.4 \N \N 3820445829
1.6.1 mposolda@redhat.com META-INF/jpa-changelog-1.6.1.xml 2022-02-02 16:47:26.306641 17 EXECUTED 9:d41d8cd98f00b204e9800998ecf8427e empty \N 3.5.4 \N \N 3820445829
authz-2.5.1 psilva@redhat.com META-INF/jpa-changelog-authz-2.5.1.xml 2022-02-02 16:47:26.484459 28 EXECUTED 9:44bae577f551b3738740281eceb4ea70 update tableName=RESOURCE_SERVER_POLICY \N 3.5.4 \N \N 3820445829
8.0.0-updating-credential-data-not-oracle keycloak META-INF/jpa-changelog-8.0.0.xml 2022-02-02 16:47:26.937673 73 EXECUTED \N update tableName=CREDENTIAL; update tableName=CREDENTIAL; update tableName=CREDENTIAL; update tableName=FED_USER_CREDENTIAL; update tableName=FED_USER_CREDENTIAL; update tableName=FED_USER_CREDENTIAL \N 3.5.4 \N \N 3820445829
8.0.0-updating-credential-data-oracle keycloak META-INF/jpa-changelog-8.0.0.xml 2022-02-02 16:47:26.939218 74 MARK_RAN \N update tableName=CREDENTIAL; update tableName=CREDENTIAL; update tableName=CREDENTIAL; update tableName=FED_USER_CREDENTIAL; update tableName=FED_USER_CREDENTIAL; update tableName=FED_USER_CREDENTIAL \N 3.5.4 \N \N 3820445829
8.0.0-credential-cleanup-fixed keycloak META-INF/jpa-changelog-8.0.0.xml 2022-02-02 16:47:26.945819 75 EXECUTED \N dropDefaultValue columnName=COUNTER, tableName=CREDENTIAL; dropDefaultValue columnName=DIGITS, tableName=CREDENTIAL; dropDefaultValue columnName=PERIOD, tableName=CREDENTIAL; dropDefaultValue columnName=ALGORITHM, tableName=CREDENTIAL; dropColumn ... \N 3.5.4 \N \N 3820445829
8.0.0-resource-tag-support keycloak META-INF/jpa-changelog-8.0.0.xml 2022-02-02 16:47:26.950255 76 EXECUTED \N addColumn tableName=MIGRATION_MODEL; createIndex indexName=IDX_UPDATE_TIME, tableName=MIGRATION_MODEL \N 3.5.4 \N \N 3820445829
9.0.0-always-display-client keycloak META-INF/jpa-changelog-9.0.0.xml 2022-02-02 16:47:26.955505 77 EXECUTED \N addColumn tableName=CLIENT \N 3.5.4 \N \N 3820445829
9.0.0-drop-constraints-for-column-increase keycloak META-INF/jpa-changelog-9.0.0.xml 2022-02-02 16:47:26.957216 78 MARK_RAN \N dropUniqueConstraint constraintName=UK_FRSR6T700S9V50BU18WS5PMT, tableName=RESOURCE_SERVER_PERM_TICKET; dropUniqueConstraint constraintName=UK_FRSR6T700S9V50BU18WS5HA6, tableName=RESOURCE_SERVER_RESOURCE; dropPrimaryKey constraintName=CONSTRAINT_O... \N 3.5.4 \N \N 3820445829
9.0.0-increase-column-size-federated-fk keycloak META-INF/jpa-changelog-9.0.0.xml 2022-02-02 16:47:26.966746 79 EXECUTED \N modifyDataType columnName=CLIENT_ID, tableName=FED_USER_CONSENT; modifyDataType columnName=CLIENT_REALM_CONSTRAINT, tableName=KEYCLOAK_ROLE; modifyDataType columnName=OWNER, tableName=RESOURCE_SERVER_POLICY; modifyDataType columnName=CLIENT_ID, ta... \N 3.5.4 \N \N 3820445829
9.0.0-recreate-constraints-after-column-increase keycloak META-INF/jpa-changelog-9.0.0.xml 2022-02-02 16:47:26.969643 80 MARK_RAN \N addNotNullConstraint columnName=CLIENT_ID, tableName=OFFLINE_CLIENT_SESSION; addNotNullConstraint columnName=OWNER, tableName=RESOURCE_SERVER_PERM_TICKET; addNotNullConstraint columnName=REQUESTER, tableName=RESOURCE_SERVER_PERM_TICKET; addNotNull... \N 3.5.4 \N \N 3820445829
9.0.1-add-index-to-client.client_id keycloak META-INF/jpa-changelog-9.0.1.xml 2022-02-02 16:47:26.975764 81 EXECUTED \N createIndex indexName=IDX_CLIENT_ID, tableName=CLIENT \N 3.5.4 \N \N 3820445829
9.0.1-KEYCLOAK-12579-drop-constraints keycloak META-INF/jpa-changelog-9.0.1.xml 2022-02-02 16:47:26.977227 82 MARK_RAN \N dropUniqueConstraint constraintName=SIBLING_NAMES, tableName=KEYCLOAK_GROUP \N 3.5.4 \N \N 3820445829
9.0.1-KEYCLOAK-12579-add-not-null-constraint keycloak META-INF/jpa-changelog-9.0.1.xml 2022-02-02 16:47:26.980058 83 EXECUTED \N addNotNullConstraint columnName=PARENT_GROUP, tableName=KEYCLOAK_GROUP \N 3.5.4 \N \N 3820445829
9.0.1-add-index-to-events keycloak META-INF/jpa-changelog-9.0.1.xml 2022-02-02 16:47:26.985465 85 EXECUTED \N createIndex indexName=IDX_EVENT_TIME, tableName=EVENT_ENTITY \N 3.5.4 \N \N 3820445829
map-remove-ri keycloak META-INF/jpa-changelog-11.0.0.xml 2022-02-02 16:47:26.98869 86 EXECUTED \N dropForeignKeyConstraint baseTableName=REALM, constraintName=FK_TRAF444KK6QRKMS7N56AIWQ5Y; dropForeignKeyConstraint baseTableName=KEYCLOAK_ROLE, constraintName=FK_KJHO5LE2C0RAL09FL8CM9WFW9 \N 3.5.4 \N \N 3820445829
map-remove-ri keycloak META-INF/jpa-changelog-12.0.0.xml 2022-02-02 16:47:26.992854 87 EXECUTED \N dropForeignKeyConstraint baseTableName=REALM_DEFAULT_GROUPS, constraintName=FK_DEF_GROUPS_GROUP; dropForeignKeyConstraint baseTableName=REALM_DEFAULT_ROLES, constraintName=FK_H4WPD7W4HSOOLNI3H0SW7BTJE; dropForeignKeyConstraint baseTableName=CLIENT... \N 3.5.4 \N \N 3820445829
12.1.0-add-realm-localization-table keycloak META-INF/jpa-changelog-12.0.0.xml 2022-02-02 16:47:26.999694 88 EXECUTED \N createTable tableName=REALM_LOCALIZATIONS; addPrimaryKey tableName=REALM_LOCALIZATIONS \N 3.5.4 \N \N 3820445829
8.0.0-updating-credential-data-not-oracle-fixed keycloak META-INF/jpa-changelog-8.0.0.xml 2023-01-09 14:34:23.080082 89 MARK_RAN 8:83f7a671792ca98b3cbd3a1a34862d3d update tableName=CREDENTIAL; update tableName=CREDENTIAL; update tableName=CREDENTIAL; update tableName=FED_USER_CREDENTIAL; update tableName=FED_USER_CREDENTIAL; update tableName=FED_USER_CREDENTIAL \N 4.8.0 \N \N 3274862955
8.0.0-updating-credential-data-oracle-fixed keycloak META-INF/jpa-changelog-8.0.0.xml 2023-01-09 14:34:23.099857 90 MARK_RAN 8:f58ad148698cf30707a6efbdf8061aa7 update tableName=CREDENTIAL; update tableName=CREDENTIAL; update tableName=CREDENTIAL; update tableName=FED_USER_CREDENTIAL; update tableName=FED_USER_CREDENTIAL; update tableName=FED_USER_CREDENTIAL \N 4.8.0 \N \N 3274862955
default-roles keycloak META-INF/jpa-changelog-13.0.0.xml 2023-01-09 14:34:23.144776 91 EXECUTED 8:72d03345fda8e2f17093d08801947773 addColumn tableName=REALM; customChange \N 4.8.0 \N \N 3274862955
default-roles-cleanup keycloak META-INF/jpa-changelog-13.0.0.xml 2023-01-09 14:34:23.155298 92 EXECUTED 8:61c9233951bd96ffecd9ba75f7d978a4 dropTable tableName=REALM_DEFAULT_ROLES; dropTable tableName=CLIENT_DEFAULT_ROLES \N 4.8.0 \N \N 3274862955
13.0.0-KEYCLOAK-16844 keycloak META-INF/jpa-changelog-13.0.0.xml 2023-01-09 14:34:23.162911 93 EXECUTED 8:ea82e6ad945cec250af6372767b25525 createIndex indexName=IDX_OFFLINE_USS_PRELOAD, tableName=OFFLINE_USER_SESSION \N 4.8.0 \N \N 3274862955
map-remove-ri-13.0.0 keycloak META-INF/jpa-changelog-13.0.0.xml 2023-01-09 14:34:23.17617 94 EXECUTED 8:d3f4a33f41d960ddacd7e2ef30d126b3 dropForeignKeyConstraint baseTableName=DEFAULT_CLIENT_SCOPE, constraintName=FK_R_DEF_CLI_SCOPE_SCOPE; dropForeignKeyConstraint baseTableName=CLIENT_SCOPE_CLIENT, constraintName=FK_C_CLI_SCOPE_SCOPE; dropForeignKeyConstraint baseTableName=CLIENT_SC... \N 4.8.0 \N \N 3274862955
13.0.0-KEYCLOAK-17992-drop-constraints keycloak META-INF/jpa-changelog-13.0.0.xml 2023-01-09 14:34:23.1803 95 MARK_RAN 8:1284a27fbd049d65831cb6fc07c8a783 dropPrimaryKey constraintName=C_CLI_SCOPE_BIND, tableName=CLIENT_SCOPE_CLIENT; dropIndex indexName=IDX_CLSCOPE_CL, tableName=CLIENT_SCOPE_CLIENT; dropIndex indexName=IDX_CL_CLSCOPE, tableName=CLIENT_SCOPE_CLIENT \N 4.8.0 \N \N 3274862955
13.0.0-increase-column-size-federated keycloak META-INF/jpa-changelog-13.0.0.xml 2023-01-09 14:34:23.190613 96 EXECUTED 8:9d11b619db2ae27c25853b8a37cd0dea modifyDataType columnName=CLIENT_ID, tableName=CLIENT_SCOPE_CLIENT; modifyDataType columnName=SCOPE_ID, tableName=CLIENT_SCOPE_CLIENT \N 4.8.0 \N \N 3274862955
13.0.0-KEYCLOAK-17992-recreate-constraints keycloak META-INF/jpa-changelog-13.0.0.xml 2023-01-09 14:34:23.193934 97 MARK_RAN 8:3002bb3997451bb9e8bac5c5cd8d6327 addNotNullConstraint columnName=CLIENT_ID, tableName=CLIENT_SCOPE_CLIENT; addNotNullConstraint columnName=SCOPE_ID, tableName=CLIENT_SCOPE_CLIENT; addPrimaryKey constraintName=C_CLI_SCOPE_BIND, tableName=CLIENT_SCOPE_CLIENT; createIndex indexName=... \N 4.8.0 \N \N 3274862955
json-string-accomodation-fixed keycloak META-INF/jpa-changelog-13.0.0.xml 2023-01-09 14:34:23.202965 98 EXECUTED 8:dfbee0d6237a23ef4ccbb7a4e063c163 addColumn tableName=REALM_ATTRIBUTE; update tableName=REALM_ATTRIBUTE; dropColumn columnName=VALUE, tableName=REALM_ATTRIBUTE; renameColumn newColumnName=VALUE, oldColumnName=VALUE_NEW, tableName=REALM_ATTRIBUTE \N 4.8.0 \N \N 3274862955
14.0.0-KEYCLOAK-11019 keycloak META-INF/jpa-changelog-14.0.0.xml 2023-01-09 14:34:23.212244 99 EXECUTED 8:75f3e372df18d38c62734eebb986b960 createIndex indexName=IDX_OFFLINE_CSS_PRELOAD, tableName=OFFLINE_CLIENT_SESSION; createIndex indexName=IDX_OFFLINE_USS_BY_USER, tableName=OFFLINE_USER_SESSION; createIndex indexName=IDX_OFFLINE_USS_BY_USERSESS, tableName=OFFLINE_USER_SESSION \N 4.8.0 \N \N 3274862955
14.0.0-KEYCLOAK-18286 keycloak META-INF/jpa-changelog-14.0.0.xml 2023-01-09 14:34:23.2164 100 MARK_RAN 8:7fee73eddf84a6035691512c85637eef createIndex indexName=IDX_CLIENT_ATT_BY_NAME_VALUE, tableName=CLIENT_ATTRIBUTES \N 4.8.0 \N \N 3274862955
14.0.0-KEYCLOAK-18286-revert keycloak META-INF/jpa-changelog-14.0.0.xml 2023-01-09 14:34:23.227895 101 MARK_RAN 8:7a11134ab12820f999fbf3bb13c3adc8 dropIndex indexName=IDX_CLIENT_ATT_BY_NAME_VALUE, tableName=CLIENT_ATTRIBUTES \N 4.8.0 \N \N 3274862955
14.0.0-KEYCLOAK-18286-supported-dbs keycloak META-INF/jpa-changelog-14.0.0.xml 2023-01-09 14:34:23.235491 102 EXECUTED 8:c0f6eaac1f3be773ffe54cb5b8482b70 createIndex indexName=IDX_CLIENT_ATT_BY_NAME_VALUE, tableName=CLIENT_ATTRIBUTES \N 4.8.0 \N \N 3274862955
14.0.0-KEYCLOAK-18286-unsupported-dbs keycloak META-INF/jpa-changelog-14.0.0.xml 2023-01-09 14:34:23.238498 103 MARK_RAN 8:18186f0008b86e0f0f49b0c4d0e842ac createIndex indexName=IDX_CLIENT_ATT_BY_NAME_VALUE, tableName=CLIENT_ATTRIBUTES \N 4.8.0 \N \N 3274862955
KEYCLOAK-17267-add-index-to-user-attributes keycloak META-INF/jpa-changelog-14.0.0.xml 2023-01-09 14:34:23.24435 104 EXECUTED 8:09c2780bcb23b310a7019d217dc7b433 createIndex indexName=IDX_USER_ATTRIBUTE_NAME, tableName=USER_ATTRIBUTE \N 4.8.0 \N \N 3274862955
KEYCLOAK-18146-add-saml-art-binding-identifier keycloak META-INF/jpa-changelog-14.0.0.xml 2023-01-09 14:34:23.250444 105 EXECUTED 8:276a44955eab693c970a42880197fff2 customChange \N 4.8.0 \N \N 3274862955
15.0.0-KEYCLOAK-18467 keycloak META-INF/jpa-changelog-15.0.0.xml 2023-01-09 14:34:23.261701 106 EXECUTED 8:ba8ee3b694d043f2bfc1a1079d0760d7 addColumn tableName=REALM_LOCALIZATIONS; update tableName=REALM_LOCALIZATIONS; dropColumn columnName=TEXTS, tableName=REALM_LOCALIZATIONS; renameColumn newColumnName=TEXTS, oldColumnName=TEXTS_NEW, tableName=REALM_LOCALIZATIONS; addNotNullConstrai... \N 4.8.0 \N \N 3274862955
17.0.0-9562 keycloak META-INF/jpa-changelog-17.0.0.xml 2023-01-09 14:34:23.269577 107 EXECUTED 8:5e06b1d75f5d17685485e610c2851b17 createIndex indexName=IDX_USER_SERVICE_ACCOUNT, tableName=USER_ENTITY \N 4.8.0 \N \N 3274862955
18.0.0-10625-IDX_ADMIN_EVENT_TIME keycloak META-INF/jpa-changelog-18.0.0.xml 2023-01-09 14:34:23.276738 108 EXECUTED 8:4b80546c1dc550ac552ee7b24a4ab7c0 createIndex indexName=IDX_ADMIN_EVENT_TIME, tableName=ADMIN_EVENT_ENTITY \N 4.8.0 \N \N 3274862955
19.0.0-10135 keycloak META-INF/jpa-changelog-19.0.0.xml 2023-01-09 14:34:23.297485 109 EXECUTED 8:af510cd1bb2ab6339c45372f3e491696 customChange \N 4.8.0 \N \N 3274862955
20.0.0-12964-supported-dbs keycloak META-INF/jpa-changelog-20.0.0.xml 2023-01-09 14:34:23.305463 110 EXECUTED 8:05c99fc610845ef66ee812b7921af0ef createIndex indexName=IDX_GROUP_ATT_BY_NAME_VALUE, tableName=GROUP_ATTRIBUTE \N 4.8.0 \N \N 3274862955
20.0.0-12964-unsupported-dbs keycloak META-INF/jpa-changelog-20.0.0.xml 2023-01-09 14:34:23.309005 111 MARK_RAN 8:314e803baf2f1ec315b3464e398b8247 createIndex indexName=IDX_GROUP_ATT_BY_NAME_VALUE, tableName=GROUP_ATTRIBUTE \N 4.8.0 \N \N 3274862955
client-attributes-string-accomodation-fixed keycloak META-INF/jpa-changelog-20.0.0.xml 2023-01-09 14:34:23.318788 112 EXECUTED 8:56e4677e7e12556f70b604c573840100 addColumn tableName=CLIENT_ATTRIBUTES; update tableName=CLIENT_ATTRIBUTES; dropColumn columnName=VALUE, tableName=CLIENT_ATTRIBUTES; renameColumn newColumnName=VALUE, oldColumnName=VALUE_NEW, tableName=CLIENT_ATTRIBUTES \N 4.8.0 \N \N 3274862955
3.4.2 keycloak META-INF/jpa-changelog-3.4.2.xml 2022-02-02 16:47:26.786619 53 EXECUTED 9:8f23e334dbc59f82e0a328373ca6ced0 update tableName=REALM \N 3.5.4 \N \N 3820445829
1.0.0.Final-KEYCLOAK-5461 sthorger@redhat.com META-INF/jpa-changelog-1.0.0.Final.xml 2022-02-02 16:47:26.017844 1 EXECUTED 9:6f1016664e21e16d26517a4418f5e3df createTable tableName=APPLICATION_DEFAULT_ROLES; createTable tableName=CLIENT; createTable tableName=CLIENT_SESSION; createTable tableName=CLIENT_SESSION_ROLE; createTable tableName=COMPOSITE_ROLE; createTable tableName=CREDENTIAL; createTable tab... \N 3.5.4 \N \N 3820445829
1.0.0.Final-KEYCLOAK-5461 sthorger@redhat.com META-INF/db2-jpa-changelog-1.0.0.Final.xml 2022-02-02 16:47:26.03122 2 MARK_RAN 9:828775b1596a07d1200ba1d49e5e3941 createTable tableName=APPLICATION_DEFAULT_ROLES; createTable tableName=CLIENT; createTable tableName=CLIENT_SESSION; createTable tableName=CLIENT_SESSION_ROLE; createTable tableName=COMPOSITE_ROLE; createTable tableName=CREDENTIAL; createTable tab... \N 3.5.4 \N \N 3820445829
1.1.0.Beta1 sthorger@redhat.com META-INF/jpa-changelog-1.1.0.Beta1.xml 2022-02-02 16:47:26.06085 3 EXECUTED 9:5f090e44a7d595883c1fb61f4b41fd38 delete tableName=CLIENT_SESSION_ROLE; delete tableName=CLIENT_SESSION; delete tableName=USER_SESSION; createTable tableName=CLIENT_ATTRIBUTES; createTable tableName=CLIENT_SESSION_NOTE; createTable tableName=APP_NODE_REGISTRATIONS; addColumn table... \N 3.5.4 \N \N 3820445829
1.1.0.Final sthorger@redhat.com META-INF/jpa-changelog-1.1.0.Final.xml 2022-02-02 16:47:26.065284 4 EXECUTED 9:c07e577387a3d2c04d1adc9aaad8730e renameColumn newColumnName=EVENT_TIME, oldColumnName=TIME, tableName=EVENT_ENTITY \N 3.5.4 \N \N 3820445829
1.2.0.Beta1 psilva@redhat.com META-INF/jpa-changelog-1.2.0.Beta1.xml 2022-02-02 16:47:26.130908 5 EXECUTED 9:b68ce996c655922dbcd2fe6b6ae72686 delete tableName=CLIENT_SESSION_ROLE; delete tableName=CLIENT_SESSION_NOTE; delete tableName=CLIENT_SESSION; delete tableName=USER_SESSION; createTable tableName=PROTOCOL_MAPPER; createTable tableName=PROTOCOL_MAPPER_CONFIG; createTable tableName=... \N 3.5.4 \N \N 3820445829
1.2.0.Beta1 psilva@redhat.com META-INF/db2-jpa-changelog-1.2.0.Beta1.xml 2022-02-02 16:47:26.133863 6 MARK_RAN 9:543b5c9989f024fe35c6f6c5a97de88e delete tableName=CLIENT_SESSION_ROLE; delete tableName=CLIENT_SESSION_NOTE; delete tableName=CLIENT_SESSION; delete tableName=USER_SESSION; createTable tableName=PROTOCOL_MAPPER; createTable tableName=PROTOCOL_MAPPER_CONFIG; createTable tableName=... \N 3.5.4 \N \N 3820445829
1.2.0.RC1 bburke@redhat.com META-INF/jpa-changelog-1.2.0.CR1.xml 2022-02-02 16:47:26.183318 7 EXECUTED 9:765afebbe21cf5bbca048e632df38336 delete tableName=CLIENT_SESSION_ROLE; delete tableName=CLIENT_SESSION_NOTE; delete tableName=CLIENT_SESSION; delete tableName=USER_SESSION_NOTE; delete tableName=USER_SESSION; createTable tableName=MIGRATION_MODEL; createTable tableName=IDENTITY_P... \N 3.5.4 \N \N 3820445829
1.2.0.RC1 bburke@redhat.com META-INF/db2-jpa-changelog-1.2.0.CR1.xml 2022-02-02 16:47:26.186858 8 MARK_RAN 9:db4a145ba11a6fdaefb397f6dbf829a1 delete tableName=CLIENT_SESSION_ROLE; delete tableName=CLIENT_SESSION_NOTE; delete tableName=CLIENT_SESSION; delete tableName=USER_SESSION_NOTE; delete tableName=USER_SESSION; createTable tableName=MIGRATION_MODEL; createTable tableName=IDENTITY_P... \N 3.5.4 \N \N 3820445829
1.2.0.Final keycloak META-INF/jpa-changelog-1.2.0.Final.xml 2022-02-02 16:47:26.19172 9 EXECUTED 9:9d05c7be10cdb873f8bcb41bc3a8ab23 update tableName=CLIENT; update tableName=CLIENT; update tableName=CLIENT \N 3.5.4 \N \N 3820445829
1.3.0 bburke@redhat.com META-INF/jpa-changelog-1.3.0.xml 2022-02-02 16:47:26.242162 10 EXECUTED 9:18593702353128d53111f9b1ff0b82b8 delete tableName=CLIENT_SESSION_ROLE; delete tableName=CLIENT_SESSION_PROT_MAPPER; delete tableName=CLIENT_SESSION_NOTE; delete tableName=CLIENT_SESSION; delete tableName=USER_SESSION_NOTE; delete tableName=USER_SESSION; createTable tableName=ADMI... \N 3.5.4 \N \N 3820445829
1.4.0 bburke@redhat.com META-INF/jpa-changelog-1.4.0.xml 2022-02-02 16:47:26.275929 11 EXECUTED 9:6122efe5f090e41a85c0f1c9e52cbb62 delete tableName=CLIENT_SESSION_AUTH_STATUS; delete tableName=CLIENT_SESSION_ROLE; delete tableName=CLIENT_SESSION_PROT_MAPPER; delete tableName=CLIENT_SESSION_NOTE; delete tableName=CLIENT_SESSION; delete tableName=USER_SESSION_NOTE; delete table... \N 3.5.4 \N \N 3820445829
1.4.0 bburke@redhat.com META-INF/db2-jpa-changelog-1.4.0.xml 2022-02-02 16:47:26.278548 12 MARK_RAN 9:e1ff28bf7568451453f844c5d54bb0b5 delete tableName=CLIENT_SESSION_AUTH_STATUS; delete tableName=CLIENT_SESSION_ROLE; delete tableName=CLIENT_SESSION_PROT_MAPPER; delete tableName=CLIENT_SESSION_NOTE; delete tableName=CLIENT_SESSION; delete tableName=USER_SESSION_NOTE; delete table... \N 3.5.4 \N \N 3820445829
1.5.0 bburke@redhat.com META-INF/jpa-changelog-1.5.0.xml 2022-02-02 16:47:26.287616 13 EXECUTED 9:7af32cd8957fbc069f796b61217483fd delete tableName=CLIENT_SESSION_AUTH_STATUS; delete tableName=CLIENT_SESSION_ROLE; delete tableName=CLIENT_SESSION_PROT_MAPPER; delete tableName=CLIENT_SESSION_NOTE; delete tableName=CLIENT_SESSION; delete tableName=USER_SESSION_NOTE; delete table... \N 3.5.4 \N \N 3820445829
1.6.1_from15 mposolda@redhat.com META-INF/jpa-changelog-1.6.1.xml 2022-02-02 16:47:26.299798 14 EXECUTED 9:6005e15e84714cd83226bf7879f54190 addColumn tableName=REALM; addColumn tableName=KEYCLOAK_ROLE; addColumn tableName=CLIENT; createTable tableName=OFFLINE_USER_SESSION; createTable tableName=OFFLINE_CLIENT_SESSION; addPrimaryKey constraintName=CONSTRAINT_OFFL_US_SES_PK2, tableName=... \N 3.5.4 \N \N 3820445829
1.6.1_from16-pre mposolda@redhat.com META-INF/jpa-changelog-1.6.1.xml 2022-02-02 16:47:26.302088 15 MARK_RAN 9:bf656f5a2b055d07f314431cae76f06c delete tableName=OFFLINE_CLIENT_SESSION; delete tableName=OFFLINE_USER_SESSION \N 3.5.4 \N \N 3820445829
1.6.1_from16 mposolda@redhat.com META-INF/jpa-changelog-1.6.1.xml 2022-02-02 16:47:26.303889 16 MARK_RAN 9:f8dadc9284440469dcf71e25ca6ab99b dropPrimaryKey constraintName=CONSTRAINT_OFFLINE_US_SES_PK, tableName=OFFLINE_USER_SESSION; dropPrimaryKey constraintName=CONSTRAINT_OFFLINE_CL_SES_PK, tableName=OFFLINE_CLIENT_SESSION; addColumn tableName=OFFLINE_USER_SESSION; update tableName=OF... \N 3.5.4 \N \N 3820445829
1.7.0 bburke@redhat.com META-INF/jpa-changelog-1.7.0.xml 2022-02-02 16:47:26.338791 18 EXECUTED 9:3368ff0be4c2855ee2dd9ca813b38d8e createTable tableName=KEYCLOAK_GROUP; createTable tableName=GROUP_ROLE_MAPPING; createTable tableName=GROUP_ATTRIBUTE; createTable tableName=USER_GROUP_MEMBERSHIP; createTable tableName=REALM_DEFAULT_GROUPS; addColumn tableName=IDENTITY_PROVIDER; ... \N 3.5.4 \N \N 3820445829
1.8.0 mposolda@redhat.com META-INF/jpa-changelog-1.8.0.xml 2022-02-02 16:47:26.381463 19 EXECUTED 9:8ac2fb5dd030b24c0570a763ed75ed20 addColumn tableName=IDENTITY_PROVIDER; createTable tableName=CLIENT_TEMPLATE; createTable tableName=CLIENT_TEMPLATE_ATTRIBUTES; createTable tableName=TEMPLATE_SCOPE_MAPPING; dropNotNullConstraint columnName=CLIENT_ID, tableName=PROTOCOL_MAPPER; ad... \N 3.5.4 \N \N 3820445829
1.8.0-2 keycloak META-INF/jpa-changelog-1.8.0.xml 2022-02-02 16:47:26.390165 20 EXECUTED 9:f91ddca9b19743db60e3057679810e6c dropDefaultValue columnName=ALGORITHM, tableName=CREDENTIAL; update tableName=CREDENTIAL \N 3.5.4 \N \N 3820445829
1.8.0 mposolda@redhat.com META-INF/db2-jpa-changelog-1.8.0.xml 2022-02-02 16:47:26.392862 21 MARK_RAN 9:831e82914316dc8a57dc09d755f23c51 addColumn tableName=IDENTITY_PROVIDER; createTable tableName=CLIENT_TEMPLATE; createTable tableName=CLIENT_TEMPLATE_ATTRIBUTES; createTable tableName=TEMPLATE_SCOPE_MAPPING; dropNotNullConstraint columnName=CLIENT_ID, tableName=PROTOCOL_MAPPER; ad... \N 3.5.4 \N \N 3820445829
1.8.0-2 keycloak META-INF/db2-jpa-changelog-1.8.0.xml 2022-02-02 16:47:26.395652 22 MARK_RAN 9:f91ddca9b19743db60e3057679810e6c dropDefaultValue columnName=ALGORITHM, tableName=CREDENTIAL; update tableName=CREDENTIAL \N 3.5.4 \N \N 3820445829
1.9.0 mposolda@redhat.com META-INF/jpa-changelog-1.9.0.xml 2022-02-02 16:47:26.40969 23 EXECUTED 9:bc3d0f9e823a69dc21e23e94c7a94bb1 update tableName=REALM; update tableName=REALM; update tableName=REALM; update tableName=REALM; update tableName=CREDENTIAL; update tableName=CREDENTIAL; update tableName=CREDENTIAL; update tableName=REALM; update tableName=REALM; customChange; dr... \N 3.5.4 \N \N 3820445829
1.9.1 keycloak META-INF/jpa-changelog-1.9.1.xml 2022-02-02 16:47:26.414344 24 EXECUTED 9:c9999da42f543575ab790e76439a2679 modifyDataType columnName=PRIVATE_KEY, tableName=REALM; modifyDataType columnName=PUBLIC_KEY, tableName=REALM; modifyDataType columnName=CERTIFICATE, tableName=REALM \N 3.5.4 \N \N 3820445829
1.9.1 keycloak META-INF/db2-jpa-changelog-1.9.1.xml 2022-02-02 16:47:26.416193 25 MARK_RAN 9:0d6c65c6f58732d81569e77b10ba301d modifyDataType columnName=PRIVATE_KEY, tableName=REALM; modifyDataType columnName=CERTIFICATE, tableName=REALM \N 3.5.4 \N \N 3820445829
1.9.2 keycloak META-INF/jpa-changelog-1.9.2.xml 2022-02-02 16:47:26.437367 26 EXECUTED 9:fc576660fc016ae53d2d4778d84d86d0 createIndex indexName=IDX_USER_EMAIL, tableName=USER_ENTITY; createIndex indexName=IDX_USER_ROLE_MAPPING, tableName=USER_ROLE_MAPPING; createIndex indexName=IDX_USER_GROUP_MAPPING, tableName=USER_GROUP_MEMBERSHIP; createIndex indexName=IDX_USER_CO... \N 3.5.4 \N \N 3820445829
authz-2.0.0 psilva@redhat.com META-INF/jpa-changelog-authz-2.0.0.xml 2022-02-02 16:47:26.481647 27 EXECUTED 9:43ed6b0da89ff77206289e87eaa9c024 createTable tableName=RESOURCE_SERVER; addPrimaryKey constraintName=CONSTRAINT_FARS, tableName=RESOURCE_SERVER; addUniqueConstraint constraintName=UK_AU8TT6T700S9V50BU18WS5HA6, tableName=RESOURCE_SERVER; createTable tableName=RESOURCE_SERVER_RESOU... \N 3.5.4 \N \N 3820445829
2.1.0-KEYCLOAK-5461 bburke@redhat.com META-INF/jpa-changelog-2.1.0.xml 2022-02-02 16:47:26.523006 29 EXECUTED 9:bd88e1f833df0420b01e114533aee5e8 createTable tableName=BROKER_LINK; createTable tableName=FED_USER_ATTRIBUTE; createTable tableName=FED_USER_CONSENT; createTable tableName=FED_USER_CONSENT_ROLE; createTable tableName=FED_USER_CONSENT_PROT_MAPPER; createTable tableName=FED_USER_CR... \N 3.5.4 \N \N 3820445829
2.2.0 bburke@redhat.com META-INF/jpa-changelog-2.2.0.xml 2022-02-02 16:47:26.532066 30 EXECUTED 9:a7022af5267f019d020edfe316ef4371 addColumn tableName=ADMIN_EVENT_ENTITY; createTable tableName=CREDENTIAL_ATTRIBUTE; createTable tableName=FED_CREDENTIAL_ATTRIBUTE; modifyDataType columnName=VALUE, tableName=CREDENTIAL; addForeignKeyConstraint baseTableName=FED_CREDENTIAL_ATTRIBU... \N 3.5.4 \N \N 3820445829
2.3.0 bburke@redhat.com META-INF/jpa-changelog-2.3.0.xml 2022-02-02 16:47:26.541837 31 EXECUTED 9:fc155c394040654d6a79227e56f5e25a createTable tableName=FEDERATED_USER; addPrimaryKey constraintName=CONSTR_FEDERATED_USER, tableName=FEDERATED_USER; dropDefaultValue columnName=TOTP, tableName=USER_ENTITY; dropColumn columnName=TOTP, tableName=USER_ENTITY; addColumn tableName=IDE... \N 3.5.4 \N \N 3820445829
2.4.0 bburke@redhat.com META-INF/jpa-changelog-2.4.0.xml 2022-02-02 16:47:26.545809 32 EXECUTED 9:eac4ffb2a14795e5dc7b426063e54d88 customChange \N 3.5.4 \N \N 3820445829
2.5.0 bburke@redhat.com META-INF/jpa-changelog-2.5.0.xml 2022-02-02 16:47:26.549823 33 EXECUTED 9:54937c05672568c4c64fc9524c1e9462 customChange; modifyDataType columnName=USER_ID, tableName=OFFLINE_USER_SESSION \N 3.5.4 \N \N 3820445829
2.5.0-unicode-oracle hmlnarik@redhat.com META-INF/jpa-changelog-2.5.0.xml 2022-02-02 16:47:26.55176 34 MARK_RAN 9:3a32bace77c84d7678d035a7f5a8084e modifyDataType columnName=DESCRIPTION, tableName=AUTHENTICATION_FLOW; modifyDataType columnName=DESCRIPTION, tableName=CLIENT_TEMPLATE; modifyDataType columnName=DESCRIPTION, tableName=RESOURCE_SERVER_POLICY; modifyDataType columnName=DESCRIPTION,... \N 3.5.4 \N \N 3820445829
2.5.0-unicode-other-dbs hmlnarik@redhat.com META-INF/jpa-changelog-2.5.0.xml 2022-02-02 16:47:26.567305 35 EXECUTED 9:33d72168746f81f98ae3a1e8e0ca3554 modifyDataType columnName=DESCRIPTION, tableName=AUTHENTICATION_FLOW; modifyDataType columnName=DESCRIPTION, tableName=CLIENT_TEMPLATE; modifyDataType columnName=DESCRIPTION, tableName=RESOURCE_SERVER_POLICY; modifyDataType columnName=DESCRIPTION,... \N 3.5.4 \N \N 3820445829
2.5.0-duplicate-email-support slawomir@dabek.name META-INF/jpa-changelog-2.5.0.xml 2022-02-02 16:47:26.570727 36 EXECUTED 9:61b6d3d7a4c0e0024b0c839da283da0c addColumn tableName=REALM \N 3.5.4 \N \N 3820445829
2.5.0-unique-group-names hmlnarik@redhat.com META-INF/jpa-changelog-2.5.0.xml 2022-02-02 16:47:26.578396 37 EXECUTED 9:8dcac7bdf7378e7d823cdfddebf72fda addUniqueConstraint constraintName=SIBLING_NAMES, tableName=KEYCLOAK_GROUP \N 3.5.4 \N \N 3820445829
2.5.1 bburke@redhat.com META-INF/jpa-changelog-2.5.1.xml 2022-02-02 16:47:26.581391 38 EXECUTED 9:a2b870802540cb3faa72098db5388af3 addColumn tableName=FED_USER_CONSENT \N 3.5.4 \N \N 3820445829
3.0.0 bburke@redhat.com META-INF/jpa-changelog-3.0.0.xml 2022-02-02 16:47:26.584204 39 EXECUTED 9:132a67499ba24bcc54fb5cbdcfe7e4c0 addColumn tableName=IDENTITY_PROVIDER \N 3.5.4 \N \N 3820445829
3.2.0-fix keycloak META-INF/jpa-changelog-3.2.0.xml 2022-02-02 16:47:26.585877 40 MARK_RAN 9:938f894c032f5430f2b0fafb1a243462 addNotNullConstraint columnName=REALM_ID, tableName=CLIENT_INITIAL_ACCESS \N 3.5.4 \N \N 3820445829
3.2.0-fix-with-keycloak-5416 keycloak META-INF/jpa-changelog-3.2.0.xml 2022-02-02 16:47:26.587657 41 MARK_RAN 9:845c332ff1874dc5d35974b0babf3006 dropIndex indexName=IDX_CLIENT_INIT_ACC_REALM, tableName=CLIENT_INITIAL_ACCESS; addNotNullConstraint columnName=REALM_ID, tableName=CLIENT_INITIAL_ACCESS; createIndex indexName=IDX_CLIENT_INIT_ACC_REALM, tableName=CLIENT_INITIAL_ACCESS \N 3.5.4 \N \N 3820445829
3.2.0-fix-offline-sessions hmlnarik META-INF/jpa-changelog-3.2.0.xml 2022-02-02 16:47:26.591561 42 EXECUTED 9:fc86359c079781adc577c5a217e4d04c customChange \N 3.5.4 \N \N 3820445829
3.2.0-fixed keycloak META-INF/jpa-changelog-3.2.0.xml 2022-02-02 16:47:26.669981 43 EXECUTED 9:59a64800e3c0d09b825f8a3b444fa8f4 addColumn tableName=REALM; dropPrimaryKey constraintName=CONSTRAINT_OFFL_CL_SES_PK2, tableName=OFFLINE_CLIENT_SESSION; dropColumn columnName=CLIENT_SESSION_ID, tableName=OFFLINE_CLIENT_SESSION; addPrimaryKey constraintName=CONSTRAINT_OFFL_CL_SES_P... \N 3.5.4 \N \N 3820445829
3.3.0 keycloak META-INF/jpa-changelog-3.3.0.xml 2022-02-02 16:47:26.673701 44 EXECUTED 9:d48d6da5c6ccf667807f633fe489ce88 addColumn tableName=USER_ENTITY \N 3.5.4 \N \N 3820445829
authz-3.4.0.CR1-resource-server-pk-change-part1 glavoie@gmail.com META-INF/jpa-changelog-authz-3.4.0.CR1.xml 2022-02-02 16:47:26.679075 45 EXECUTED 9:dde36f7973e80d71fceee683bc5d2951 addColumn tableName=RESOURCE_SERVER_POLICY; addColumn tableName=RESOURCE_SERVER_RESOURCE; addColumn tableName=RESOURCE_SERVER_SCOPE \N 3.5.4 \N \N 3820445829
authz-3.4.0.CR1-resource-server-pk-change-part2-KEYCLOAK-6095 hmlnarik@redhat.com META-INF/jpa-changelog-authz-3.4.0.CR1.xml 2022-02-02 16:47:26.681987 46 EXECUTED 9:b855e9b0a406b34fa323235a0cf4f640 customChange \N 3.5.4 \N \N 3820445829
authz-3.4.0.CR1-resource-server-pk-change-part3-fixed glavoie@gmail.com META-INF/jpa-changelog-authz-3.4.0.CR1.xml 2022-02-02 16:47:26.683661 47 MARK_RAN 9:51abbacd7b416c50c4421a8cabf7927e dropIndex indexName=IDX_RES_SERV_POL_RES_SERV, tableName=RESOURCE_SERVER_POLICY; dropIndex indexName=IDX_RES_SRV_RES_RES_SRV, tableName=RESOURCE_SERVER_RESOURCE; dropIndex indexName=IDX_RES_SRV_SCOPE_RES_SRV, tableName=RESOURCE_SERVER_SCOPE \N 3.5.4 \N \N 3820445829
authz-3.4.0.CR1-resource-server-pk-change-part3-fixed-nodropindex glavoie@gmail.com META-INF/jpa-changelog-authz-3.4.0.CR1.xml 2022-02-02 16:47:26.702743 48 EXECUTED 9:bdc99e567b3398bac83263d375aad143 addNotNullConstraint columnName=RESOURCE_SERVER_CLIENT_ID, tableName=RESOURCE_SERVER_POLICY; addNotNullConstraint columnName=RESOURCE_SERVER_CLIENT_ID, tableName=RESOURCE_SERVER_RESOURCE; addNotNullConstraint columnName=RESOURCE_SERVER_CLIENT_ID, ... \N 3.5.4 \N \N 3820445829
authn-3.4.0.CR1-refresh-token-max-reuse glavoie@gmail.com META-INF/jpa-changelog-authz-3.4.0.CR1.xml 2022-02-02 16:47:26.706593 49 EXECUTED 9:d198654156881c46bfba39abd7769e69 addColumn tableName=REALM \N 3.5.4 \N \N 3820445829
3.4.0 keycloak META-INF/jpa-changelog-3.4.0.xml 2022-02-02 16:47:26.734467 50 EXECUTED 9:cfdd8736332ccdd72c5256ccb42335db addPrimaryKey constraintName=CONSTRAINT_REALM_DEFAULT_ROLES, tableName=REALM_DEFAULT_ROLES; addPrimaryKey constraintName=CONSTRAINT_COMPOSITE_ROLE, tableName=COMPOSITE_ROLE; addPrimaryKey constraintName=CONSTR_REALM_DEFAULT_GROUPS, tableName=REALM... \N 3.5.4 \N \N 3820445829
3.4.0-KEYCLOAK-5230 hmlnarik@redhat.com META-INF/jpa-changelog-3.4.0.xml 2022-02-02 16:47:26.78037 51 EXECUTED 9:7c84de3d9bd84d7f077607c1a4dcb714 createIndex indexName=IDX_FU_ATTRIBUTE, tableName=FED_USER_ATTRIBUTE; createIndex indexName=IDX_FU_CONSENT, tableName=FED_USER_CONSENT; createIndex indexName=IDX_FU_CONSENT_RU, tableName=FED_USER_CONSENT; createIndex indexName=IDX_FU_CREDENTIAL, t... \N 3.5.4 \N \N 3820445829
3.4.1 psilva@redhat.com META-INF/jpa-changelog-3.4.1.xml 2022-02-02 16:47:26.783989 52 EXECUTED 9:5a6bb36cbefb6a9d6928452c0852af2d modifyDataType columnName=VALUE, tableName=CLIENT_ATTRIBUTES \N 3.5.4 \N \N 3820445829
3.4.2-KEYCLOAK-5172 mkanis@redhat.com META-INF/jpa-changelog-3.4.2.xml 2022-02-02 16:47:26.788788 54 EXECUTED 9:9156214268f09d970cdf0e1564d866af update tableName=CLIENT \N 3.5.4 \N \N 3820445829
4.0.0-KEYCLOAK-6335 bburke@redhat.com META-INF/jpa-changelog-4.0.0.xml 2022-02-02 16:47:26.794881 55 EXECUTED 9:db806613b1ed154826c02610b7dbdf74 createTable tableName=CLIENT_AUTH_FLOW_BINDINGS; addPrimaryKey constraintName=C_CLI_FLOW_BIND, tableName=CLIENT_AUTH_FLOW_BINDINGS \N 3.5.4 \N \N 3820445829
4.0.0-CLEANUP-UNUSED-TABLE bburke@redhat.com META-INF/jpa-changelog-4.0.0.xml 2022-02-02 16:47:26.799493 56 EXECUTED 9:229a041fb72d5beac76bb94a5fa709de dropTable tableName=CLIENT_IDENTITY_PROV_MAPPING \N 3.5.4 \N \N 3820445829
4.0.0-KEYCLOAK-6228 bburke@redhat.com META-INF/jpa-changelog-4.0.0.xml 2022-02-02 16:47:26.810686 57 EXECUTED 9:079899dade9c1e683f26b2aa9ca6ff04 dropUniqueConstraint constraintName=UK_JKUWUVD56ONTGSUHOGM8UEWRT, tableName=USER_CONSENT; dropNotNullConstraint columnName=CLIENT_ID, tableName=USER_CONSENT; addColumn tableName=USER_CONSENT; addUniqueConstraint constraintName=UK_JKUWUVD56ONTGSUHO... \N 3.5.4 \N \N 3820445829
4.0.0-KEYCLOAK-5579-fixed mposolda@redhat.com META-INF/jpa-changelog-4.0.0.xml 2022-02-02 16:47:26.861332 58 EXECUTED 9:139b79bcbbfe903bb1c2d2a4dbf001d9 dropForeignKeyConstraint baseTableName=CLIENT_TEMPLATE_ATTRIBUTES, constraintName=FK_CL_TEMPL_ATTR_TEMPL; renameTable newTableName=CLIENT_SCOPE_ATTRIBUTES, oldTableName=CLIENT_TEMPLATE_ATTRIBUTES; renameColumn newColumnName=SCOPE_ID, oldColumnName... \N 3.5.4 \N \N 3820445829
authz-4.0.0.CR1 psilva@redhat.com META-INF/jpa-changelog-authz-4.0.0.CR1.xml 2022-02-02 16:47:26.877018 59 EXECUTED 9:b55738ad889860c625ba2bf483495a04 createTable tableName=RESOURCE_SERVER_PERM_TICKET; addPrimaryKey constraintName=CONSTRAINT_FAPMT, tableName=RESOURCE_SERVER_PERM_TICKET; addForeignKeyConstraint baseTableName=RESOURCE_SERVER_PERM_TICKET, constraintName=FK_FRSRHO213XCX4WNKOG82SSPMT... \N 3.5.4 \N \N 3820445829
authz-4.0.0.Beta3 psilva@redhat.com META-INF/jpa-changelog-authz-4.0.0.Beta3.xml 2022-02-02 16:47:26.881203 60 EXECUTED 9:e0057eac39aa8fc8e09ac6cfa4ae15fe addColumn tableName=RESOURCE_SERVER_POLICY; addColumn tableName=RESOURCE_SERVER_PERM_TICKET; addForeignKeyConstraint baseTableName=RESOURCE_SERVER_PERM_TICKET, constraintName=FK_FRSRPO2128CX4WNKOG82SSRFY, referencedTableName=RESOURCE_SERVER_POLICY \N 3.5.4 \N \N 3820445829
authz-4.2.0.Final mhajas@redhat.com META-INF/jpa-changelog-authz-4.2.0.Final.xml 2022-02-02 16:47:26.886177 61 EXECUTED 9:42a33806f3a0443fe0e7feeec821326c createTable tableName=RESOURCE_URIS; addForeignKeyConstraint baseTableName=RESOURCE_URIS, constraintName=FK_RESOURCE_SERVER_URIS, referencedTableName=RESOURCE_SERVER_RESOURCE; customChange; dropColumn columnName=URI, tableName=RESOURCE_SERVER_RESO... \N 3.5.4 \N \N 3820445829
authz-4.2.0.Final-KEYCLOAK-9944 hmlnarik@redhat.com META-INF/jpa-changelog-authz-4.2.0.Final.xml 2022-02-02 16:47:26.890482 62 EXECUTED 9:9968206fca46eecc1f51db9c024bfe56 addPrimaryKey constraintName=CONSTRAINT_RESOUR_URIS_PK, tableName=RESOURCE_URIS \N 3.5.4 \N \N 3820445829
4.2.0-KEYCLOAK-6313 wadahiro@gmail.com META-INF/jpa-changelog-4.2.0.xml 2022-02-02 16:47:26.893518 63 EXECUTED 9:92143a6daea0a3f3b8f598c97ce55c3d addColumn tableName=REQUIRED_ACTION_PROVIDER \N 3.5.4 \N \N 3820445829
4.3.0-KEYCLOAK-7984 wadahiro@gmail.com META-INF/jpa-changelog-4.3.0.xml 2022-02-02 16:47:26.895621 64 EXECUTED 9:82bab26a27195d889fb0429003b18f40 update tableName=REQUIRED_ACTION_PROVIDER \N 3.5.4 \N \N 3820445829
4.6.0-KEYCLOAK-7950 psilva@redhat.com META-INF/jpa-changelog-4.6.0.xml 2022-02-02 16:47:26.89756 65 EXECUTED 9:e590c88ddc0b38b0ae4249bbfcb5abc3 update tableName=RESOURCE_SERVER_RESOURCE \N 3.5.4 \N \N 3820445829
4.6.0-KEYCLOAK-8377 keycloak META-INF/jpa-changelog-4.6.0.xml 2022-02-02 16:47:26.908059 66 EXECUTED 9:5c1f475536118dbdc38d5d7977950cc0 createTable tableName=ROLE_ATTRIBUTE; addPrimaryKey constraintName=CONSTRAINT_ROLE_ATTRIBUTE_PK, tableName=ROLE_ATTRIBUTE; addForeignKeyConstraint baseTableName=ROLE_ATTRIBUTE, constraintName=FK_ROLE_ATTRIBUTE_ID, referencedTableName=KEYCLOAK_ROLE... \N 3.5.4 \N \N 3820445829
4.6.0-KEYCLOAK-8555 gideonray@gmail.com META-INF/jpa-changelog-4.6.0.xml 2022-02-02 16:47:26.912693 67 EXECUTED 9:e7c9f5f9c4d67ccbbcc215440c718a17 createIndex indexName=IDX_COMPONENT_PROVIDER_TYPE, tableName=COMPONENT \N 3.5.4 \N \N 3820445829
4.7.0-KEYCLOAK-1267 sguilhen@redhat.com META-INF/jpa-changelog-4.7.0.xml 2022-02-02 16:47:26.915771 68 EXECUTED 9:88e0bfdda924690d6f4e430c53447dd5 addColumn tableName=REALM \N 3.5.4 \N \N 3820445829
4.7.0-KEYCLOAK-7275 keycloak META-INF/jpa-changelog-4.7.0.xml 2022-02-02 16:47:26.924465 69 EXECUTED 9:f53177f137e1c46b6a88c59ec1cb5218 renameColumn newColumnName=CREATED_ON, oldColumnName=LAST_SESSION_REFRESH, tableName=OFFLINE_USER_SESSION; addNotNullConstraint columnName=CREATED_ON, tableName=OFFLINE_USER_SESSION; addColumn tableName=OFFLINE_USER_SESSION; customChange; createIn... \N 3.5.4 \N \N 3820445829
4.8.0-KEYCLOAK-8835 sguilhen@redhat.com META-INF/jpa-changelog-4.8.0.xml 2022-02-02 16:47:26.928034 70 EXECUTED 9:a74d33da4dc42a37ec27121580d1459f addNotNullConstraint columnName=SSO_MAX_LIFESPAN_REMEMBER_ME, tableName=REALM; addNotNullConstraint columnName=SSO_IDLE_TIMEOUT_REMEMBER_ME, tableName=REALM \N 3.5.4 \N \N 3820445829
authz-7.0.0-KEYCLOAK-10443 psilva@redhat.com META-INF/jpa-changelog-authz-7.0.0.xml 2022-02-02 16:47:26.93061 71 EXECUTED 9:fd4ade7b90c3b67fae0bfcfcb42dfb5f addColumn tableName=RESOURCE_SERVER \N 3.5.4 \N \N 3820445829
8.0.0-adding-credential-columns keycloak META-INF/jpa-changelog-8.0.0.xml 2022-02-02 16:47:26.933771 72 EXECUTED 9:aa072ad090bbba210d8f18781b8cebf4 addColumn tableName=CREDENTIAL; addColumn tableName=FED_USER_CREDENTIAL \N 3.5.4 \N \N 3820445829
8.0.0-credential-cleanup-fixed keycloak META-INF/jpa-changelog-8.0.0.xml 2022-02-02 16:47:26.945819 75 EXECUTED 9:2b9cc12779be32c5b40e2e67711a218b dropDefaultValue columnName=COUNTER, tableName=CREDENTIAL; dropDefaultValue columnName=DIGITS, tableName=CREDENTIAL; dropDefaultValue columnName=PERIOD, tableName=CREDENTIAL; dropDefaultValue columnName=ALGORITHM, tableName=CREDENTIAL; dropColumn ... \N 3.5.4 \N \N 3820445829
8.0.0-resource-tag-support keycloak META-INF/jpa-changelog-8.0.0.xml 2022-02-02 16:47:26.950255 76 EXECUTED 9:91fa186ce7a5af127a2d7a91ee083cc5 addColumn tableName=MIGRATION_MODEL; createIndex indexName=IDX_UPDATE_TIME, tableName=MIGRATION_MODEL \N 3.5.4 \N \N 3820445829
9.0.0-always-display-client keycloak META-INF/jpa-changelog-9.0.0.xml 2022-02-02 16:47:26.955505 77 EXECUTED 9:6335e5c94e83a2639ccd68dd24e2e5ad addColumn tableName=CLIENT \N 3.5.4 \N \N 3820445829
9.0.0-drop-constraints-for-column-increase keycloak META-INF/jpa-changelog-9.0.0.xml 2022-02-02 16:47:26.957216 78 MARK_RAN 9:6bdb5658951e028bfe16fa0a8228b530 dropUniqueConstraint constraintName=UK_FRSR6T700S9V50BU18WS5PMT, tableName=RESOURCE_SERVER_PERM_TICKET; dropUniqueConstraint constraintName=UK_FRSR6T700S9V50BU18WS5HA6, tableName=RESOURCE_SERVER_RESOURCE; dropPrimaryKey constraintName=CONSTRAINT_O... \N 3.5.4 \N \N 3820445829
9.0.0-increase-column-size-federated-fk keycloak META-INF/jpa-changelog-9.0.0.xml 2022-02-02 16:47:26.966746 79 EXECUTED 9:d5bc15a64117ccad481ce8792d4c608f modifyDataType columnName=CLIENT_ID, tableName=FED_USER_CONSENT; modifyDataType columnName=CLIENT_REALM_CONSTRAINT, tableName=KEYCLOAK_ROLE; modifyDataType columnName=OWNER, tableName=RESOURCE_SERVER_POLICY; modifyDataType columnName=CLIENT_ID, ta... \N 3.5.4 \N \N 3820445829
9.0.0-recreate-constraints-after-column-increase keycloak META-INF/jpa-changelog-9.0.0.xml 2022-02-02 16:47:26.969643 80 MARK_RAN 9:077cba51999515f4d3e7ad5619ab592c addNotNullConstraint columnName=CLIENT_ID, tableName=OFFLINE_CLIENT_SESSION; addNotNullConstraint columnName=OWNER, tableName=RESOURCE_SERVER_PERM_TICKET; addNotNullConstraint columnName=REQUESTER, tableName=RESOURCE_SERVER_PERM_TICKET; addNotNull... \N 3.5.4 \N \N 3820445829
9.0.1-add-index-to-client.client_id keycloak META-INF/jpa-changelog-9.0.1.xml 2022-02-02 16:47:26.975764 81 EXECUTED 9:be969f08a163bf47c6b9e9ead8ac2afb createIndex indexName=IDX_CLIENT_ID, tableName=CLIENT \N 3.5.4 \N \N 3820445829
9.0.1-KEYCLOAK-12579-drop-constraints keycloak META-INF/jpa-changelog-9.0.1.xml 2022-02-02 16:47:26.977227 82 MARK_RAN 9:6d3bb4408ba5a72f39bd8a0b301ec6e3 dropUniqueConstraint constraintName=SIBLING_NAMES, tableName=KEYCLOAK_GROUP \N 3.5.4 \N \N 3820445829
9.0.1-KEYCLOAK-12579-add-not-null-constraint keycloak META-INF/jpa-changelog-9.0.1.xml 2022-02-02 16:47:26.980058 83 EXECUTED 9:966bda61e46bebf3cc39518fbed52fa7 addNotNullConstraint columnName=PARENT_GROUP, tableName=KEYCLOAK_GROUP \N 3.5.4 \N \N 3820445829
9.0.1-KEYCLOAK-12579-recreate-constraints keycloak META-INF/jpa-changelog-9.0.1.xml 2022-02-02 16:47:26.981645 84 MARK_RAN 9:8dcac7bdf7378e7d823cdfddebf72fda addUniqueConstraint constraintName=SIBLING_NAMES, tableName=KEYCLOAK_GROUP \N 3.5.4 \N \N 3820445829
9.0.1-add-index-to-events keycloak META-INF/jpa-changelog-9.0.1.xml 2022-02-02 16:47:26.985465 85 EXECUTED 9:7d93d602352a30c0c317e6a609b56599 createIndex indexName=IDX_EVENT_TIME, tableName=EVENT_ENTITY \N 3.5.4 \N \N 3820445829
map-remove-ri keycloak META-INF/jpa-changelog-11.0.0.xml 2022-02-02 16:47:26.98869 86 EXECUTED 9:71c5969e6cdd8d7b6f47cebc86d37627 dropForeignKeyConstraint baseTableName=REALM, constraintName=FK_TRAF444KK6QRKMS7N56AIWQ5Y; dropForeignKeyConstraint baseTableName=KEYCLOAK_ROLE, constraintName=FK_KJHO5LE2C0RAL09FL8CM9WFW9 \N 3.5.4 \N \N 3820445829
map-remove-ri keycloak META-INF/jpa-changelog-12.0.0.xml 2022-02-02 16:47:26.992854 87 EXECUTED 9:a9ba7d47f065f041b7da856a81762021 dropForeignKeyConstraint baseTableName=REALM_DEFAULT_GROUPS, constraintName=FK_DEF_GROUPS_GROUP; dropForeignKeyConstraint baseTableName=REALM_DEFAULT_ROLES, constraintName=FK_H4WPD7W4HSOOLNI3H0SW7BTJE; dropForeignKeyConstraint baseTableName=CLIENT... \N 3.5.4 \N \N 3820445829
12.1.0-add-realm-localization-table keycloak META-INF/jpa-changelog-12.0.0.xml 2022-02-02 16:47:26.999694 88 EXECUTED 9:fffabce2bc01e1a8f5110d5278500065 createTable tableName=REALM_LOCALIZATIONS; addPrimaryKey tableName=REALM_LOCALIZATIONS \N 3.5.4 \N \N 3820445829
8.0.0-updating-credential-data-not-oracle-fixed keycloak META-INF/jpa-changelog-8.0.0.xml 2023-01-09 14:34:23.080082 89 MARK_RAN 9:1ae6be29bab7c2aa376f6983b932be37 update tableName=CREDENTIAL; update tableName=CREDENTIAL; update tableName=CREDENTIAL; update tableName=FED_USER_CREDENTIAL; update tableName=FED_USER_CREDENTIAL; update tableName=FED_USER_CREDENTIAL \N 4.8.0 \N \N 3274862955
8.0.0-updating-credential-data-oracle-fixed keycloak META-INF/jpa-changelog-8.0.0.xml 2023-01-09 14:34:23.099857 90 MARK_RAN 9:14706f286953fc9a25286dbd8fb30d97 update tableName=CREDENTIAL; update tableName=CREDENTIAL; update tableName=CREDENTIAL; update tableName=FED_USER_CREDENTIAL; update tableName=FED_USER_CREDENTIAL; update tableName=FED_USER_CREDENTIAL \N 4.8.0 \N \N 3274862955
default-roles keycloak META-INF/jpa-changelog-13.0.0.xml 2023-01-09 14:34:23.144776 91 EXECUTED 9:fa8a5b5445e3857f4b010bafb5009957 addColumn tableName=REALM; customChange \N 4.8.0 \N \N 3274862955
default-roles-cleanup keycloak META-INF/jpa-changelog-13.0.0.xml 2023-01-09 14:34:23.155298 92 EXECUTED 9:67ac3241df9a8582d591c5ed87125f39 dropTable tableName=REALM_DEFAULT_ROLES; dropTable tableName=CLIENT_DEFAULT_ROLES \N 4.8.0 \N \N 3274862955
13.0.0-KEYCLOAK-16844 keycloak META-INF/jpa-changelog-13.0.0.xml 2023-01-09 14:34:23.162911 93 EXECUTED 9:ad1194d66c937e3ffc82386c050ba089 createIndex indexName=IDX_OFFLINE_USS_PRELOAD, tableName=OFFLINE_USER_SESSION \N 4.8.0 \N \N 3274862955
map-remove-ri-13.0.0 keycloak META-INF/jpa-changelog-13.0.0.xml 2023-01-09 14:34:23.17617 94 EXECUTED 9:d9be619d94af5a2f5d07b9f003543b91 dropForeignKeyConstraint baseTableName=DEFAULT_CLIENT_SCOPE, constraintName=FK_R_DEF_CLI_SCOPE_SCOPE; dropForeignKeyConstraint baseTableName=CLIENT_SCOPE_CLIENT, constraintName=FK_C_CLI_SCOPE_SCOPE; dropForeignKeyConstraint baseTableName=CLIENT_SC... \N 4.8.0 \N \N 3274862955
13.0.0-KEYCLOAK-17992-drop-constraints keycloak META-INF/jpa-changelog-13.0.0.xml 2023-01-09 14:34:23.1803 95 MARK_RAN 9:544d201116a0fcc5a5da0925fbbc3bde dropPrimaryKey constraintName=C_CLI_SCOPE_BIND, tableName=CLIENT_SCOPE_CLIENT; dropIndex indexName=IDX_CLSCOPE_CL, tableName=CLIENT_SCOPE_CLIENT; dropIndex indexName=IDX_CL_CLSCOPE, tableName=CLIENT_SCOPE_CLIENT \N 4.8.0 \N \N 3274862955
13.0.0-increase-column-size-federated keycloak META-INF/jpa-changelog-13.0.0.xml 2023-01-09 14:34:23.190613 96 EXECUTED 9:43c0c1055b6761b4b3e89de76d612ccf modifyDataType columnName=CLIENT_ID, tableName=CLIENT_SCOPE_CLIENT; modifyDataType columnName=SCOPE_ID, tableName=CLIENT_SCOPE_CLIENT \N 4.8.0 \N \N 3274862955
13.0.0-KEYCLOAK-17992-recreate-constraints keycloak META-INF/jpa-changelog-13.0.0.xml 2023-01-09 14:34:23.193934 97 MARK_RAN 9:8bd711fd0330f4fe980494ca43ab1139 addNotNullConstraint columnName=CLIENT_ID, tableName=CLIENT_SCOPE_CLIENT; addNotNullConstraint columnName=SCOPE_ID, tableName=CLIENT_SCOPE_CLIENT; addPrimaryKey constraintName=C_CLI_SCOPE_BIND, tableName=CLIENT_SCOPE_CLIENT; createIndex indexName=... \N 4.8.0 \N \N 3274862955
json-string-accomodation-fixed keycloak META-INF/jpa-changelog-13.0.0.xml 2023-01-09 14:34:23.202965 98 EXECUTED 9:e07d2bc0970c348bb06fb63b1f82ddbf addColumn tableName=REALM_ATTRIBUTE; update tableName=REALM_ATTRIBUTE; dropColumn columnName=VALUE, tableName=REALM_ATTRIBUTE; renameColumn newColumnName=VALUE, oldColumnName=VALUE_NEW, tableName=REALM_ATTRIBUTE \N 4.8.0 \N \N 3274862955
14.0.0-KEYCLOAK-11019 keycloak META-INF/jpa-changelog-14.0.0.xml 2023-01-09 14:34:23.212244 99 EXECUTED 9:24fb8611e97f29989bea412aa38d12b7 createIndex indexName=IDX_OFFLINE_CSS_PRELOAD, tableName=OFFLINE_CLIENT_SESSION; createIndex indexName=IDX_OFFLINE_USS_BY_USER, tableName=OFFLINE_USER_SESSION; createIndex indexName=IDX_OFFLINE_USS_BY_USERSESS, tableName=OFFLINE_USER_SESSION \N 4.8.0 \N \N 3274862955
14.0.0-KEYCLOAK-18286 keycloak META-INF/jpa-changelog-14.0.0.xml 2023-01-09 14:34:23.2164 100 MARK_RAN 9:259f89014ce2506ee84740cbf7163aa7 createIndex indexName=IDX_CLIENT_ATT_BY_NAME_VALUE, tableName=CLIENT_ATTRIBUTES \N 4.8.0 \N \N 3274862955
14.0.0-KEYCLOAK-18286-revert keycloak META-INF/jpa-changelog-14.0.0.xml 2023-01-09 14:34:23.227895 101 MARK_RAN 9:04baaf56c116ed19951cbc2cca584022 dropIndex indexName=IDX_CLIENT_ATT_BY_NAME_VALUE, tableName=CLIENT_ATTRIBUTES \N 4.8.0 \N \N 3274862955
14.0.0-KEYCLOAK-18286-supported-dbs keycloak META-INF/jpa-changelog-14.0.0.xml 2023-01-09 14:34:23.235491 102 EXECUTED 9:60ca84a0f8c94ec8c3504a5a3bc88ee8 createIndex indexName=IDX_CLIENT_ATT_BY_NAME_VALUE, tableName=CLIENT_ATTRIBUTES \N 4.8.0 \N \N 3274862955
14.0.0-KEYCLOAK-18286-unsupported-dbs keycloak META-INF/jpa-changelog-14.0.0.xml 2023-01-09 14:34:23.238498 103 MARK_RAN 9:d3d977031d431db16e2c181ce49d73e9 createIndex indexName=IDX_CLIENT_ATT_BY_NAME_VALUE, tableName=CLIENT_ATTRIBUTES \N 4.8.0 \N \N 3274862955
KEYCLOAK-17267-add-index-to-user-attributes keycloak META-INF/jpa-changelog-14.0.0.xml 2023-01-09 14:34:23.24435 104 EXECUTED 9:0b305d8d1277f3a89a0a53a659ad274c createIndex indexName=IDX_USER_ATTRIBUTE_NAME, tableName=USER_ATTRIBUTE \N 4.8.0 \N \N 3274862955
KEYCLOAK-18146-add-saml-art-binding-identifier keycloak META-INF/jpa-changelog-14.0.0.xml 2023-01-09 14:34:23.250444 105 EXECUTED 9:2c374ad2cdfe20e2905a84c8fac48460 customChange \N 4.8.0 \N \N 3274862955
15.0.0-KEYCLOAK-18467 keycloak META-INF/jpa-changelog-15.0.0.xml 2023-01-09 14:34:23.261701 106 EXECUTED 9:47a760639ac597360a8219f5b768b4de addColumn tableName=REALM_LOCALIZATIONS; update tableName=REALM_LOCALIZATIONS; dropColumn columnName=TEXTS, tableName=REALM_LOCALIZATIONS; renameColumn newColumnName=TEXTS, oldColumnName=TEXTS_NEW, tableName=REALM_LOCALIZATIONS; addNotNullConstrai... \N 4.8.0 \N \N 3274862955
17.0.0-9562 keycloak META-INF/jpa-changelog-17.0.0.xml 2023-01-09 14:34:23.269577 107 EXECUTED 9:a6272f0576727dd8cad2522335f5d99e createIndex indexName=IDX_USER_SERVICE_ACCOUNT, tableName=USER_ENTITY \N 4.8.0 \N \N 3274862955
18.0.0-10625-IDX_ADMIN_EVENT_TIME keycloak META-INF/jpa-changelog-18.0.0.xml 2023-01-09 14:34:23.276738 108 EXECUTED 9:015479dbd691d9cc8669282f4828c41d createIndex indexName=IDX_ADMIN_EVENT_TIME, tableName=ADMIN_EVENT_ENTITY \N 4.8.0 \N \N 3274862955
19.0.0-10135 keycloak META-INF/jpa-changelog-19.0.0.xml 2023-01-09 14:34:23.297485 109 EXECUTED 9:9518e495fdd22f78ad6425cc30630221 customChange \N 4.8.0 \N \N 3274862955
20.0.0-12964-supported-dbs keycloak META-INF/jpa-changelog-20.0.0.xml 2023-01-09 14:34:23.305463 110 EXECUTED 9:e5f243877199fd96bcc842f27a1656ac createIndex indexName=IDX_GROUP_ATT_BY_NAME_VALUE, tableName=GROUP_ATTRIBUTE \N 4.8.0 \N \N 3274862955
20.0.0-12964-unsupported-dbs keycloak META-INF/jpa-changelog-20.0.0.xml 2023-01-09 14:34:23.309005 111 MARK_RAN 9:1a6fcaa85e20bdeae0a9ce49b41946a5 createIndex indexName=IDX_GROUP_ATT_BY_NAME_VALUE, tableName=GROUP_ATTRIBUTE \N 4.8.0 \N \N 3274862955
client-attributes-string-accomodation-fixed keycloak META-INF/jpa-changelog-20.0.0.xml 2023-01-09 14:34:23.318788 112 EXECUTED 9:3f332e13e90739ed0c35b0b25b7822ca addColumn tableName=CLIENT_ATTRIBUTES; update tableName=CLIENT_ATTRIBUTES; dropColumn columnName=VALUE, tableName=CLIENT_ATTRIBUTES; renameColumn newColumnName=VALUE, oldColumnName=VALUE_NEW, tableName=CLIENT_ATTRIBUTES \N 4.8.0 \N \N 3274862955
21.0.2-17277 keycloak META-INF/jpa-changelog-21.0.2.xml 2024-02-14 09:01:09.307684 113 EXECUTED 9:7ee1f7a3fb8f5588f171fb9a6ab623c0 customChange \N 4.23.2 \N \N 7901269232
21.1.0-19404 keycloak META-INF/jpa-changelog-21.1.0.xml 2024-02-14 09:01:09.324282 114 EXECUTED 9:3d7e830b52f33676b9d64f7f2b2ea634 modifyDataType columnName=DECISION_STRATEGY, tableName=RESOURCE_SERVER_POLICY; modifyDataType columnName=LOGIC, tableName=RESOURCE_SERVER_POLICY; modifyDataType columnName=POLICY_ENFORCE_MODE, tableName=RESOURCE_SERVER \N 4.23.2 \N \N 7901269232
21.1.0-19404-2 keycloak META-INF/jpa-changelog-21.1.0.xml 2024-02-14 09:01:09.327044 115 MARK_RAN 9:627d032e3ef2c06c0e1f73d2ae25c26c addColumn tableName=RESOURCE_SERVER_POLICY; update tableName=RESOURCE_SERVER_POLICY; dropColumn columnName=DECISION_STRATEGY, tableName=RESOURCE_SERVER_POLICY; renameColumn newColumnName=DECISION_STRATEGY, oldColumnName=DECISION_STRATEGY_NEW, tabl... \N 4.23.2 \N \N 7901269232
22.0.0-17484-updated keycloak META-INF/jpa-changelog-22.0.0.xml 2024-02-14 09:01:09.332189 116 EXECUTED 9:90af0bfd30cafc17b9f4d6eccd92b8b3 customChange \N 4.23.2 \N \N 7901269232
22.0.5-24031 keycloak META-INF/jpa-changelog-22.0.0.xml 2024-02-14 09:01:09.333603 117 MARK_RAN 9:a60d2d7b315ec2d3eba9e2f145f9df28 customChange \N 4.23.2 \N \N 7901269232
23.0.0-12062 keycloak META-INF/jpa-changelog-23.0.0.xml 2024-02-14 09:01:09.340927 118 EXECUTED 9:2168fbe728fec46ae9baf15bf80927b8 addColumn tableName=COMPONENT_CONFIG; update tableName=COMPONENT_CONFIG; dropColumn columnName=VALUE, tableName=COMPONENT_CONFIG; renameColumn newColumnName=VALUE, oldColumnName=VALUE_NEW, tableName=COMPONENT_CONFIG \N 4.23.2 \N \N 7901269232
23.0.0-17258 keycloak META-INF/jpa-changelog-23.0.0.xml 2024-02-14 09:01:09.343484 119 EXECUTED 9:36506d679a83bbfda85a27ea1864dca8 addColumn tableName=EVENT_ENTITY \N 4.23.2 \N \N 7901269232
\.
@@ -2385,9 +2379,9 @@ grafana a5bb3a5f-fd26-4be6-9557-26e20a03d33d f
grafana d6ffe9fc-a03c-4496-85dc-dbb5e7754587 f
grafana d6077ed7-b265-4f82-9336-24614967bd5d t
grafana 699671ab-e7c1-4fcf-beb8-ea54f1471fc1 t
grafana c61f5b19-c17e-49a1-91b8-a0296411b928 f
grafana d30340a8-630b-416e-8c93-3ccf932d34f3 t
master a96603aa-e6db-4b3e-8baa-679c75ccfc8f t
grafana c61f5b19-c17e-49a1-91b8-a0296411b928 t
\.
@@ -2395,7 +2389,7 @@ master a96603aa-e6db-4b3e-8baa-679c75ccfc8f t
-- Data for Name: event_entity; Type: TABLE DATA; Schema: public; Owner: keycloak
--
COPY public.event_entity (id, client_id, details_json, error, ip_address, realm_id, session_id, event_time, type, user_id) FROM stdin;
COPY public.event_entity (id, client_id, details_json, error, ip_address, realm_id, session_id, event_time, type, user_id, details_json_long_value) FROM stdin;
\.
@@ -2524,6 +2518,9 @@ COPY public.idp_mapper_config (idp_mapper_id, value, name) FROM stdin;
--
COPY public.keycloak_group (id, name, parent_group, realm_id) FROM stdin;
f1975bf4-6e92-479a-923c-d7d5b65d684c First grafana
fe974984-8b18-4925-beef-37b6cfb6af7b Second grafana
4cc0bd0f-9071-42a9-b282-be22515156ba Third grafana
\.
@@ -2628,6 +2625,7 @@ c9a895d1-c901-46b0-91cf-2c67902b4a93 a5a8fed6-0bca-4646-9946-2fe84175353b t ${ro
COPY public.migration_model (id, version, update_time) FROM stdin;
g5slr 12.0.1 1643820448
wupxt 20.0.2 1673274863
y2nke 23.0.1 1707901269
\.
@@ -2710,13 +2708,13 @@ b4854867-3bfb-409b-92a8-6ec37db17f99 phone number verified openid-connect oidc-u
1fc8999a-04d9-421b-8557-e417a3750358 realm roles openid-connect oidc-usermodel-realm-role-mapper \N d6077ed7-b265-4f82-9336-24614967bd5d
384e97dd-36ad-4b0e-af63-d0cb3a2153d4 allowed web origins openid-connect oidc-allowed-origins-mapper \N 699671ab-e7c1-4fcf-beb8-ea54f1471fc1
f03cac68-3f0e-4068-9adf-ee64567689a7 upn openid-connect oidc-usermodel-property-mapper \N c61f5b19-c17e-49a1-91b8-a0296411b928
04183ee1-b558-4f63-839f-922d30b34a9e groups openid-connect oidc-usermodel-realm-role-mapper \N c61f5b19-c17e-49a1-91b8-a0296411b928
df78645e-c32b-4160-b79f-42e622d71982 locale openid-connect oidc-usermodel-attribute-mapper 805aebc8-9d01-42b6-bcce-6ce48ca63ef0 \N
0108b99f-2f31-4e73-9597-cb29e0e8c486 username openid-connect oidc-usermodel-property-mapper \N f619a55a-d565-4cc0-8bf4-4dbaab5382fe
70b0a264-a7c3-43ff-b24f-14ca4f5f118e login openid-connect oidc-usermodel-property-mapper \N 0a7c7dde-23d7-4a93-bdee-4a8963aee9a4
2f8ee9af-b6dd-4790-9e7b-cce83a603566 name openid-connect oidc-full-name-mapper \N d4723cd4-f717-44b7-a9b0-6c32c5ecd23f
854a81a5-8e06-4257-98ec-0e3087356223 acr loa level openid-connect oidc-acr-mapper \N d30340a8-630b-416e-8c93-3ccf932d34f3
53832401-d27c-489e-801f-9807cdaa4b08 acr loa level openid-connect oidc-acr-mapper \N a96603aa-e6db-4b3e-8baa-679c75ccfc8f
6814ca6a-2d7d-495d-87ad-53e12b561808 groups openid-connect oidc-group-membership-mapper \N c61f5b19-c17e-49a1-91b8-a0296411b928
\.
@@ -2991,12 +2989,6 @@ f03cac68-3f0e-4068-9adf-ee64567689a7 true id.token.claim
f03cac68-3f0e-4068-9adf-ee64567689a7 true access.token.claim
f03cac68-3f0e-4068-9adf-ee64567689a7 upn claim.name
f03cac68-3f0e-4068-9adf-ee64567689a7 String jsonType.label
04183ee1-b558-4f63-839f-922d30b34a9e true multivalued
04183ee1-b558-4f63-839f-922d30b34a9e foo user.attribute
04183ee1-b558-4f63-839f-922d30b34a9e true id.token.claim
04183ee1-b558-4f63-839f-922d30b34a9e true access.token.claim
04183ee1-b558-4f63-839f-922d30b34a9e groups claim.name
04183ee1-b558-4f63-839f-922d30b34a9e String jsonType.label
df78645e-c32b-4160-b79f-42e622d71982 true userinfo.token.claim
df78645e-c32b-4160-b79f-42e622d71982 locale user.attribute
df78645e-c32b-4160-b79f-42e622d71982 true id.token.claim
@@ -3025,6 +3017,13 @@ df78645e-c32b-4160-b79f-42e622d71982 String jsonType.label
854a81a5-8e06-4257-98ec-0e3087356223 true access.token.claim
53832401-d27c-489e-801f-9807cdaa4b08 true id.token.claim
53832401-d27c-489e-801f-9807cdaa4b08 true access.token.claim
6814ca6a-2d7d-495d-87ad-53e12b561808 true introspection.token.claim
6814ca6a-2d7d-495d-87ad-53e12b561808 true userinfo.token.claim
6814ca6a-2d7d-495d-87ad-53e12b561808 true id.token.claim
6814ca6a-2d7d-495d-87ad-53e12b561808 true access.token.claim
6814ca6a-2d7d-495d-87ad-53e12b561808 groups claim.name
6814ca6a-2d7d-495d-87ad-53e12b561808 false full.path
6814ca6a-2d7d-495d-87ad-53e12b561808 true multivalued
\.
@@ -3199,16 +3198,16 @@ ad4dfd2c-307a-4563-b93a-0bb726b4ccaa VERIFY_EMAIL Verify Email master t f VERIFY
2c7fffa4-ff20-4015-9a97-cc6a19e698ba UPDATE_PROFILE Update Profile master t f UPDATE_PROFILE 40
c76d17f4-eacf-497a-ab5a-f78936bbc50e CONFIGURE_TOTP Configure OTP master t f CONFIGURE_TOTP 10
83de9f97-43df-4265-982c-5414a2b19985 UPDATE_PASSWORD Update Password master t f UPDATE_PASSWORD 30
9f538737-770e-4731-abd9-e98172a85d2f terms_and_conditions Terms and Conditions master f f terms_and_conditions 20
306fc47e-d8ae-4bb1-b2bc-53608a44536c update_user_locale Update User Locale master t f update_user_locale 1000
f158f7d8-8b7f-414c-b1bd-0dde83c91133 delete_account Delete Account master f f delete_account 60
969a57d1-c906-4f49-87d6-3cbba2f3898a VERIFY_EMAIL Verify Email grafana t f VERIFY_EMAIL 50
233d5b8e-6f36-450f-bffd-43b82e27295c UPDATE_PROFILE Update Profile grafana t f UPDATE_PROFILE 40
ab3a9aa7-3d1b-4fb1-93ad-9412142deed3 CONFIGURE_TOTP Configure OTP grafana t f CONFIGURE_TOTP 10
988d8e0d-35ef-4e6a-8b48-821cca56acf2 UPDATE_PASSWORD Update Password grafana t f UPDATE_PASSWORD 30
0e2b6144-5c2c-4dcb-92d8-00529b19a7a5 terms_and_conditions Terms and Conditions grafana f f terms_and_conditions 20
94993a02-f883-4f8a-a549-d48f95aabed2 update_user_locale Update User Locale grafana t f update_user_locale 1000
72d09b7f-acde-4b90-af9a-ea3c642a2f6d delete_account Delete Account grafana f f delete_account 60
9f538737-770e-4731-abd9-e98172a85d2f TERMS_AND_CONDITIONS Terms and Conditions master f f TERMS_AND_CONDITIONS 20
0e2b6144-5c2c-4dcb-92d8-00529b19a7a5 TERMS_AND_CONDITIONS Terms and Conditions grafana f f TERMS_AND_CONDITIONS 20
\.
@@ -3386,6 +3385,11 @@ COPY public.user_federation_provider (id, changed_sync_period, display_name, ful
--
COPY public.user_group_membership (group_id, user_id) FROM stdin;
f1975bf4-6e92-479a-923c-d7d5b65d684c 88692d07-bb9a-46cf-844c-7ff5c529cd04
f1975bf4-6e92-479a-923c-d7d5b65d684c 8f58cbec-6e40-4bab-bff0-1c5ff899fe2e
fe974984-8b18-4925-beef-37b6cfb6af7b 88692d07-bb9a-46cf-844c-7ff5c529cd04
4cc0bd0f-9071-42a9-b282-be22515156ba 6db3c5e5-b84b-4f9d-a7a8-8d05b03c929d
4cc0bd0f-9071-42a9-b282-be22515156ba 1a85b7e0-4baa-420b-89f8-1cea43a540dd
\.
+1 -1
View File
@@ -183,7 +183,7 @@
"jest-matcher-utils": "29.7.0",
"lerna": "8.1.2",
"mini-css-extract-plugin": "2.8.0",
"msw": "1.3.2",
"msw": "2.2.0",
"mutationobserver-shim": "0.3.7",
"ngtemplate-loader": "2.1.0",
"node-notifier": "10.0.1",
@@ -2,12 +2,30 @@ import { css, cx } from '@emotion/css';
import { GrafanaTheme2 } from '@grafana/data';
export const getDragStyles = (theme: GrafanaTheme2) => {
export type DragHandlePosition = 'middle' | 'start' | 'end';
export const getDragStyles = (theme: GrafanaTheme2, handlePosition?: DragHandlePosition) => {
const position = handlePosition || 'middle';
const baseColor = theme.colors.emphasize(theme.colors.background.secondary, 0.15);
const hoverColor = theme.colors.primary.border;
const clickTargetSize = theme.spacing(2);
const handlebarThickness = 4;
const handlebarWidth = 200;
let verticalOffset = '50%';
let horizontalOffset = '50%';
switch (position) {
case 'start': {
verticalOffset = '0%';
horizontalOffset = '0%';
break;
}
case 'end': {
verticalOffset = '100%';
horizontalOffset = '100%';
break;
}
}
const dragHandleBase = css({
position: 'relative',
@@ -16,17 +34,17 @@ export const getDragStyles = (theme: GrafanaTheme2) => {
content: '""',
position: 'absolute',
transition: theme.transitions.create('border-color'),
zIndex: 1,
},
'&:after': {
background: baseColor,
content: '""',
position: 'absolute',
left: '50%',
top: '50%',
transition: theme.transitions.create('background'),
transform: 'translate(-50%, -50%)',
borderRadius: theme.shape.radius.pill,
zIndex: 1,
},
'&:hover': {
@@ -50,11 +68,13 @@ export const getDragStyles = (theme: GrafanaTheme2) => {
'&:before': {
borderRight: '1px solid transparent',
height: '100%',
left: '50%',
left: verticalOffset,
transform: 'translateX(-50%)',
},
'&:after': {
left: verticalOffset,
top: '50%',
height: handlebarWidth,
width: handlebarThickness,
},
@@ -68,12 +88,14 @@ export const getDragStyles = (theme: GrafanaTheme2) => {
'&:before': {
borderTop: '1px solid transparent',
top: '50%',
top: horizontalOffset,
transform: 'translateY(-50%)',
width: '100%',
},
'&:after': {
left: '50%',
top: horizontalOffset,
height: handlebarThickness,
width: handlebarWidth,
},
@@ -0,0 +1,23 @@
import { Meta, Preview, ArgTypes } from '@storybook/blocks';
import { Box, Splitter, Text } from '@grafana/ui';
<Meta title="MDX|Splitter" component={Splitter} />
# Splitter
The splitter creates two resizable panes, either horizontally or vertically.
<Preview>
<div style={{ display: 'flex', width: '900px', height: '700px' }}>
<Splitter direction="row" initialSize={0.7}>
<Box display="flex" grow={1} backgroundColor="secondary" padding={2}>
<Text color="primary">Primary</Text>
</Box>
<Box display="flex" grow={1} backgroundColor="secondary" padding={2}>
<Text color="primary">Secondary</Text>
</Box>
</Splitter>
</div>
</Preview>
<ArgTypes of={Splitter} />
@@ -0,0 +1,55 @@
import { css } from '@emotion/css';
import { Meta, StoryFn } from '@storybook/react';
import React from 'react';
import { Splitter, useTheme2 } from '@grafana/ui';
import { DashboardStoryCanvas } from '../../utils/storybook/DashboardStoryCanvas';
import mdx from './Splitter.mdx';
const meta: Meta = {
title: 'General/Layout/Splitter',
component: Splitter,
parameters: {
docs: {
page: mdx,
},
controls: {
exclude: [],
},
},
argTypes: {
initialSize: { control: { type: 'number', min: 0.1, max: 1 } },
},
};
export const Basic: StoryFn = (args) => {
const theme = useTheme2();
const paneStyles = css({
display: 'flex',
flexGrow: 1,
background: theme.colors.background.primary,
padding: theme.spacing(2),
border: `1px solid ${theme.colors.border.weak}`,
height: '100%',
});
return (
<DashboardStoryCanvas>
<div style={{ display: 'flex', width: '700px', height: '500px' }}>
<Splitter {...args}>
<div className={paneStyles}>Primary</div>
<div className={paneStyles}>Secondary</div>
</Splitter>
</div>
</DashboardStoryCanvas>
);
};
Basic.args = {
direction: 'row',
dragPosition: 'middle',
};
export default meta;
@@ -0,0 +1,475 @@
import { css } from '@emotion/css';
import { clamp, throttle } from 'lodash';
import React, { useCallback, useId, useLayoutEffect, useRef } from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { useStyles2 } from '../../themes';
import { DragHandlePosition, getDragStyles } from '../DragHandle/DragHandle';
export interface Props {
/**
* The initial size of the primary pane between 0-1, defaults to 0.5
*/
initialSize?: number;
direction?: 'row' | 'column';
dragPosition?: DragHandlePosition;
primaryPaneStyles?: React.CSSProperties;
secondaryPaneStyles?: React.CSSProperties;
/**
* Called when ever the size of the primary pane changes
* @param size (float from 0-1)
*/
onSizeChange?: (size: number) => void;
children: [React.ReactNode, React.ReactNode];
}
/**
* Splits two children into two resizable panes
* @alpha
*/
export function Splitter(props: Props) {
const {
direction = 'row',
initialSize = 0.5,
primaryPaneStyles,
secondaryPaneStyles,
onSizeChange,
dragPosition = 'middle',
children,
} = props;
const { containerRef, firstPaneRef, minDimProp, splitterProps, secondPaneRef } = useSplitter(
direction,
onSizeChange,
children
);
const kids = React.Children.toArray(children);
const styles = useStyles2(getStyles, direction);
const dragStyles = useStyles2(getDragStyles, dragPosition);
const dragHandleStyle = direction === 'column' ? dragStyles.dragHandleHorizontal : dragStyles.dragHandleVertical;
const id = useId();
const secondAvailable = kids.length === 2;
const visibilitySecond = secondAvailable ? 'visible' : 'hidden';
let firstChildSize = initialSize;
// If second child is missing let first child have all the space
if (!children[1]) {
firstChildSize = 1;
}
return (
<div ref={containerRef} className={styles.container}>
<div
ref={firstPaneRef}
className={styles.panel}
style={{
flexGrow: clamp(firstChildSize, 0, 1),
[minDimProp]: 'min-content',
...primaryPaneStyles,
}}
id={`start-panel-${id}`}
>
{kids[0]}
</div>
{kids[1] && (
<>
<div
className={dragHandleStyle}
{...splitterProps}
role="separator"
aria-valuemin={0}
aria-valuemax={100}
aria-valuenow={initialSize * 100}
aria-controls={`start-panel-${id}`}
aria-label="Pane resize widget"
// eslint-disable-next-line jsx-a11y/no-noninteractive-tabindex
tabIndex={0}
></div>
<div
ref={secondPaneRef}
className={styles.panel}
style={{
flexGrow: clamp(1 - initialSize, 0, 1),
[minDimProp]: 'min-content',
visibility: `${visibilitySecond}`,
...secondaryPaneStyles,
}}
id={`end-panel-${id}`}
>
{kids[1]}
</div>
</>
)}
</div>
);
}
function getStyles(theme: GrafanaTheme2, direction: Props['direction']) {
return {
container: css({
display: 'flex',
flexDirection: direction === 'row' ? 'row' : 'column',
width: '100%',
flexGrow: 1,
overflow: 'hidden',
}),
panel: css({ display: 'flex', position: 'relative', flexBasis: 0 }),
dragEdge: {
second: css({
top: 0,
left: theme.spacing(-1),
bottom: 0,
position: 'absolute',
zIndex: theme.zIndex.modal,
}),
first: css({
top: 0,
left: theme.spacing(-1),
bottom: 0,
position: 'absolute',
zIndex: theme.zIndex.modal,
}),
},
};
}
const PIXELS_PER_MS = 0.3 as const;
const VERTICAL_KEYS = new Set(['ArrowUp', 'ArrowDown']);
const HORIZONTAL_KEYS = new Set(['ArrowLeft', 'ArrowRight']);
const propsForDirection = {
row: {
dim: 'width',
axis: 'clientX',
min: 'minWidth',
max: 'maxWidth',
},
column: {
dim: 'height',
axis: 'clientY',
min: 'minHeight',
max: 'maxHeight',
},
} as const;
function useSplitter(direction: 'row' | 'column', onSizeChange: Props['onSizeChange'], children: Props['children']) {
const handleSize = 16;
const splitterRef = useRef<HTMLDivElement | null>(null);
const firstPaneRef = useRef<HTMLDivElement | null>(null);
const secondPaneRef = useRef<HTMLDivElement | null>(null);
const containerRef = useRef<HTMLDivElement | null>(null);
const containerSize = useRef<number | null>(null);
const primarySizeRef = useRef<'1fr' | number>('1fr');
const firstPaneMeasurements = useRef<MeasureResult | undefined>(undefined);
const savedPos = useRef<string | undefined>(undefined);
const measurementProp = propsForDirection[direction].dim;
const clientAxis = propsForDirection[direction].axis;
const minDimProp = propsForDirection[direction].min;
const maxDimProp = propsForDirection[direction].max;
// Using a resize observer here, as with content or screen based width/height the ratio between panes might
// change after a window resize, so ariaValueNow needs to be updated accordingly
useResizeObserver(
containerRef.current!,
(entries) => {
for (const entry of entries) {
if (!entry.target.isSameNode(containerRef.current)) {
return;
}
if (!firstPaneRef.current) {
return;
}
const curSize = firstPaneRef.current!.getBoundingClientRect()[measurementProp];
const newDims = measureElement(firstPaneRef.current);
splitterRef.current!.ariaValueNow = `${clamp(
((curSize - newDims[minDimProp]) / (newDims[maxDimProp] - newDims[minDimProp])) * 100,
0,
100
)}`;
}
},
500,
[maxDimProp, minDimProp, direction, measurementProp]
);
const dragStart = useRef<number | null>(null);
const onPointerDown = useCallback(
(e: React.PointerEvent<HTMLDivElement>) => {
if (!firstPaneRef.current) {
return;
}
// measure left-side width
primarySizeRef.current = firstPaneRef.current!.getBoundingClientRect()[measurementProp];
containerSize.current = containerRef.current!.getBoundingClientRect()[measurementProp];
// set position at start of drag
dragStart.current = e[clientAxis];
splitterRef.current!.setPointerCapture(e.pointerId);
firstPaneMeasurements.current = measureElement(firstPaneRef.current);
savedPos.current = undefined;
},
[measurementProp, clientAxis]
);
const onPointerMove = useCallback(
(e: React.PointerEvent<HTMLDivElement>) => {
if (dragStart.current !== null && primarySizeRef.current !== '1fr') {
const diff = e[clientAxis] - dragStart.current;
const dims = firstPaneMeasurements.current!;
const newSize = clamp(primarySizeRef.current + diff, dims[minDimProp], dims[maxDimProp]);
const newFlex = newSize / (containerSize.current! - handleSize);
firstPaneRef.current!.style.flexGrow = `${newFlex}`;
secondPaneRef.current!.style.flexGrow = `${1 - newFlex}`;
const ariaValueNow = clamp(
((newSize - dims[minDimProp]) / (dims[maxDimProp] - dims[minDimProp])) * 100,
0,
100
);
splitterRef.current!.ariaValueNow = `${ariaValueNow}`;
}
},
[handleSize, clientAxis, minDimProp, maxDimProp]
);
const onPointerUp = useCallback(
(e: React.PointerEvent<HTMLDivElement>) => {
e.preventDefault();
e.stopPropagation();
splitterRef.current!.releasePointerCapture(e.pointerId);
dragStart.current = null;
onSizeChange?.(parseFloat(firstPaneRef.current!.style.flexGrow));
},
[onSizeChange]
);
const pressedKeys = useRef(new Set<string>());
const keysLastHandledAt = useRef<number | null>(null);
const handlePressedKeys = useCallback(
(time: number) => {
const nothingPressed = pressedKeys.current.size === 0;
if (nothingPressed) {
keysLastHandledAt.current = null;
return;
} else if (primarySizeRef.current === '1fr') {
return;
}
const dt = time - (keysLastHandledAt.current ?? time);
const dx = dt * PIXELS_PER_MS;
let sizeChange = 0;
if (direction === 'row') {
if (pressedKeys.current.has('ArrowLeft')) {
sizeChange -= dx;
}
if (pressedKeys.current.has('ArrowRight')) {
sizeChange += dx;
}
} else {
if (pressedKeys.current.has('ArrowUp')) {
sizeChange -= dx;
}
if (pressedKeys.current.has('ArrowDown')) {
sizeChange += dx;
}
}
const firstPaneDims = firstPaneMeasurements.current!;
const curSize = firstPaneRef.current!.getBoundingClientRect()[measurementProp];
const newSize = clamp(curSize + sizeChange, firstPaneDims[minDimProp], firstPaneDims[maxDimProp]);
const newFlex = newSize / (containerSize.current! - handleSize);
firstPaneRef.current!.style.flexGrow = `${newFlex}`;
secondPaneRef.current!.style.flexGrow = `${1 - newFlex}`;
const ariaValueNow =
((newSize - firstPaneDims[minDimProp]) / (firstPaneDims[maxDimProp] - firstPaneDims[minDimProp])) * 100;
splitterRef.current!.ariaValueNow = `${clamp(ariaValueNow, 0, 100)}`;
keysLastHandledAt.current = time;
window.requestAnimationFrame(handlePressedKeys);
},
[direction, handleSize, minDimProp, maxDimProp, measurementProp]
);
const onKeyDown = useCallback(
(e: React.KeyboardEvent<HTMLDivElement>) => {
if (!firstPaneRef.current || !secondPaneRef.current || !splitterRef.current || !containerRef.current) {
return;
}
if (e.key === 'Enter') {
if (savedPos.current === undefined) {
savedPos.current = firstPaneRef.current!.style.flexGrow;
firstPaneRef.current!.style.flexGrow = '0';
secondPaneRef.current!.style.flexGrow = '1';
} else {
firstPaneRef.current!.style.flexGrow = savedPos.current;
secondPaneRef.current!.style.flexGrow = `${1 - parseFloat(savedPos.current)}`;
savedPos.current = undefined;
}
return;
} else if (e.key === 'Home') {
firstPaneMeasurements.current = measureElement(firstPaneRef.current);
containerSize.current = containerRef.current!.getBoundingClientRect()[measurementProp];
const newFlex = firstPaneMeasurements.current[minDimProp] / (containerSize.current - handleSize);
firstPaneRef.current.style.flexGrow = `${newFlex}`;
secondPaneRef.current.style.flexGrow = `${1 - newFlex}`;
splitterRef.current.ariaValueNow = '0';
return;
} else if (e.key === 'End') {
firstPaneMeasurements.current = measureElement(firstPaneRef.current);
containerSize.current = containerRef.current!.getBoundingClientRect()[measurementProp];
const newFlex = firstPaneMeasurements.current[maxDimProp] / (containerSize.current - handleSize);
firstPaneRef.current!.style.flexGrow = `${newFlex}`;
secondPaneRef.current!.style.flexGrow = `${1 - newFlex}`;
splitterRef.current!.ariaValueNow = '100';
return;
}
if (
!(
(direction === 'column' && VERTICAL_KEYS.has(e.key)) ||
(direction === 'row' && HORIZONTAL_KEYS.has(e.key))
) ||
pressedKeys.current.has(e.key)
) {
return;
}
savedPos.current = undefined;
e.preventDefault();
e.stopPropagation();
primarySizeRef.current = firstPaneRef.current.getBoundingClientRect()[measurementProp];
containerSize.current = containerRef.current!.getBoundingClientRect()[measurementProp];
firstPaneMeasurements.current = measureElement(firstPaneRef.current);
const newKey = !pressedKeys.current.has(e.key);
if (newKey) {
const initiateAnimationLoop = pressedKeys.current.size === 0;
pressedKeys.current.add(e.key);
if (initiateAnimationLoop) {
window.requestAnimationFrame(handlePressedKeys);
}
}
},
[direction, handlePressedKeys, handleSize, maxDimProp, measurementProp, minDimProp]
);
const onKeyUp = useCallback(
(e: React.KeyboardEvent<HTMLDivElement>) => {
if (
(direction === 'row' && !HORIZONTAL_KEYS.has(e.key)) ||
(direction === 'column' && !VERTICAL_KEYS.has(e.key))
) {
return;
}
pressedKeys.current.delete(e.key);
onSizeChange?.(parseFloat(firstPaneRef.current!.style.flexGrow));
},
[direction, onSizeChange]
);
const onDoubleClick = useCallback(() => {
if (!firstPaneRef.current || !secondPaneRef.current) {
return;
}
firstPaneRef.current.style.flexGrow = '0.5';
secondPaneRef.current.style.flexGrow = '0.5';
const dim = measureElement(firstPaneRef.current);
firstPaneMeasurements.current = dim;
primarySizeRef.current = firstPaneRef.current!.getBoundingClientRect()[measurementProp];
splitterRef.current!.ariaValueNow = `${((primarySizeRef.current - dim[minDimProp]) / (dim[maxDimProp] - dim[minDimProp])) * 100}`;
}, [maxDimProp, measurementProp, minDimProp]);
const onBlur = useCallback(() => {
// If focus is lost while keys are held, stop changing panel sizes
if (pressedKeys.current.size > 0) {
pressedKeys.current.clear();
dragStart.current = null;
onSizeChange?.(parseFloat(firstPaneRef.current!.style.flexGrow));
}
}, [onSizeChange]);
return {
containerRef,
firstPaneRef,
minDimProp,
splitterProps: {
onPointerUp,
onPointerDown,
onPointerMove,
onKeyDown,
onKeyUp,
onDoubleClick,
onBlur,
ref: splitterRef,
style: { [measurementProp]: `${handleSize}px` },
},
secondPaneRef,
};
}
interface MeasureResult {
minWidth: number;
maxWidth: number;
minHeight: number;
maxHeight: number;
}
function measureElement<T extends HTMLElement>(ref: T): MeasureResult {
const savedBodyOverflow = document.body.style.overflow;
const savedWidth = ref.style.width;
const savedHeight = ref.style.height;
const savedFlex = ref.style.flexGrow;
document.body.style.overflow = 'hidden';
ref.style.flexGrow = '0';
const { width: minWidth, height: minHeight } = ref.getBoundingClientRect();
ref.style.flexGrow = '100';
const { width: maxWidth, height: maxHeight } = ref.getBoundingClientRect();
document.body.style.overflow = savedBodyOverflow;
ref.style.width = savedWidth;
ref.style.height = savedHeight;
ref.style.flexGrow = savedFlex;
return { minWidth, maxWidth, minHeight, maxHeight } as MeasureResult;
}
function useResizeObserver(
target: Element,
cb: (entries: ResizeObserverEntry[]) => void,
throttleWait = 0,
deps?: React.DependencyList
) {
const throttledCallback = throttle(cb, throttleWait);
useLayoutEffect(() => {
if (!target) {
return;
}
const resizeObserver = new ResizeObserver(throttledCallback);
resizeObserver.observe(target, { box: 'device-pixel-content-box' });
return () => resizeObserver.disconnect();
// eslint-disable-next-line react-hooks/exhaustive-deps
}, deps);
}
@@ -265,6 +265,7 @@ export { Avatar } from './UsersIndicator/Avatar';
export { InlineFormLabel } from './FormLabel/FormLabel';
export { Divider } from './Divider/Divider';
export { getDragStyles } from './DragHandle/DragHandle';
export { Splitter } from './Splitter/Splitter';
export { LayoutItemContext, type LayoutItemContextProps } from './Layout/LayoutItemContext';
+30 -28
View File
@@ -143,6 +143,7 @@ func TestFinder_Find(t *testing.T) {
{Name: "img1", Path: "img/screenshot1.png"},
{Name: "img2", Path: "img/screenshot2.png"},
},
Keywords: []string{"test"},
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "3.x.x",
@@ -176,40 +177,19 @@ func TestFinder_Find(t *testing.T) {
{
name: "Multiple plugin dirs",
pluginDirs: []string{"../../testdata/duplicate-plugins", "../../testdata/invalid-v1-signature"},
expectedBundles: []*plugins.FoundBundle{{
Primary: plugins.FoundPlugin{
JSONData: plugins.JSONData{
ID: "test-app",
Type: plugins.TypeDataSource,
Name: "Parent",
Info: plugins.Info{
Author: plugins.InfoLink{
Name: "Grafana Labs",
URL: "http://grafana.com",
},
Description: "Parent plugin",
Version: "1.0.0",
Updated: "2020-10-20",
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "*",
Plugins: []plugins.Dependency{},
},
},
FS: mustNewStaticFSForTests(t, filepath.Join(testData, "duplicate-plugins/nested")),
},
Children: []*plugins.FoundPlugin{
{
expectedBundles: []*plugins.FoundBundle{
{
Primary: plugins.FoundPlugin{
JSONData: plugins.JSONData{
ID: "test-app",
Type: plugins.TypeDataSource,
Name: "Child",
Name: "Parent",
Info: plugins.Info{
Author: plugins.InfoLink{
Name: "Grafana Labs",
URL: "http://grafana.com",
},
Description: "Child plugin",
Description: "Parent plugin",
Version: "1.0.0",
Updated: "2020-10-20",
},
@@ -218,10 +198,32 @@ func TestFinder_Find(t *testing.T) {
Plugins: []plugins.Dependency{},
},
},
FS: mustNewStaticFSForTests(t, filepath.Join(testData, "duplicate-plugins/nested/nested")),
FS: mustNewStaticFSForTests(t, filepath.Join(testData, "duplicate-plugins/nested")),
},
Children: []*plugins.FoundPlugin{
{
JSONData: plugins.JSONData{
ID: "test-app",
Type: plugins.TypeDataSource,
Name: "Child",
Info: plugins.Info{
Author: plugins.InfoLink{
Name: "Grafana Labs",
URL: "http://grafana.com",
},
Description: "Child plugin",
Version: "1.0.0",
Updated: "2020-10-20",
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "*",
Plugins: []plugins.Dependency{},
},
},
FS: mustNewStaticFSForTests(t, filepath.Join(testData, "duplicate-plugins/nested/nested")),
},
},
},
},
{
Primary: plugins.FoundPlugin{
JSONData: plugins.JSONData{
+11 -6
View File
@@ -154,7 +154,8 @@ func TestLoader_Load(t *testing.T) {
Class: plugins.ClassBundled,
},
},
}, {
},
{
name: "Load plugin with symbolic links",
class: plugins.ClassExternal,
cfg: &config.Cfg{Features: featuremgmt.WithFeatures()},
@@ -183,8 +184,9 @@ func TestLoader_Load(t *testing.T) {
{Path: "public/plugins/test-app/img/screenshot1.png", Name: "img1"},
{Path: "public/plugins/test-app/img/screenshot2.png", Name: "img2"},
},
Version: "1.0.0",
Updated: "2015-02-10",
Version: "1.0.0",
Updated: "2015-02-10",
Keywords: []string{"test"},
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "3.x.x",
@@ -212,7 +214,8 @@ func TestLoader_Load(t *testing.T) {
Name: "Nginx Panel",
Type: string(plugins.TypePanel),
Role: org.RoleViewer,
Slug: "nginx-panel"},
Slug: "nginx-panel",
},
{
Name: "Nginx Datasource",
Type: string(plugins.TypeDataSource),
@@ -230,7 +233,8 @@ func TestLoader_Load(t *testing.T) {
SignatureOrg: "Grafana Labs",
},
},
}, {
},
{
name: "Load an unsigned plugin (development)",
class: plugins.ClassExternal,
cfg: &config.Cfg{
@@ -383,7 +387,8 @@ func TestLoader_Load(t *testing.T) {
Small: "public/img/icn-app.svg",
Large: "public/img/icn-app.svg",
},
Updated: "2015-02-10",
Updated: "2015-02-10",
Keywords: []string{"test"},
},
Dependencies: plugins.Dependencies{
GrafanaDependency: ">=8.0.0",
+1
View File
@@ -130,6 +130,7 @@ type Info struct {
Screenshots []Screenshots `json:"screenshots"`
Version string `json:"version"`
Updated string `json:"updated"`
Keywords []string `json:"keywords"`
}
type InfoLink struct {
+3 -2
View File
@@ -49,7 +49,8 @@ func Test_ReadPluginJSON(t *testing.T) {
{Path: "img/screenshot1.png", Name: "img1"},
{Path: "img/screenshot2.png", Name: "img2"},
},
Updated: "2015-02-10",
Updated: "2015-02-10",
Keywords: []string{"test"},
},
Dependencies: Dependencies{
GrafanaVersion: "3.x.x",
@@ -107,7 +108,7 @@ func Test_ReadPluginJSON(t *testing.T) {
pluginJSON: func(t *testing.T) io.ReadCloser {
pJSON := `{
"id": "grafana-pyroscope-datasource",
"type": "datasource",
"type": "datasource",
"aliasIDs": ["phlare"]
}`
return io.NopCloser(strings.NewReader(pJSON))
@@ -19,6 +19,7 @@ import (
const GrafanaRequestID = "X-Grafana-Request-Id"
const GrafanaSignedRequestID = "X-Grafana-Signed-Request-Id"
const XRealIPHeader = "X-Real-Ip"
const GrafanaInternalRequest = "X-Grafana-Internal-Request"
// NewHostedGrafanaACHeaderMiddleware creates a new plugins.ClientMiddleware that will
@@ -83,6 +84,7 @@ func (m *HostedGrafanaACHeaderMiddleware) applyGrafanaRequestIDHeader(ctx contex
if reqCtx != nil && reqCtx.Req != nil {
remoteAddress := web.RemoteAddr(reqCtx.Req)
if remoteAddress != "" {
h.SetHTTPHeader(XRealIPHeader, remoteAddress)
return
}
}
@@ -54,6 +54,9 @@ func Test_HostedGrafanaACHeaderMiddleware(t *testing.T) {
require.Equal(t, cdt.CallResourceReq.Headers[GrafanaSignedRequestID][0], computed)
require.Len(t, cdt.CallResourceReq.Headers[XRealIPHeader], 1)
require.Equal(t, cdt.CallResourceReq.Headers[XRealIPHeader][0], "1.2.3.4")
// Internal header should not be set
require.Len(t, cdt.CallResourceReq.Headers[GrafanaInternalRequest], 0)
})
@@ -154,7 +154,8 @@ func TestLoader_Load(t *testing.T) {
Class: plugins.ClassBundled,
},
},
}, {
},
{
name: "Load plugin with symbolic links",
class: plugins.ClassExternal,
cfg: &config.Cfg{Features: featuremgmt.WithFeatures()},
@@ -183,8 +184,9 @@ func TestLoader_Load(t *testing.T) {
{Path: "public/plugins/test-app/img/screenshot1.png", Name: "img1"},
{Path: "public/plugins/test-app/img/screenshot2.png", Name: "img2"},
},
Version: "1.0.0",
Updated: "2015-02-10",
Version: "1.0.0",
Updated: "2015-02-10",
Keywords: []string{"test"},
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "3.x.x",
@@ -212,7 +214,8 @@ func TestLoader_Load(t *testing.T) {
Name: "Nginx Panel",
Type: string(plugins.TypePanel),
Role: org.RoleViewer,
Slug: "nginx-panel"},
Slug: "nginx-panel",
},
{
Name: "Nginx Datasource",
Type: string(plugins.TypeDataSource),
@@ -230,7 +233,8 @@ func TestLoader_Load(t *testing.T) {
SignatureOrg: "Grafana Labs",
},
},
}, {
},
{
name: "Load an unsigned plugin (development)",
class: plugins.ClassExternal,
cfg: &config.Cfg{
@@ -269,7 +273,8 @@ func TestLoader_Load(t *testing.T) {
Signature: "unsigned",
},
},
}, {
},
{
name: "Load an unsigned plugin (production)",
class: plugins.ClassExternal,
cfg: &config.Cfg{Features: featuremgmt.WithFeatures()},
@@ -392,38 +397,40 @@ func TestLoader_Load(t *testing.T) {
},
pluginPaths: []string{filepath.Join(testDataDir(t), "test-app-with-includes")},
want: []*plugins.Plugin{
{JSONData: plugins.JSONData{
ID: "test-app",
Type: plugins.TypeApp,
Name: "Test App",
Info: plugins.Info{
Author: plugins.InfoLink{
Name: "Test Inc.",
URL: "http://test.com",
{
JSONData: plugins.JSONData{
ID: "test-app",
Type: plugins.TypeApp,
Name: "Test App",
Info: plugins.Info{
Author: plugins.InfoLink{
Name: "Test Inc.",
URL: "http://test.com",
},
Description: "Official Grafana Test App & Dashboard bundle",
Version: "1.0.0",
Links: []plugins.InfoLink{
{Name: "Project site", URL: "http://project.com"},
{Name: "License & Terms", URL: "http://license.com"},
},
Logos: plugins.Logos{
Small: "public/img/icn-app.svg",
Large: "public/img/icn-app.svg",
},
Updated: "2015-02-10",
Keywords: []string{"test"},
},
Description: "Official Grafana Test App & Dashboard bundle",
Version: "1.0.0",
Links: []plugins.InfoLink{
{Name: "Project site", URL: "http://project.com"},
{Name: "License & Terms", URL: "http://license.com"},
Dependencies: plugins.Dependencies{
GrafanaDependency: ">=8.0.0",
GrafanaVersion: "*",
Plugins: []plugins.Dependency{},
},
Logos: plugins.Logos{
Small: "public/img/icn-app.svg",
Large: "public/img/icn-app.svg",
Includes: []*plugins.Includes{
{Name: "Nginx Memory", Path: "dashboards/memory.json", Type: "dashboard", Role: org.RoleViewer, Slug: "nginx-memory"},
{Name: "Root Page (react)", Type: "page", Role: org.RoleViewer, Path: "/a/my-simple-app", DefaultNav: true, AddToNav: true, Slug: "root-page-react"},
},
Updated: "2015-02-10",
Backend: false,
},
Dependencies: plugins.Dependencies{
GrafanaDependency: ">=8.0.0",
GrafanaVersion: "*",
Plugins: []plugins.Dependency{},
},
Includes: []*plugins.Includes{
{Name: "Nginx Memory", Path: "dashboards/memory.json", Type: "dashboard", Role: org.RoleViewer, Slug: "nginx-memory"},
{Name: "Root Page (react)", Type: "page", Role: org.RoleViewer, Path: "/a/my-simple-app", DefaultNav: true, AddToNav: true, Slug: "root-page-react"},
},
Backend: false,
},
DefaultNavURL: "/plugins/test-app/page/root-page-react",
FS: mustNewStaticFSForTests(t, filepath.Join(testDataDir(t), "test-app-with-includes")),
Class: plugins.ClassExternal,
@@ -570,10 +577,12 @@ func TestLoader_Load_ExternalRegistration(t *testing.T) {
backendFactoryProvider.BackendFactoryFunc = func(ctx context.Context, plugin *plugins.Plugin) backendplugin.PluginFactoryFunc {
return func(pluginID string, logger log.Logger, env func() []string) (backendplugin.Plugin, error) {
require.Equal(t, "grafana-test-datasource", pluginID)
require.Equal(t, []string{"GF_VERSION=", "GF_EDITION=", "GF_ENTERPRISE_LICENSE_PATH=",
require.Equal(t, []string{
"GF_VERSION=", "GF_EDITION=", "GF_ENTERPRISE_LICENSE_PATH=",
"GF_ENTERPRISE_APP_URL=", "GF_ENTERPRISE_LICENSE_TEXT=", "GF_APP_URL=",
"GF_PLUGIN_APP_CLIENT_ID=client-id", "GF_PLUGIN_APP_CLIENT_SECRET=secretz",
"GF_PLUGIN_APP_PRIVATE_KEY=priv@t3", "GF_INSTANCE_FEATURE_TOGGLES_ENABLE=externalServiceAuth"}, env())
"GF_PLUGIN_APP_PRIVATE_KEY=priv@t3", "GF_INSTANCE_FEATURE_TOGGLES_ENABLE=externalServiceAuth",
}, env())
return &fakes.FakeBackendPlugin{}, nil
}
}
@@ -614,38 +623,39 @@ func TestLoader_Load_ExternalRegistration(t *testing.T) {
}
pluginPaths := []string{filepath.Join(testDataDir(t), "external-registration")}
expected := []*plugins.Plugin{
{JSONData: plugins.JSONData{
ID: "grafana-test-datasource",
Type: plugins.TypeDataSource,
Name: "Test",
Backend: true,
Executable: "gpx_test_datasource",
Info: plugins.Info{
Author: plugins.InfoLink{
Name: "Grafana Labs",
URL: "https://grafana.com",
{
JSONData: plugins.JSONData{
ID: "grafana-test-datasource",
Type: plugins.TypeDataSource,
Name: "Test",
Backend: true,
Executable: "gpx_test_datasource",
Info: plugins.Info{
Author: plugins.InfoLink{
Name: "Grafana Labs",
URL: "https://grafana.com",
},
Version: "1.0.0",
Logos: plugins.Logos{
Small: "public/plugins/grafana-test-datasource/img/ds.svg",
Large: "public/plugins/grafana-test-datasource/img/ds.svg",
},
Updated: "2023-08-03",
Screenshots: []plugins.Screenshots{},
},
Version: "1.0.0",
Logos: plugins.Logos{
Small: "public/plugins/grafana-test-datasource/img/ds.svg",
Large: "public/plugins/grafana-test-datasource/img/ds.svg",
Dependencies: plugins.Dependencies{
GrafanaVersion: "*",
Plugins: []plugins.Dependency{},
},
Updated: "2023-08-03",
Screenshots: []plugins.Screenshots{},
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "*",
Plugins: []plugins.Dependency{},
},
IAM: &plugindef.IAM{
Permissions: []plugindef.Permission{
{
Action: "read",
Scope: stringPtr("datasource"),
IAM: &plugindef.IAM{
Permissions: []plugindef.Permission{
{
Action: "read",
Scope: stringPtr("datasource"),
},
},
},
},
},
FS: mustNewStaticFSForTests(t, pluginPaths[0]),
Class: plugins.ClassExternal,
Signature: plugins.SignatureStatusUnsigned,
@@ -662,10 +672,12 @@ func TestLoader_Load_ExternalRegistration(t *testing.T) {
backendFactoryProvider.BackendFactoryFunc = func(ctx context.Context, plugin *plugins.Plugin) backendplugin.PluginFactoryFunc {
return func(pluginID string, logger log.Logger, env func() []string) (backendplugin.Plugin, error) {
require.Equal(t, "grafana-test-datasource", pluginID)
require.Equal(t, []string{"GF_VERSION=", "GF_EDITION=", "GF_ENTERPRISE_LICENSE_PATH=",
require.Equal(t, []string{
"GF_VERSION=", "GF_EDITION=", "GF_ENTERPRISE_LICENSE_PATH=",
"GF_ENTERPRISE_APP_URL=", "GF_ENTERPRISE_LICENSE_TEXT=", "GF_APP_URL=",
"GF_PLUGIN_APP_CLIENT_ID=client-id", "GF_PLUGIN_APP_CLIENT_SECRET=secretz",
"GF_INSTANCE_FEATURE_TOGGLES_ENABLE=externalServiceAuth"}, env())
"GF_INSTANCE_FEATURE_TOGGLES_ENABLE=externalServiceAuth",
}, env())
return &fakes.FakeBackendPlugin{}, nil
}
}
@@ -906,7 +918,8 @@ func TestLoader_Load_RBACReady(t *testing.T) {
Small: "public/img/icn-app.svg",
Large: "public/img/icn-app.svg",
},
Updated: "2015-02-10",
Updated: "2015-02-10",
Keywords: []string{"test"},
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "*",
@@ -1049,7 +1062,8 @@ func TestLoader_Load_DuplicatePlugins(t *testing.T) {
{Path: "public/plugins/test-app/img/screenshot1.png", Name: "img1"},
{Path: "public/plugins/test-app/img/screenshot2.png", Name: "img2"},
},
Updated: "2015-02-10",
Updated: "2015-02-10",
Keywords: []string{"test"},
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "3.x.x",
@@ -1129,7 +1143,8 @@ func TestLoader_Load_SkipUninitializedPlugins(t *testing.T) {
{Path: "public/plugins/test-app/img/screenshot1.png", Name: "img1"},
{Path: "public/plugins/test-app/img/screenshot2.png", Name: "img2"},
},
Updated: "2015-02-10",
Updated: "2015-02-10",
Keywords: []string{"test"},
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "3.x.x",
@@ -1476,6 +1491,7 @@ func TestLoader_Load_NestedPlugins(t *testing.T) {
Description: "Grafana App Plugin Template",
Version: "",
Updated: "",
Keywords: []string{"panel", "template"},
},
Dependencies: plugins.Dependencies{
GrafanaVersion: "7.0.0",
@@ -1556,6 +1572,7 @@ func TestLoader_Load_NestedPlugins(t *testing.T) {
Description: "Grafana Panel Plugin Template",
Version: "",
Updated: "",
Keywords: []string{"panel", "template"},
},
Dependencies: plugins.Dependencies{
GrafanaDependency: ">=7.0.0",
@@ -1612,7 +1629,8 @@ type loaderDepOpts struct {
}
func newLoader(t *testing.T, cfg *config.Cfg, reg registry.Service, proc process.Manager,
backendFactory plugins.BackendFactoryProvider, sigErrTracker pluginerrs.SignatureErrorTracker) *Loader {
backendFactory plugins.BackendFactoryProvider, sigErrTracker pluginerrs.SignatureErrorTracker,
) *Loader {
assets := assetpath.ProvideService(cfg, pluginscdn.ProvideService(cfg))
lic := fakes.NewFakeLicensingService()
angularInspector := angularinspector.NewStaticInspector()
@@ -1662,7 +1680,8 @@ func newLoaderWithOpts(t *testing.T, cfg *config.Cfg, opts loaderDepOpts) *Loade
}
func verifyState(t *testing.T, ps []*plugins.Plugin, reg registry.Service,
procPrvdr *fakes.FakeBackendProcessProvider, procMngr *fakes.FakeProcessManager) {
procPrvdr *fakes.FakeBackendProcessProvider, procMngr *fakes.FakeProcessManager,
) {
t.Helper()
for _, p := range ps {
+119 -49
View File
@@ -19,7 +19,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -61,7 +62,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -98,7 +100,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -157,7 +160,14 @@
}
],
"version": "",
"updated": ""
"updated": "",
"keywords": [
"azure",
"monitor",
"Application Insights",
"Log Analytics",
"App Insights"
]
},
"dependencies": {
"grafanaDependency": "\u003e=10.3.0",
@@ -194,7 +204,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -231,7 +242,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -268,7 +280,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -305,7 +318,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -342,7 +356,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -379,7 +394,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -416,7 +432,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -458,7 +475,10 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": [
"elasticsearch"
]
},
"dependencies": {
"grafanaDependency": "",
@@ -495,7 +515,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -532,7 +553,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -569,7 +591,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -606,7 +629,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -643,7 +667,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -685,7 +710,16 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": [
"grafana",
"datasource",
"phlare",
"flamegraph",
"profiling",
"continuous profiling",
"pyroscope"
]
},
"dependencies": {
"grafanaDependency": "\u003e=10.3.0-0",
@@ -722,7 +756,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -768,7 +803,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -805,7 +841,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -842,7 +879,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -879,7 +917,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -925,7 +964,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -962,7 +1002,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1008,7 +1049,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1045,7 +1087,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1082,7 +1125,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1119,7 +1163,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1156,7 +1201,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1193,7 +1239,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1235,7 +1282,13 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": [
"grafana",
"datasource",
"parca",
"profiling"
]
},
"dependencies": {
"grafanaDependency": "\u003e=10.3.0-0",
@@ -1272,7 +1325,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1309,7 +1363,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1351,7 +1406,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1388,7 +1444,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1425,7 +1482,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1462,7 +1520,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1499,7 +1558,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1536,7 +1596,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1578,7 +1639,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "\u003e=10.3.0-0",
@@ -1615,7 +1677,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "\u003e=10.3.0-0",
@@ -1652,7 +1715,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1689,7 +1753,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1726,7 +1791,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1763,7 +1829,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1800,7 +1867,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1837,7 +1905,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -1879,7 +1948,8 @@
"build": {},
"screenshots": null,
"version": "",
"updated": ""
"updated": "",
"keywords": null
},
"dependencies": {
"grafanaDependency": "",
@@ -13,7 +13,6 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend"
"github.com/grafana/grafana-plugin-sdk-go/backend/datasource"
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
sdkproxy "github.com/grafana/grafana-plugin-sdk-go/backend/proxy"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana-plugin-sdk-go/data/sqlutil"
"github.com/lib/pq"
@@ -21,7 +20,6 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend/log"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb/sqleng"
"github.com/grafana/grafana/pkg/tsdb/sqleng/proxyutil"
)
func ProvideService(cfg *setting.Cfg) *Service {
@@ -57,23 +55,28 @@ func (s *Service) QueryData(ctx context.Context, req *backend.QueryDataRequest)
return dsInfo.QueryData(ctx, req)
}
func newPostgres(cfg *setting.Cfg, dsInfo sqleng.DataSourceInfo, cnnstr string, logger log.Logger, settings backend.DataSourceInstanceSettings) (*sql.DB, *sqleng.DataSourceHandler, error) {
func newPostgres(ctx context.Context, cfg *setting.Cfg, dsInfo sqleng.DataSourceInfo, cnnstr string, logger log.Logger, settings backend.DataSourceInstanceSettings) (*sql.DB, *sqleng.DataSourceHandler, error) {
connector, err := pq.NewConnector(cnnstr)
if err != nil {
logger.Error("postgres connector creation failed", "error", err)
return nil, nil, fmt.Errorf("postgres connector creation failed")
}
// use the proxy-dialer if the secure socks proxy is enabled
proxyOpts := proxyutil.GetSQLProxyOptions(cfg.SecureSocksDSProxy, dsInfo, settings.Name, settings.Type)
if sdkproxy.New(proxyOpts).SecureSocksProxyEnabled() {
dialer, err := newPostgresProxyDialer(proxyOpts)
proxyClient, err := settings.ProxyClient(ctx)
if err != nil {
logger.Error("postgres proxy creation failed", "error", err)
return nil, nil, fmt.Errorf("postgres proxy creation failed")
}
if proxyClient.SecureSocksProxyEnabled() {
dialer, err := proxyClient.NewSecureSocksProxyContextDialer()
if err != nil {
logger.Error("postgres proxy creation failed", "error", err)
return nil, nil, fmt.Errorf("postgres proxy creation failed")
}
postgresDialer := newPostgresProxyDialer(dialer)
// update the postgres dialer with the proxy dialer
connector.Dialer(dialer)
connector.Dialer(postgresDialer)
}
config := sqleng.DataPluginConfiguration{
@@ -103,7 +106,7 @@ func newPostgres(cfg *setting.Cfg, dsInfo sqleng.DataSourceInfo, cnnstr string,
func (s *Service) newInstanceSettings(cfg *setting.Cfg) datasource.InstanceFactoryFunc {
logger := s.logger
return func(_ context.Context, settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) {
return func(ctx context.Context, settings backend.DataSourceInstanceSettings) (instancemgmt.Instance, error) {
logger.Debug("Creating Postgres query endpoint")
jsonData := sqleng.JsonData{
MaxOpenConns: cfg.SqlDatasourceMaxOpenConnsDefault,
@@ -140,7 +143,7 @@ func (s *Service) newInstanceSettings(cfg *setting.Cfg) datasource.InstanceFacto
return nil, err
}
_, handler, err := newPostgres(cfg, dsInfo, cnnstr, logger, settings)
_, handler, err := newPostgres(ctx, cfg, dsInfo, cnnstr, logger, settings)
if err != nil {
logger.Error("Failed connecting to Postgres", "err", err)
@@ -164,7 +164,7 @@ func TestIntegrationPostgresSnapshots(t *testing.T) {
cnnstr := getCnnStr()
db, handler, err := newPostgres(cfg, dsInfo, cnnstr, logger, backend.DataSourceInstanceSettings{})
db, handler, err := newPostgres(context.Background(), cfg, dsInfo, cnnstr, logger, backend.DataSourceInstanceSettings{})
t.Cleanup((func() {
_, err := db.Exec("DROP TABLE tbl")
@@ -212,7 +212,7 @@ func TestIntegrationPostgres(t *testing.T) {
cnnstr := postgresTestDBConnString()
db, exe, err := newPostgres(cfg, dsInfo, cnnstr, logger, backend.DataSourceInstanceSettings{})
db, exe, err := newPostgres(context.Background(), cfg, dsInfo, cnnstr, logger, backend.DataSourceInstanceSettings{})
require.NoError(t, err)
@@ -1268,7 +1268,7 @@ func TestIntegrationPostgres(t *testing.T) {
dsInfo := sqleng.DataSourceInfo{}
conf := setting.NewCfg()
conf.DataProxyRowLimit = 1
_, handler, err := newPostgres(conf, dsInfo, cnnstr, logger, backend.DataSourceInstanceSettings{})
_, handler, err := newPostgres(context.Background(), conf, dsInfo, cnnstr, logger, backend.DataSourceInstanceSettings{})
require.NoError(t, err)
@@ -5,21 +5,13 @@ import (
"net"
"time"
sdkproxy "github.com/grafana/grafana-plugin-sdk-go/backend/proxy"
"github.com/lib/pq"
"golang.org/x/net/proxy"
)
// newPostgresProxyDriver updates the dialer for a postgres connector with a dialer that proxies connections through the secure socks proxy
// and returns a new postgres driver to register
func newPostgresProxyDialer(opts *sdkproxy.Options) (pq.Dialer, error) {
dialer, err := sdkproxy.New(opts).NewSecureSocksProxyContextDialer()
if err != nil {
return nil, err
}
// update the postgres dialer with the proxy dialer
return &postgresProxyDialer{d: dialer}, nil
// we wrap the proxy.Dialer to become dialer that the postgres module accepts
func newPostgresProxyDialer(dialer proxy.Dialer) pq.Dialer {
return &postgresProxyDialer{d: dialer}
}
var _ pq.Dialer = (&postgresProxyDialer{})
@@ -3,40 +3,37 @@ package postgres
import (
"database/sql"
"fmt"
"net"
"testing"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb/sqleng"
"github.com/grafana/grafana/pkg/tsdb/sqleng/proxyutil"
"github.com/lib/pq"
"github.com/stretchr/testify/require"
"golang.org/x/net/proxy"
)
type testDialer struct {
}
func (d *testDialer) Dial(network, addr string) (c net.Conn, err error) {
return nil, fmt.Errorf("test-dialer is not functional")
}
var _ proxy.Dialer = (&testDialer{})
func TestPostgresProxyDriver(t *testing.T) {
settings := proxyutil.SetupTestSecureSocksProxySettings(t)
proxySettings := setting.SecureSocksDSProxySettings{
Enabled: true,
ClientCert: settings.ClientCert,
ClientKey: settings.ClientKey,
RootCA: settings.RootCA,
ProxyAddress: settings.ProxyAddress,
ServerName: settings.ServerName,
}
opts := proxyutil.GetSQLProxyOptions(proxySettings, sqleng.DataSourceInfo{UID: "1", JsonData: sqleng.JsonData{SecureDSProxy: true}}, "pg", "postgres")
dbURL := "localhost:5432"
cnnstr := fmt.Sprintf("postgres://auser:password@%s/db?sslmode=disable", dbURL)
t.Run("Connector should use dialer context that routes through the socks proxy to db", func(t *testing.T) {
connector, err := pq.NewConnector(cnnstr)
require.NoError(t, err)
dialer, err := newPostgresProxyDialer(opts)
require.NoError(t, err)
dialer := newPostgresProxyDialer(&testDialer{})
connector.Dialer(dialer)
db := sql.OpenDB(connector)
err = db.Ping()
require.Contains(t, err.Error(), fmt.Sprintf("socks connect %s %s->%s", "tcp", settings.ProxyAddress, dbURL))
require.Contains(t, err.Error(), "test-dialer is not functional")
})
}
+11 -5
View File
@@ -18,7 +18,6 @@ import (
"github.com/grafana/grafana-plugin-sdk-go/backend/datasource"
sdkhttpclient "github.com/grafana/grafana-plugin-sdk-go/backend/httpclient"
"github.com/grafana/grafana-plugin-sdk-go/backend/instancemgmt"
sdkproxy "github.com/grafana/grafana-plugin-sdk-go/backend/proxy"
"github.com/grafana/grafana-plugin-sdk-go/data"
"github.com/grafana/grafana-plugin-sdk-go/data/sqlutil"
@@ -26,7 +25,6 @@ import (
"github.com/grafana/grafana/pkg/infra/httpclient"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb/sqleng"
"github.com/grafana/grafana/pkg/tsdb/sqleng/proxyutil"
)
const (
@@ -89,12 +87,20 @@ func newInstanceSettings(cfg *setting.Cfg, logger log.Logger) datasource.Instanc
protocol = "unix"
}
proxyClient, err := settings.ProxyClient(ctx)
if err != nil {
return nil, err
}
// register the secure socks proxy dialer context, if enabled
proxyOpts := proxyutil.GetSQLProxyOptions(cfg.SecureSocksDSProxy, dsInfo, settings.Name, settings.Type)
if sdkproxy.New(proxyOpts).SecureSocksProxyEnabled() {
if proxyClient.SecureSocksProxyEnabled() {
dialer, err := proxyClient.NewSecureSocksProxyContextDialer()
if err != nil {
return nil, err
}
// UID is only unique per org, the only way to ensure uniqueness is to do it by connection information
uniqueIdentifier := dsInfo.User + dsInfo.DecryptedSecureJSONData["password"] + dsInfo.URL + dsInfo.Database
protocol, err = registerProxyDialerContext(protocol, uniqueIdentifier, proxyOpts)
protocol, err = registerProxyDialerContext(protocol, uniqueIdentifier, dialer)
if err != nil {
return nil, err
}
+6 -11
View File
@@ -7,15 +7,14 @@ import (
"net"
"github.com/go-sql-driver/mysql"
sdkproxy "github.com/grafana/grafana-plugin-sdk-go/backend/proxy"
"golang.org/x/net/proxy"
)
// registerProxyDialerContext registers a new dialer context to be used by mysql when the proxy network is
// specified in the connection string
func registerProxyDialerContext(protocol, cnnstr string, opts *sdkproxy.Options) (string, error) {
// the dialer contains the true network used behind the scenes
dialer, err := getProxyDialerContext(protocol, opts)
func registerProxyDialerContext(protocol, cnnstr string, dialer proxy.Dialer) (string, error) {
// the mysqlDialer contains the true network used behind the scenes
mysqlDialer, err := getProxyDialerContext(protocol, dialer)
if err != nil {
return "", err
}
@@ -24,7 +23,7 @@ func registerProxyDialerContext(protocol, cnnstr string, opts *sdkproxy.Options)
// have a unique network per connection string
hash := fmt.Sprintf("%x", md5.Sum([]byte(cnnstr)))
network := "proxy-" + hash
mysql.RegisterDialContext(network, dialer.DialContext)
mysql.RegisterDialContext(network, mysqlDialer.DialContext)
return network, nil
}
@@ -36,14 +35,10 @@ type mySQLContextDialer struct {
}
// getProxyDialerContext returns a context dialer that will send the request through to the secure socks proxy
func getProxyDialerContext(actualNetwork string, opts *sdkproxy.Options) (*mySQLContextDialer, error) {
dialer, err := sdkproxy.New(opts).NewSecureSocksProxyContextDialer()
if err != nil {
return nil, err
}
func getProxyDialerContext(actualNetwork string, dialer proxy.Dialer) (*mySQLContextDialer, error) {
contextDialer, ok := dialer.(proxy.ContextDialer)
if !ok {
return nil, err
return nil, fmt.Errorf("mysql proxy creation failed")
}
return &mySQLContextDialer{dialer: contextDialer, network: actualNetwork}, nil
}
+19 -16
View File
@@ -3,29 +3,32 @@ package mysql
import (
"context"
"fmt"
"net"
"testing"
"github.com/go-sql-driver/mysql"
"github.com/grafana/grafana/pkg/setting"
"github.com/grafana/grafana/pkg/tsdb/sqleng"
"github.com/grafana/grafana/pkg/tsdb/sqleng/proxyutil"
"github.com/stretchr/testify/require"
"golang.org/x/net/proxy"
)
type testDialer struct {
}
func (d *testDialer) Dial(network, addr string) (c net.Conn, err error) {
return nil, fmt.Errorf("test-dialer: Dial is not functional")
}
func (d *testDialer) DialContext(ctx context.Context, network, address string) (net.Conn, error) {
return nil, fmt.Errorf("test-dialer: DialContext is not functional")
}
var _ proxy.Dialer = (&testDialer{})
var _ proxy.ContextDialer = (&testDialer{})
func TestMySQLProxyDialer(t *testing.T) {
settings := proxyutil.SetupTestSecureSocksProxySettings(t)
proxySettings := setting.SecureSocksDSProxySettings{
Enabled: true,
ClientCert: settings.ClientCert,
ClientKey: settings.ClientKey,
RootCA: settings.RootCA,
ProxyAddress: settings.ProxyAddress,
ServerName: settings.ServerName,
}
protocol := "tcp"
opts := proxyutil.GetSQLProxyOptions(proxySettings, sqleng.DataSourceInfo{UID: "1", JsonData: sqleng.JsonData{SecureDSProxy: true}}, "mysql", "mysql")
dbURL := "localhost:5432"
network, err := registerProxyDialerContext(protocol, dbURL, opts)
network, err := registerProxyDialerContext(protocol, dbURL, &testDialer{})
require.NoError(t, err)
driver := mysql.MySQLDriver{}
cnnstr := fmt.Sprintf("test:test@%s(%s)/db",
@@ -38,7 +41,7 @@ func TestMySQLProxyDialer(t *testing.T) {
})
t.Run("Multiple networks can be created", func(t *testing.T) {
network, err := registerProxyDialerContext(protocol, dbURL, opts)
network, err := registerProxyDialerContext(protocol, dbURL, &testDialer{})
require.NoError(t, err)
cnnstr2 := fmt.Sprintf("test:test@%s(%s)/db",
network,
@@ -56,6 +59,6 @@ func TestMySQLProxyDialer(t *testing.T) {
require.NoError(t, err)
_, err = conn.Connect(context.Background())
require.Error(t, err)
require.Contains(t, err.Error(), fmt.Sprintf("socks connect %s %s->%s", protocol, settings.ProxyAddress, dbURL))
require.Contains(t, err.Error(), "test-dialer: DialContext is not functional")
})
}
@@ -1,7 +1,7 @@
import 'whatwg-fetch'; // fetch polyfill
import { fireEvent, render as rtlRender, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { rest } from 'msw';
import { HttpResponse, http } from 'msw';
import { SetupServer, setupServer } from 'msw/node';
import React from 'react';
import { TestProvider } from 'test/helpers/TestProvider';
@@ -47,14 +47,11 @@ describe('NestedFolderPicker', () => {
beforeAll(() => {
window.HTMLElement.prototype.scrollIntoView = function () {};
server = setupServer(
rest.get('/api/folders/:uid', (_, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
title: folderA.item.title,
uid: folderA.item.uid,
})
);
http.get('/api/folders/:uid', () => {
return HttpResponse.json({
title: folderA.item.title,
uid: folderA.item.uid,
});
})
);
server.listen();
@@ -1,3 +1,4 @@
import 'whatwg-fetch';
import { render, waitFor, waitForElementToBeRemoved, within } from '@testing-library/react';
import { setupServer } from 'msw/node';
import React from 'react';
@@ -11,7 +12,6 @@ import { backendSrv } from 'app/core/services/backend_srv';
import { DashboardSearchItem, DashboardSearchItemType } from 'app/features/search/types';
import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';
import { RuleWithLocation } from 'app/types/unified-alerting';
import 'whatwg-fetch';
import {
RulerAlertingRuleDTO,
@@ -1,10 +1,9 @@
import { render, screen } from '@testing-library/react';
import 'whatwg-fetch';
import { render, screen, waitFor } from '@testing-library/react';
import { setupServer } from 'msw/node';
import React from 'react';
import { Provider } from 'react-redux';
import 'whatwg-fetch';
import { setBackendSrv } from '@grafana/runtime';
import { backendSrv } from 'app/core/services/backend_srv';
import { configureStore } from 'app/store/configureStore';
@@ -76,7 +75,9 @@ describe('GrafanaAlertmanagerDeliveryWarning', () => {
<GrafanaAlertmanagerDeliveryWarning currentAlertmanager={GRAFANA_RULES_SOURCE_NAME} />
);
expect(container).toBeEmptyDOMElement();
await waitFor(() => {
expect(container).toBeEmptyDOMElement();
});
});
it('Should render no warning when choice is All but no active AM instances', async () => {
@@ -89,7 +90,9 @@ describe('GrafanaAlertmanagerDeliveryWarning', () => {
<GrafanaAlertmanagerDeliveryWarning currentAlertmanager={GRAFANA_RULES_SOURCE_NAME} />
);
expect(container).toBeEmptyDOMElement();
await waitFor(() => {
expect(container).toBeEmptyDOMElement();
});
});
});
@@ -1,20 +1,25 @@
import { rest } from 'msw';
import { setupServer } from 'msw/node';
// bit of setup to mock HTTP request responses
import 'whatwg-fetch';
import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
import { SupportedPlugin } from '../types/pluginBridges';
export const NON_EXISTING_PLUGIN = '__does_not_exist__';
const server = setupServer(
rest.get(`/api/plugins/${NON_EXISTING_PLUGIN}/settings`, async (_req, res, ctx) => res(ctx.status(404))),
rest.get(`/api/plugins/${SupportedPlugin.Incident}/settings`, async (_req, res, ctx) => {
return res(
ctx.json({
enabled: true,
})
);
http.get(`/api/plugins/${NON_EXISTING_PLUGIN}/settings`, async () =>
HttpResponse.json(
{},
{
status: 404,
}
)
),
http.get(`/api/plugins/${SupportedPlugin.Incident}/settings`, async () => {
return HttpResponse.json({
enabled: true,
});
})
);
@@ -1,4 +1,5 @@
import { rest } from 'msw';
import 'whatwg-fetch';
import { http, HttpResponse } from 'msw';
import { SetupServer } from 'msw/node';
import { AlertmanagerChoice, AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';
@@ -14,15 +15,15 @@ import receiversMock from './receivers.mock.json';
export default (server: SetupServer) => {
server.use(
// this endpoint is a grafana built-in alertmanager
rest.get('/api/alertmanager/grafana/config/api/v1/alerts', (_req, res, ctx) =>
res(ctx.json<AlertManagerCortexConfig>(alertmanagerMock))
http.get('/api/alertmanager/grafana/config/api/v1/alerts', () =>
HttpResponse.json<AlertManagerCortexConfig>(alertmanagerMock)
),
// this endpoint is only available for the built-in alertmanager
rest.get('/api/alertmanager/grafana/config/api/v1/receivers', (_req, res, ctx) =>
res(ctx.json<ReceiversStateDTO[]>(receiversMock))
http.get('/api/alertmanager/grafana/config/api/v1/receivers', () =>
HttpResponse.json<ReceiversStateDTO[]>(receiversMock)
),
// this endpoint will respond if the OnCall plugin is installed
rest.get('/api/plugins/grafana-oncall-app/settings', (_req, res, ctx) => res(ctx.status(404)))
http.get('/api/plugins/grafana-oncall-app/settings', () => HttpResponse.json({}, { status: 404 }))
);
// this endpoint is for rendering the "additional AMs to configure" warning
@@ -41,12 +42,18 @@ export const setupTestEndpointMock = (server: SetupServer) => {
const mock = jest.fn();
server.use(
rest.post('/api/alertmanager/grafana/config/api/v1/receivers/test', async (req, res, ctx) => {
const requestBody = await req.json();
mock(requestBody);
http.post(
'/api/alertmanager/grafana/config/api/v1/receivers/test',
async ({ request }) => {
const requestBody = await request.json();
mock(requestBody);
return res.once(ctx.status(200));
})
return HttpResponse.json({});
},
{
once: true,
}
)
);
return mock;
@@ -56,12 +63,18 @@ export const setupSaveEndpointMock = (server: SetupServer) => {
const mock = jest.fn();
server.use(
rest.post('/api/alertmanager/grafana/config/api/v1/alerts', async (req, res, ctx) => {
const requestBody = await req.json();
mock(requestBody);
http.post(
'/api/alertmanager/grafana/config/api/v1/alerts',
async ({ request }) => {
const requestBody = await request.json();
mock(requestBody);
return res.once(ctx.status(200));
})
return HttpResponse.json({});
},
{
once: true,
}
)
);
return mock;
@@ -1,4 +1,5 @@
import { rest } from 'msw';
import 'whatwg-fetch';
import { http, HttpResponse } from 'msw';
import { SetupServer } from 'msw/lib/node';
import { AlertManagerCortexConfig } from 'app/plugins/datasource/alertmanager/types';
@@ -10,14 +11,20 @@ export const MIMIR_DATASOURCE_UID = 'mimir';
export default (server: SetupServer) => {
server.use(
rest.get(`/api/alertmanager/${MIMIR_DATASOURCE_UID}/config/api/v1/alerts`, (_req, res, ctx) =>
res(ctx.json<AlertManagerCortexConfig>(mimirAlertmanagerMock))
http.get(`/api/alertmanager/${MIMIR_DATASOURCE_UID}/config/api/v1/alerts`, () =>
HttpResponse.json(mimirAlertmanagerMock)
),
rest.get(`/api/datasources/proxy/uid/${MIMIR_DATASOURCE_UID}/api/v1/status/buildinfo`, (_req, res, ctx) =>
res(ctx.status(404))
http.get(`/api/datasources/proxy/uid/${MIMIR_DATASOURCE_UID}/api/v1/status/buildinfo`, () =>
HttpResponse.json<AlertManagerCortexConfig>(
{
template_files: {},
alertmanager_config: {},
},
{ status: 404 }
)
),
// this endpoint will respond if the OnCall plugin is installed
rest.get('/api/plugins/grafana-oncall-app/settings', (_req, res, ctx) => res(ctx.status(404)))
http.get('/api/plugins/grafana-oncall-app/settings', () => HttpResponse.json({}, { status: 404 }))
);
return server;
@@ -1,4 +1,5 @@
import { rest } from 'msw';
import 'whatwg-fetch';
import { http, HttpResponse } from 'msw';
import { SetupServer } from 'msw/lib/node';
import { AlertmanagerStatus } from 'app/plugins/datasource/alertmanager/types';
@@ -10,11 +11,11 @@ export const VANILLA_ALERTMANAGER_DATASOURCE_UID = 'alertmanager';
export default (server: SetupServer) => {
server.use(
rest.get(`/api/alertmanager/${VANILLA_ALERTMANAGER_DATASOURCE_UID}/api/v2/status`, (_req, res, ctx) =>
res(ctx.json<AlertmanagerStatus>(vanillaAlertManagerConfig))
http.get(`/api/alertmanager/${VANILLA_ALERTMANAGER_DATASOURCE_UID}/api/v2/status`, () =>
HttpResponse.json<AlertmanagerStatus>(vanillaAlertManagerConfig)
),
// this endpoint will respond if the OnCall plugin is installed
rest.get('/api/plugins/grafana-oncall-app/settings', (_req, res, ctx) => res(ctx.status(404)))
http.get('/api/plugins/grafana-oncall-app/settings', () => HttpResponse.json({}, { status: 404 }))
);
return server;
@@ -0,0 +1,157 @@
import { GrafanaManagedContactPoint } from 'app/plugins/datasource/alertmanager/types';
import { ReceiverTypes } from '../receivers/grafanaAppReceivers/onCall/onCall';
import { RECEIVER_META_KEY, RECEIVER_PLUGIN_META_KEY } from './useContactPoints';
import {
ReceiverConfigWithMetadata,
getReceiverDescription,
isAutoGeneratedPolicy,
isProvisioned,
summarizeEmailAddresses,
} from './utils';
describe('isProvisioned', () => {
it('should return true when at least one receiver is provisioned', () => {
const contactPoint: GrafanaManagedContactPoint = {
name: 'my-contact-point',
grafana_managed_receiver_configs: [
{ name: 'email', provenance: 'api', type: 'email', disableResolveMessage: false, settings: {} },
],
};
expect(isProvisioned(contactPoint)).toBe(true);
});
it('should return false when no receiver was provisioned', () => {
const contactPoint: GrafanaManagedContactPoint = {
name: 'my-contact-point',
grafana_managed_receiver_configs: [
{ name: 'email', provenance: undefined, type: 'email', disableResolveMessage: false, settings: {} },
],
};
expect(isProvisioned(contactPoint)).toBe(false);
});
});
describe('isAutoGeneratedPolicy', () => {
it('should return false when not enabled', () => {
expect(isAutoGeneratedPolicy({})).toBe(false);
});
});
describe('getReceiverDescription', () => {
it('should show multiple email addresses', () => {
const receiver: ReceiverConfigWithMetadata = {
name: 'email',
provenance: undefined,
type: 'email',
disableResolveMessage: false,
settings: { addresses: 'test1@test.com,test2@test.com,test3@test.com,test4@test.com' },
[RECEIVER_META_KEY]: {
name: 'Email',
description: 'The email receiver',
},
};
expect(getReceiverDescription(receiver)).toBe('test1@test.com, test2@test.com, test3@test.com, +1 more');
});
it('should work for Slack', () => {
const output = '#channel';
const receiver1: ReceiverConfigWithMetadata = {
name: 'slack',
provenance: undefined,
type: 'slack',
disableResolveMessage: false,
settings: { recipient: '#channel' },
[RECEIVER_META_KEY]: {
name: 'Slack',
description: 'The Slack receiver',
},
};
const receiver2: ReceiverConfigWithMetadata = {
name: 'slack',
provenance: undefined,
type: 'slack',
disableResolveMessage: false,
settings: { recipient: 'channel' },
[RECEIVER_META_KEY]: {
name: 'Slack',
description: 'The Slack receiver',
},
};
expect(getReceiverDescription(receiver1)).toBe(output);
expect(getReceiverDescription(receiver2)).toBe(output);
});
it('should work for OnCall', () => {
const output = 'The OnCall receiver';
const input: ReceiverConfigWithMetadata = {
name: 'my oncall',
provenance: undefined,
type: ReceiverTypes.OnCall,
disableResolveMessage: false,
settings: {},
[RECEIVER_PLUGIN_META_KEY]: {
description: output,
icon: '',
title: '',
},
[RECEIVER_META_KEY]: {
name: '',
},
};
expect(getReceiverDescription(input)).toBe(output);
});
it('should work for any type', () => {
const output = 'Some description of the receiver';
const input: ReceiverConfigWithMetadata = {
name: 'some receiver',
provenance: undefined,
type: 'some',
disableResolveMessage: false,
settings: {},
[RECEIVER_META_KEY]: {
name: 'Some Receiver',
description: output,
},
};
expect(getReceiverDescription(input)).toBe(output);
});
it('should work for any type with no description', () => {
const input: ReceiverConfigWithMetadata = {
name: 'some receiver',
provenance: undefined,
type: 'some',
disableResolveMessage: false,
settings: {},
[RECEIVER_META_KEY]: {
name: 'Some Receiver',
},
};
expect(getReceiverDescription(input)).toBe(undefined);
});
});
describe('summarizeEmailAddresses', () => {
it('should work with one email address', () => {
expect(summarizeEmailAddresses('test@test.com')).toBe('test@test.com');
});
it('should work with multiple types of separators', () => {
const output = 'foo@foo.com, bar@bar.com';
expect(summarizeEmailAddresses('foo@foo.com, bar@bar.com')).toBe(output);
expect(summarizeEmailAddresses(' foo@foo.com; bar@bar.com')).toBe(output);
expect(summarizeEmailAddresses('foo@foo.com\n bar@bar.com ')).toBe(output);
});
});
@@ -1,4 +1,4 @@
import { countBy, split, trim, upperFirst } from 'lodash';
import { countBy, difference, take, trim, upperFirst } from 'lodash';
import { ReactNode } from 'react';
import { config } from '@grafana/runtime';
@@ -40,15 +40,21 @@ export function getReceiverDescription(receiver: ReceiverConfigWithMetadata): Re
return hasEmailAddresses ? summarizeEmailAddresses(receiver.settings['addresses']) : undefined;
}
case 'slack': {
const channelName = receiver.settings['recipient'];
return channelName ? `#${channelName}` : undefined;
const recipient: string | undefined = receiver.settings['recipient'];
if (!recipient) {
return;
}
// Slack channel name might have a "#" in the recipient already
const channelName = recipient.replace(/^#/, '');
return `#${channelName}`;
}
case 'kafka': {
const topicName = receiver.settings['kafkaTopic'];
const topicName: string | undefined = receiver.settings['kafkaTopic'];
return topicName;
}
case 'webhook': {
const url = receiver.settings['url'];
const url: string | undefined = receiver.settings['url'];
return url;
}
case ReceiverTypes.OnCall: {
@@ -61,20 +67,22 @@ export function getReceiverDescription(receiver: ReceiverConfigWithMetadata): Re
// input: foo+1@bar.com, foo+2@bar.com, foo+3@bar.com, foo+4@bar.com
// output: foo+1@bar.com, foo+2@bar.com, +2 more
function summarizeEmailAddresses(addresses: string): string {
export function summarizeEmailAddresses(addresses: string): string {
const MAX_ADDRESSES_SHOWN = 3;
const SUPPORTED_SEPARATORS = /,|;|\n+/g;
// split all email addresses
const emails = addresses.trim().split(SUPPORTED_SEPARATORS).map(trim);
const notShown = emails.length - MAX_ADDRESSES_SHOWN;
// grab the first 3 and the rest
const summary = take(emails, MAX_ADDRESSES_SHOWN);
const rest = difference(emails, summary);
const truncatedAddresses = split(addresses, SUPPORTED_SEPARATORS, MAX_ADDRESSES_SHOWN);
if (notShown > 0) {
truncatedAddresses.push(`+${notShown} more`);
if (rest.length) {
summary.push(`+${rest.length} more`);
}
return truncatedAddresses.join(', ');
return summary.join(', ');
}
// Grafana Managed contact points have receivers with additional diagnostics
@@ -1,7 +1,7 @@
import { rest } from 'msw';
import 'whatwg-fetch';
import { http, HttpResponse } from 'msw';
import { SetupServer, setupServer } from 'msw/node';
import 'whatwg-fetch';
import { AlertmanagersChoiceResponse } from 'app/features/alerting/unified/api/alertmanagerApi';
import { mockAlertmanagerChoiceResponse } from 'app/features/alerting/unified/mocks/alertmanagerApi';
import { AlertmanagerChoice } from 'app/plugins/datasource/alertmanager/types';
@@ -33,16 +33,15 @@ export function createMockGrafanaServer() {
// a user must alsso have permissions for the folder (namespace) in which the alert rule is stored
function mockFolderAccess(server: SetupServer, accessControl: Partial<Record<AccessControlAction, boolean>>) {
server.use(
rest.get('/api/folders/:uid', (req, res, ctx) => {
const uid = req.params.uid;
http.get('/api/folders/:uid', ({ request }) => {
const url = new URL(request.url);
const uid = url.searchParams.get('uid');
return res(
ctx.json({
title: 'My Folder',
uid,
accessControl,
})
);
return HttpResponse.json({
title: 'My Folder',
uid,
accessControl,
});
})
);
@@ -51,8 +50,8 @@ function mockFolderAccess(server: SetupServer, accessControl: Partial<Record<Acc
function mockGrafanaIncidentPluginSettings(server: SetupServer) {
server.use(
rest.get('/api/plugins/grafana-incident-app/settings', (_, res, ctx) => {
return res(ctx.status(200));
http.get('/api/plugins/grafana-incident-app/settings', () => {
return HttpResponse.json({});
})
);
}
@@ -1,4 +1,6 @@
import 'whatwg-fetch';
import { render, screen, waitFor } from '@testing-library/react';
import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
import React from 'react';
import { Provider } from 'react-redux';
@@ -18,6 +20,7 @@ import { AlertmanagersChoiceResponse } from '../../api/alertmanagerApi';
import { useIsRuleEditable } from '../../hooks/useIsRuleEditable';
import { getCloudRule, getGrafanaRule } from '../../mocks';
import { mockAlertmanagerChoiceResponse } from '../../mocks/alertmanagerApi';
import { SupportedPlugin } from '../../types/pluginBridges';
import { RuleDetails } from './RuleDetails';
@@ -42,7 +45,13 @@ const ui = {
},
};
const server = setupServer();
const server = setupServer(
http.get(`/api/plugins/${SupportedPlugin.Incident}/settings`, async () => {
return HttpResponse.json({
enabled: false,
});
})
);
const alertmanagerChoiceMockedResponse: AlertmanagersChoiceResponse = {
alertmanagersChoice: AlertmanagerChoice.Internal,
@@ -74,6 +83,7 @@ beforeEach(() => {
],
});
server.resetHandlers();
mockAlertmanagerChoiceResponse(server, alertmanagerChoiceMockedResponse);
});
describe('RuleDetails RBAC', () => {
@@ -107,7 +117,6 @@ describe('RuleDetails RBAC', () => {
it('Should not render Silence button for users wihout the instance create permission', async () => {
// Arrange
jest.spyOn(contextSrv, 'hasPermission').mockReturnValue(false);
mockAlertmanagerChoiceResponse(server, alertmanagerChoiceMockedResponse);
// Act
renderRuleDetails(grafanaRule);
@@ -118,8 +127,6 @@ describe('RuleDetails RBAC', () => {
});
it('Should render Silence button for users with the instance create permissions', async () => {
mockAlertmanagerChoiceResponse(server, alertmanagerChoiceMockedResponse);
// Arrange
jest
.spyOn(contextSrv, 'hasPermission')
@@ -108,10 +108,12 @@ describe('Rules group tests', () => {
groups: [group],
};
it('Should hide delete and edit group buttons', () => {
it('Should hide delete and edit group buttons', async () => {
// Act
mockUseHasRuler(true, true);
mockFolderApi(server).folder('cpu-usage', mockFolder({ uid: 'cpu-usage', canSave: false }));
renderRulesGroup(namespace, group);
expect(await screen.findByTestId('rule-group')).toBeInTheDocument();
// Assert
expect(ui.deleteGroupButton.query()).not.toBeInTheDocument();
@@ -1,9 +1,9 @@
import 'whatwg-fetch';
import { render, waitFor } from '@testing-library/react';
import { rest } from 'msw';
import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
import React from 'react';
import { byRole, byText } from 'testing-library-selector';
import 'whatwg-fetch';
import { DataFrameJSON } from '@grafana/data';
import { setBackendSrv } from '@grafana/runtime';
@@ -20,53 +20,51 @@ beforeAll(() => {
server.listen({ onUnhandledRequest: 'error' });
server.use(
rest.get('/api/v1/rules/history', (req, res, ctx) =>
res(
ctx.json<DataFrameJSON>({
data: {
values: [
[1681739580000, 1681739580000, 1681739580000],
[
{
previous: 'Normal',
current: 'Pending',
values: {
B: 0.010344684900897919,
C: 1,
},
labels: {
handler: '/api/prometheus/grafana/api/v1/rules',
},
http.get('/api/v1/rules/history', () =>
HttpResponse.json<DataFrameJSON>({
data: {
values: [
[1681739580000, 1681739580000, 1681739580000],
[
{
previous: 'Normal',
current: 'Pending',
values: {
B: 0.010344684900897919,
C: 1,
},
{
previous: 'Normal',
current: 'Pending',
values: {
B: 0.010344684900897919,
C: 1,
},
dashboardUID: '',
panelID: 0,
labels: {
handler: '/api/live/ws',
},
labels: {
handler: '/api/prometheus/grafana/api/v1/rules',
},
{
previous: 'Normal',
current: 'Pending',
values: {
B: 0.010344684900897919,
C: 1,
},
labels: {
handler: '/api/folders/:uid/',
},
},
{
previous: 'Normal',
current: 'Pending',
values: {
B: 0.010344684900897919,
C: 1,
},
],
dashboardUID: '',
panelID: 0,
labels: {
handler: '/api/live/ws',
},
},
{
previous: 'Normal',
current: 'Pending',
values: {
B: 0.010344684900897919,
C: 1,
},
labels: {
handler: '/api/folders/:uid/',
},
},
],
},
})
)
],
},
})
)
);
});
@@ -100,8 +98,8 @@ describe('LokiStateHistory', () => {
it('should render no entries message when no records are returned', async () => {
server.use(
rest.get('/api/v1/rules/history', (req, res, ctx) =>
res(ctx.json<DataFrameJSON>({ data: { values: [] }, schema: { fields: [] } }))
http.get('/api/v1/rules/history', () =>
HttpResponse.json<DataFrameJSON>({ data: { values: [] }, schema: { fields: [] } })
)
);
@@ -1,10 +1,9 @@
import 'whatwg-fetch';
import { renderHook, waitFor } from '@testing-library/react';
import { rest } from 'msw';
import { http, HttpResponse } from 'msw';
import { SetupServer, setupServer } from 'msw/node';
import { TestProvider } from 'test/helpers/TestProvider';
import 'whatwg-fetch';
import { DataSourceSettings } from '@grafana/data';
import { setBackendSrv } from '@grafana/runtime';
import { backendSrv } from 'app/core/services/backend_srv';
@@ -215,8 +214,8 @@ function setupAlertmanagerDataSource(
};
server.use(
rest.get('/api/datasources', (_req, res, ctx) => {
return res(ctx.json([dsSettings]));
http.get('/api/datasources', () => {
return HttpResponse.json([dsSettings]);
})
);
}
+72 -83
View File
@@ -1,7 +1,7 @@
import { uniqueId } from 'lodash';
import { rest } from 'msw';
import { setupServer, SetupServer } from 'msw/node';
import 'whatwg-fetch';
import { uniqueId } from 'lodash';
import { http, HttpResponse } from 'msw';
import { setupServer, SetupServer } from 'msw/node';
import { DataSourceInstanceSettings, PluginMeta } from '@grafana/data';
import { setBackendSrv } from '@grafana/runtime';
@@ -190,85 +190,74 @@ export function mockApi(server: SetupServer) {
configure(builder);
server.use(
rest.get(`api/alertmanager/${amName}/config/api/v1/alerts`, (req, res, ctx) =>
res(
ctx.status(200),
ctx.json<AlertManagerCortexConfig>({
alertmanager_config: builder.build(),
template_files: {},
})
)
http.get(`api/alertmanager/${amName}/config/api/v1/alerts`, () =>
HttpResponse.json<AlertManagerCortexConfig>({
alertmanager_config: builder.build(),
template_files: {},
})
)
);
},
eval: (response: AlertingQueryResponse) => {
server.use(
rest.post('/api/v1/eval', (_, res, ctx) => {
return res(ctx.status(200), ctx.json(response));
http.post('/api/v1/eval', () => {
return HttpResponse.json(response);
})
);
},
grafanaNotifiers: (response: NotifierDTO[]) => {
server.use(
rest.get(`api/alert-notifiers`, (req, res, ctx) => res(ctx.status(200), ctx.json<NotifierDTO[]>(response)))
);
server.use(http.get(`api/alert-notifiers`, () => HttpResponse.json(response)));
},
plugins: {
getPluginSettings: (response: PluginMeta) => {
server.use(
rest.get(`api/plugins/${response.id}/settings`, (req, res, ctx) =>
res(ctx.status(200), ctx.json<PluginMeta>(response))
)
);
server.use(http.get(`api/plugins/${response.id}/settings`, () => HttpResponse.json(response)));
},
},
oncall: {
getOnCallIntegrations: (response: OnCallIntegrationDTO[]) => {
server.use(
rest.get(`api/plugin-proxy/grafana-oncall-app/api/internal/v1/alert_receive_channels`, (_, res, ctx) =>
res(ctx.status(200), ctx.json<OnCallIntegrationDTO[]>(response))
http.get(`api/plugin-proxy/grafana-oncall-app/api/internal/v1/alert_receive_channels`, () =>
HttpResponse.json<OnCallIntegrationDTO[]>(response)
)
);
},
features: (response: string[]) => {
server.use(
rest.get(`api/plugin-proxy/grafana-oncall-app/api/internal/v1/features`, (_, res, ctx) =>
res(ctx.status(200), ctx.json<string[]>(response))
)
http.get(`api/plugin-proxy/grafana-oncall-app/api/internal/v1/features`, () => HttpResponse.json(response))
);
},
validateIntegrationName: (invalidNames: string[]) => {
server.use(
rest.get(
http.get(
`api/plugin-proxy/grafana-oncall-app/api/internal/v1/alert_receive_channels/validate_name`,
(req, res, ctx) => {
const isValid = !invalidNames.includes(req.url.searchParams.get('verbal_name') ?? '');
return res(ctx.status(isValid ? 200 : 409), ctx.json<boolean>(isValid));
({ request }) => {
const url = new URL(request.url);
const isValid = !invalidNames.includes(url.searchParams.get('verbal_name') ?? '');
return HttpResponse.json(isValid, {
status: isValid ? 200 : 409,
});
}
)
);
},
createIntegraion: () => {
server.use(
rest.post<CreateIntegrationDTO>(
http.post<{}, CreateIntegrationDTO>(
`api/plugin-proxy/grafana-oncall-app/api/internal/v1/alert_receive_channels`,
async (req, res, ctx) => {
const body = await req.json<CreateIntegrationDTO>();
async ({ request }) => {
const body = await request.json();
const integrationId = uniqueId('oncall-integration-');
return res(
ctx.status(200),
ctx.json<NewOnCallIntegrationDTO>({
id: integrationId,
integration: body.integration,
integration_url: `https://oncall-endpoint.example.com/${integrationId}`,
verbal_name: body.verbal_name,
connected_escalations_chains_count: 0,
})
);
return HttpResponse.json<NewOnCallIntegrationDTO>({
id: integrationId,
integration: body.integration,
integration_url: `https://oncall-endpoint.example.com/${integrationId}`,
verbal_name: body.verbal_name,
connected_escalations_chains_count: 0,
});
}
)
);
@@ -281,21 +270,15 @@ export function mockAlertRuleApi(server: SetupServer) {
return {
prometheusRuleNamespaces: (dsName: string, response: PromRulesResponse) => {
server.use(
rest.get(`api/prometheus/${dsName}/api/v1/rules`, (req, res, ctx) =>
res(ctx.status(200), ctx.json<PromRulesResponse>(response))
)
http.get(`api/prometheus/${dsName}/api/v1/rules`, () => HttpResponse.json<PromRulesResponse>(response))
);
},
rulerRules: (dsName: string, response: RulerRulesConfigDTO) => {
server.use(
rest.get(`/api/ruler/${dsName}/api/v1/rules`, (req, res, ctx) => res(ctx.status(200), ctx.json(response)))
);
server.use(http.get(`/api/ruler/${dsName}/api/v1/rules`, () => HttpResponse.json(response)));
},
rulerRuleGroup: (dsName: string, namespace: string, group: string, response: RulerRuleGroupDTO) => {
server.use(
rest.get(`/api/ruler/${dsName}/api/v1/rules/${namespace}/${group}`, (req, res, ctx) =>
res(ctx.status(200), ctx.json(response))
)
http.get(`/api/ruler/${dsName}/api/v1/rules/${namespace}/${group}`, () => HttpResponse.json(response))
);
},
};
@@ -312,9 +295,7 @@ export function mockFeatureDiscoveryApi(server: SetupServer) {
* @param response Use `buildInfoResponse` to get a pre-defined response for Prometheus and Mimir
*/
discoverDsFeatures: (dsSettings: DataSourceInstanceSettings, response: PromBuildInfoResponse) => {
server.use(
rest.get(`${dsSettings.url}/api/v1/status/buildinfo`, (_, res, ctx) => res(ctx.status(200), ctx.json(response)))
);
server.use(http.get(`${dsSettings.url}/api/v1/status/buildinfo`, () => HttpResponse.json(response)));
},
};
}
@@ -323,16 +304,20 @@ export function mockProvisioningApi(server: SetupServer) {
return {
exportRuleGroup: (folderUid: string, groupName: string, response: Record<string, string>) => {
server.use(
rest.get(`/api/v1/provisioning/folder/${folderUid}/rule-groups/${groupName}/export`, (req, res, ctx) =>
res(ctx.status(200), ctx.text(response[req.url.searchParams.get('format') ?? 'yaml']))
)
http.get(`/api/v1/provisioning/folder/${folderUid}/rule-groups/${groupName}/export`, ({ request }) => {
const url = new URL(request.url);
const format = url.searchParams.get('format') ?? 'yaml';
return HttpResponse.text(response[format]);
})
);
},
exportReceiver: (response: Record<string, string>) => {
server.use(
rest.get(`/api/v1/provisioning/contact-points/export/`, (req, res, ctx) =>
res(ctx.status(200), ctx.text(response[req.url.searchParams.get('format') ?? 'yaml']))
)
http.get(`/api/v1/provisioning/contact-points/export/`, ({ request }) => {
const url = new URL(request.url);
const format = url.searchParams.get('format') ?? 'yaml';
return HttpResponse.text(response[format]);
})
);
},
};
@@ -344,43 +329,51 @@ export function mockExportApi(server: SetupServer) {
// exportRule requires ruleUid parameter and doesn't allow folderUid and group parameters
exportRule: (ruleUid: string, response: Record<string, string>) => {
server.use(
rest.get('/api/ruler/grafana/api/v1/export/rules', (req, res, ctx) => {
if (req.url.searchParams.get('ruleUid') === ruleUid) {
return res(ctx.status(200), ctx.text(response[req.url.searchParams.get('format') ?? 'yaml']));
http.get('/api/ruler/grafana/api/v1/export/rules', ({ request }) => {
const url = new URL(request.url);
if (url.searchParams.get('ruleUid') === ruleUid) {
const format = url.searchParams.get('format') ?? 'yaml';
return HttpResponse.text(response[format]);
}
return res(ctx.status(500));
return HttpResponse.text('', { status: 500 });
})
);
},
// exportRulesGroup requires folderUid and group parameters and doesn't allow ruleUid parameter
exportRulesGroup: (folderUid: string, group: string, response: Record<string, string>) => {
server.use(
rest.get('/api/ruler/grafana/api/v1/export/rules', (req, res, ctx) => {
if (req.url.searchParams.get('folderUid') === folderUid && req.url.searchParams.get('group') === group) {
return res(ctx.status(200), ctx.text(response[req.url.searchParams.get('format') ?? 'yaml']));
http.get('/api/ruler/grafana/api/v1/export/rules', ({ request }) => {
const url = new URL(request.url);
if (url.searchParams.get('folderUid') === folderUid && url.searchParams.get('group') === group) {
const format = url.searchParams.get('format') ?? 'yaml';
return HttpResponse.text(response[format]);
}
return res(ctx.status(500));
return HttpResponse.text('', { status: 500 });
})
);
},
// exportRulesFolder requires folderUid parameter
exportRulesFolder: (folderUid: string, response: Record<string, string>) => {
server.use(
rest.get('/api/ruler/grafana/api/v1/export/rules', (req, res, ctx) => {
if (req.url.searchParams.get('folderUid') === folderUid) {
return res(ctx.status(200), ctx.text(response[req.url.searchParams.get('format') ?? 'yaml']));
http.get('/api/ruler/grafana/api/v1/export/rules', ({ request }) => {
const url = new URL(request.url);
if (url.searchParams.get('folderUid') === folderUid) {
const format = url.searchParams.get('format') ?? 'yaml';
return HttpResponse.text(response[format]);
}
return res(ctx.status(500));
return HttpResponse.text('', { status: 500 });
})
);
},
modifiedExport: (namespaceUID: string, response: Record<string, string>) => {
server.use(
rest.post(`/api/ruler/grafana/api/v1/rules/${namespaceUID}/export`, (req, res, ctx) => {
return res(ctx.status(200), ctx.text(response[req.url.searchParams.get('format') ?? 'yaml']));
http.post(`/api/ruler/grafana/api/v1/rules/${namespaceUID}/export`, ({ request }) => {
const url = new URL(request.url);
const format = url.searchParams.get('format') ?? 'yaml';
return HttpResponse.text(response[format]);
})
);
},
@@ -390,7 +383,7 @@ export function mockExportApi(server: SetupServer) {
export function mockFolderApi(server: SetupServer) {
return {
folder: (folderUid: string, response: FolderDTO) => {
server.use(rest.get(`/api/folders/${folderUid}`, (_, res, ctx) => res(ctx.status(200), ctx.json(response))));
server.use(http.get(`/api/folders/${folderUid}`, () => HttpResponse.json(response)));
},
};
}
@@ -398,7 +391,7 @@ export function mockFolderApi(server: SetupServer) {
export function mockSearchApi(server: SetupServer) {
return {
search: (results: DashboardSearchItem[]) => {
server.use(rest.get(`/api/search`, (_, res, ctx) => res(ctx.status(200), ctx.json(results))));
server.use(http.get(`/api/search`, () => HttpResponse.json(results)));
},
};
}
@@ -406,14 +399,10 @@ export function mockSearchApi(server: SetupServer) {
export function mockDashboardApi(server: SetupServer) {
return {
search: (results: DashboardSearchItem[]) => {
server.use(rest.get(`/api/search`, (_, res, ctx) => res(ctx.status(200), ctx.json(results))));
server.use(http.get(`/api/search`, () => HttpResponse.json(results)));
},
dashboard: (response: DashboardDTO) => {
server.use(
rest.get(`/api/dashboards/uid/${response.dashboard.uid}`, (_, res, ctx) =>
res(ctx.status(200), ctx.json(response))
)
);
server.use(http.get(`/api/dashboards/uid/${response.dashboard.uid}`, () => HttpResponse.json(response)));
},
};
}
@@ -1,4 +1,5 @@
import { rest } from 'msw';
import 'whatwg-fetch';
import { http, HttpResponse } from 'msw';
import { SetupServer } from 'msw/node';
import { PromRulesResponse } from 'app/types/unified-alerting-dto';
@@ -6,9 +7,9 @@ import { PromRulesResponse } from 'app/types/unified-alerting-dto';
import { PreviewResponse, PREVIEW_URL, PROM_RULES_URL } from '../api/alertRuleApi';
export function mockPreviewApiResponse(server: SetupServer, result: PreviewResponse) {
server.use(rest.post(PREVIEW_URL, (req, res, ctx) => res(ctx.json<PreviewResponse>(result))));
server.use(http.post(PREVIEW_URL, () => HttpResponse.json(result)));
}
export function mockPromRulesApiResponse(server: SetupServer, result: PromRulesResponse) {
server.use(rest.get(PROM_RULES_URL, (req, res, ctx) => res(ctx.json<PromRulesResponse>(result))));
server.use(http.get(PROM_RULES_URL, () => HttpResponse.json(result)));
}
@@ -1,4 +1,5 @@
import { rest } from 'msw';
import 'whatwg-fetch';
import { http, HttpResponse } from 'msw';
import { SetupServer } from 'msw/node';
import {
@@ -14,7 +15,7 @@ export const defaultAlertmanagerChoiceResponse: AlertmanagersChoiceResponse = {
numExternalAlertmanagers: 0,
};
export function mockAlertmanagerChoiceResponse(server: SetupServer, response: AlertmanagersChoiceResponse) {
server.use(rest.get('/api/v1/ngalert', (req, res, ctx) => res(ctx.status(200), ctx.json(response))));
server.use(http.get('/api/v1/ngalert', () => HttpResponse.json(response)));
}
export const emptyExternalAlertmanagersResponse: ExternalAlertmanagersResponse = {
@@ -24,7 +25,7 @@ export const emptyExternalAlertmanagersResponse: ExternalAlertmanagersResponse =
},
};
export function mockAlertmanagersResponse(server: SetupServer, response: ExternalAlertmanagersResponse) {
server.use(rest.get('/api/v1/ngalert/alertmanagers', (req, res, ctx) => res(ctx.status(200), ctx.json(response))));
server.use(http.get('/api/v1/ngalert/alertmanagers', () => HttpResponse.json(response)));
}
export function mockAlertmanagerConfigResponse(
@@ -33,8 +34,8 @@ export function mockAlertmanagerConfigResponse(
response: AlertManagerCortexConfig
) {
server.use(
rest.get(`/api/alertmanager/${getDatasourceAPIUid(alertManagerSourceName)}/config/api/v1/alerts`, (req, res, ctx) =>
res(ctx.status(200), ctx.json(response))
http.get(`/api/alertmanager/${getDatasourceAPIUid(alertManagerSourceName)}/config/api/v1/alerts`, () =>
HttpResponse.json(response)
)
);
}
@@ -1,4 +1,5 @@
import { rest } from 'msw';
import 'whatwg-fetch';
import { http, HttpResponse } from 'msw';
import { SetupServer } from 'msw/lib/node';
import { PluginMeta } from '@grafana/data';
@@ -7,8 +8,11 @@ import { SupportedPlugin } from '../types/pluginBridges';
export function mockPluginSettings(server: SetupServer, plugin: SupportedPlugin, response?: PluginMeta) {
server.use(
rest.get(`/api/plugins/${plugin}/settings`, (_req, res, ctx) => {
return response ? res(ctx.status(200), ctx.json(response)) : res(ctx.status(404));
http.get(`/api/plugins/${plugin}/settings`, () => {
if (response) {
return HttpResponse.json(response);
}
return HttpResponse.json({}, { status: 404 });
})
);
}
@@ -1,14 +1,11 @@
import { rest } from 'msw';
import 'whatwg-fetch';
import { http, HttpResponse } from 'msw';
import { SetupServer } from 'msw/node';
import { RulerRuleGroupDTO, RulerRulesConfigDTO } from '../../../../types/unified-alerting-dto';
export function mockRulerRulesApiResponse(server: SetupServer, rulesSourceName: string, response: RulerRulesConfigDTO) {
server.use(
rest.get(`/api/ruler/${rulesSourceName}/api/v1/rules`, (req, res, ctx) =>
res(ctx.json<RulerRulesConfigDTO>(response))
)
);
server.use(http.get(`/api/ruler/${rulesSourceName}/api/v1/rules`, () => HttpResponse.json(response)));
}
export function mockRulerRulesGroupApiResponse(
@@ -19,8 +16,6 @@ export function mockRulerRulesGroupApiResponse(
response: RulerRuleGroupDTO
) {
server.use(
rest.get(`/api/ruler/${rulesSourceName}/api/v1/rules/${namespace}/${group}`, (req, res, ctx) =>
res(ctx.json(response))
)
http.get(`/api/ruler/${rulesSourceName}/api/v1/rules/${namespace}/${group}`, () => HttpResponse.json(response))
);
}
@@ -1,12 +1,13 @@
import { rest } from 'msw';
import 'whatwg-fetch';
import { http, HttpResponse } from 'msw';
import { SetupServer } from 'msw/node';
import { previewTemplateUrl, TemplatePreviewResponse } from '../api/templateApi';
export function mockPreviewTemplateResponse(server: SetupServer, response: TemplatePreviewResponse) {
server.use(rest.post(previewTemplateUrl, (req, res, ctx) => res(ctx.status(200), ctx.json(response))));
server.use(http.post(previewTemplateUrl, () => HttpResponse.json(response)));
}
export function mockPreviewTemplateResponseRejected(server: SetupServer) {
server.use(rest.post(previewTemplateUrl, (req, res, ctx) => res(ctx.status(500), ctx.json('error'))));
server.use(http.post(previewTemplateUrl, () => HttpResponse.json('error', { status: 500 })));
}
@@ -1,7 +1,7 @@
import 'whatwg-fetch'; // fetch polyfill
import 'whatwg-fetch';
import { render as rtlRender, screen } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { rest } from 'msw';
import { HttpResponse, http } from 'msw';
import { setupServer, SetupServer } from 'msw/node';
import React, { ComponentProps } from 'react';
import AutoSizer from 'react-virtualized-auto-sizer';
@@ -120,25 +120,19 @@ describe('browse-dashboards BrowseDashboardsPage', () => {
beforeAll(() => {
server = setupServer(
rest.get('/api/folders/:uid', (_, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
title: folderA.item.title,
uid: folderA.item.uid,
})
);
http.get('/api/folders/:uid', () => {
return HttpResponse.json({
title: folderA.item.title,
uid: folderA.item.uid,
});
}),
rest.get('/api/search', (_, res, ctx) => {
return res(ctx.status(200), ctx.json({}));
http.get('/api/search', () => {
return HttpResponse.json({});
}),
rest.get('/api/search/sorting', (_, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
sortOptions: [],
})
);
http.get('/api/search/sorting', () => {
return HttpResponse.json({
sortOptions: [],
});
})
);
server.listen();
@@ -1,6 +1,6 @@
import 'whatwg-fetch'; // fetch polyfill
import 'whatwg-fetch';
import { render as rtlRender, screen } from '@testing-library/react';
import { rest } from 'msw';
import { http, HttpResponse } from 'msw';
import { SetupServer, setupServer } from 'msw/node';
import React from 'react';
import { TestProvider } from 'test/helpers/TestProvider';
@@ -47,20 +47,17 @@ describe('browse-dashboards BrowseFolderAlertingPage', () => {
beforeAll(() => {
server = setupServer(
rest.get('/api/folders/:uid', (_, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
title: mockFolderName,
uid: mockFolderUid,
})
);
http.get('/api/folders/:uid', () => {
return HttpResponse.json({
title: mockFolderName,
uid: mockFolderUid,
});
}),
rest.get('api/ruler/grafana/api/v1/rules', (_, res, ctx) => {
return res(ctx.status(200), ctx.json(mockRulerRulesResponse));
http.get('api/ruler/grafana/api/v1/rules', () => {
return HttpResponse.json(mockRulerRulesResponse);
}),
rest.get('api/prometheus/grafana/api/v1/rules', (_, res, ctx) => {
return res(ctx.status(200), ctx.json(mockPrometheusRulesResponse));
http.get('api/prometheus/grafana/api/v1/rules', () => {
return HttpResponse.json(mockPrometheusRulesResponse);
})
);
server.listen();
@@ -1,6 +1,6 @@
import 'whatwg-fetch'; // fetch polyfill
import 'whatwg-fetch';
import { render as rtlRender, screen } from '@testing-library/react';
import { rest } from 'msw';
import { http, HttpResponse } from 'msw';
import { SetupServer, setupServer } from 'msw/node';
import React from 'react';
import { TestProvider } from 'test/helpers/TestProvider';
@@ -47,25 +47,19 @@ describe('browse-dashboards BrowseFolderLibraryPanelsPage', () => {
beforeAll(() => {
server = setupServer(
rest.get('/api/folders/:uid', (_, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
title: mockFolderName,
uid: mockFolderUid,
})
);
http.get('/api/folders/:uid', () => {
return HttpResponse.json({
title: mockFolderName,
uid: mockFolderUid,
});
}),
rest.get('/api/library-elements', (_, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
result: mockLibraryElementsResponse,
})
);
http.get('/api/library-elements', () => {
return HttpResponse.json({
result: mockLibraryElementsResponse,
});
}),
rest.get('/api/search/sorting', (_, res, ctx) => {
return res(ctx.status(200), ctx.json({}));
http.get('/api/search/sorting', () => {
return HttpResponse.json({});
})
);
server.listen();
@@ -144,7 +144,7 @@ function PanelDataPaneRendered({ model }: SceneComponentProps<PanelDataPane>) {
const currentTab = tabs.find((t) => t.tabId === tab);
return (
<>
<div className={styles.dataPane}>
<TabsBar hideBorder={true} className={styles.tabsBar}>
{tabs.map((t, index) => {
return (
@@ -161,12 +161,19 @@ function PanelDataPaneRendered({ model }: SceneComponentProps<PanelDataPane>) {
<Container>{currentTab && <currentTab.Component model={currentTab} />}</Container>
</TabContent>
</CustomScrollbar>
</>
</div>
);
}
function getStyles(theme: GrafanaTheme2) {
return {
dataPane: css({
display: 'flex',
flexDirection: 'column',
flexGrow: 1,
minHeight: 0,
height: '100%',
}),
tabContent: css({
padding: theme.spacing(2),
border: `1px solid ${theme.colors.border.weak}`,
@@ -1,10 +1,9 @@
import { PanelPlugin, PanelPluginMeta, PluginType } from '@grafana/data';
import { SceneFlexItem, SceneGridItem, SceneGridLayout, SplitLayout, VizPanel } from '@grafana/scenes';
import { SceneGridItem, SceneGridLayout, VizPanel } from '@grafana/scenes';
import { DashboardScene } from '../scene/DashboardScene';
import { activateFullSceneTree } from '../utils/test-utils';
import { PanelDataPane } from './PanelDataPane/PanelDataPane';
import { buildPanelEditScene } from './PanelEditor';
let pluginToLoad: PanelPlugin | undefined;
@@ -47,8 +46,7 @@ describe('PanelEditor', () => {
const deactivate = activateFullSceneTree(scene);
const vizManager = editScene.state.panelRef.resolve();
vizManager.state.panel.setState({ title: 'changed title' });
editScene.state.vizManager.state.panel.setState({ title: 'changed title' });
deactivate();
@@ -72,7 +70,7 @@ describe('PanelEditor', () => {
activateFullSceneTree(scene);
expect(((editScene.state.body as SplitLayout).state.primary as SplitLayout).state.secondary).toBeUndefined();
expect(editScene.state.dataPane).toBeUndefined();
});
it('should exist if panel is supporting querying', () => {
@@ -88,10 +86,7 @@ describe('PanelEditor', () => {
});
activateFullSceneTree(scene);
const secondaryPane = ((editScene.state.body as SplitLayout).state.primary as SplitLayout).state.secondary;
expect(secondaryPane).toBeInstanceOf(SceneFlexItem);
expect((secondaryPane as SceneFlexItem).state.body).toBeInstanceOf(PanelDataPane);
expect(editScene.state.dataPane).toBeDefined();
});
});
});
@@ -2,17 +2,7 @@ import * as H from 'history';
import { NavIndex } from '@grafana/data';
import { config, locationService } from '@grafana/runtime';
import {
SceneFlexItem,
SceneFlexLayout,
SceneGridItem,
SceneObject,
SceneObjectBase,
SceneObjectRef,
SceneObjectState,
SplitLayout,
VizPanel,
} from '@grafana/scenes';
import { SceneGridItem, SceneObject, SceneObjectBase, SceneObjectState, VizPanel } from '@grafana/scenes';
import {
findVizPanelByKey,
@@ -27,11 +17,12 @@ import { PanelOptionsPane } from './PanelOptionsPane';
import { VizPanelManager } from './VizPanelManager';
export interface PanelEditorState extends SceneObjectState {
body: SceneObject;
controls?: SceneObject[];
isDirty?: boolean;
panelId: number;
panelRef: SceneObjectRef<VizPanelManager>;
optionsPane?: PanelOptionsPane;
dataPane?: PanelDataPane;
vizManager: VizPanelManager;
}
export class PanelEditor extends SceneObjectBase<PanelEditorState> {
@@ -42,14 +33,41 @@ export class PanelEditor extends SceneObjectBase<PanelEditorState> {
public constructor(state: PanelEditorState) {
super(state);
this.addActivationHandler(() => {
return () => {
if (!this._discardChanges) {
this.commitChanges();
}
};
});
this.addActivationHandler(this._activationHandler.bind(this));
}
private _activationHandler() {
const panelManager = this.state.vizManager;
const panel = panelManager.state.panel;
this._subs.add(
panelManager.subscribeToState((n, p) => {
if (n.panel.state.pluginId !== p.panel.state.pluginId) {
this._initDataPane(n.panel.state.pluginId);
}
})
);
this._initDataPane(panel.state.pluginId);
return () => {
if (!this._discardChanges) {
this.commitChanges();
}
};
}
private _initDataPane(pluginId: string) {
const skipDataQuery = config.panels[pluginId].skipDataQuery;
if (!skipDataQuery && !this.state.dataPane) {
this.setState({ dataPane: new PanelDataPane(this.state.vizManager) });
} else if (this.state.dataPane) {
locationService.partial({ tab: null }, true);
this.setState({ dataPane: undefined });
}
}
public getUrlKey() {
return this.state.panelId.toString();
}
@@ -76,10 +94,20 @@ export class PanelEditor extends SceneObjectBase<PanelEditorState> {
dashboard.onEnterEditMode();
}
const panelMngr = this.state.panelRef.resolve();
if (sourcePanel!.parent instanceof SceneGridItem) {
sourcePanel!.parent.setState({ body: panelMngr.state.panel.clone() });
sourcePanel!.parent.setState({ body: this.state.vizManager.state.panel.clone() });
}
}
public toggleOptionsPane(withOpenVizPicker?: boolean) {
if (this.state.optionsPane) {
this.setState({ optionsPane: undefined });
} else {
this.setState({
optionsPane: new PanelOptionsPane({
isVizPickerOpen: withOpenVizPicker,
}),
});
}
}
}
@@ -90,78 +118,7 @@ export function buildPanelEditScene(panel: VizPanel): PanelEditor {
return new PanelEditor({
panelId: getPanelIdForVizPanel(panel),
panelRef: vizPanelMgr.getRef(),
body: new SplitLayout({
direction: 'row',
initialSize: 0.75,
primary: new SplitLayout({
direction: 'column',
$behaviors: [conditionalDataPaneBehavior],
primary: new SceneFlexLayout({
direction: 'column',
minHeight: 200,
children: [vizPanelMgr],
}),
primaryPaneStyles: {
minHeight: 0,
overflow: 'hidden',
},
secondaryPaneStyles: {
minHeight: 0,
},
}),
secondary: new SceneFlexItem({
body: new PanelOptionsPane(vizPanelMgr),
width: '100%',
}),
primaryPaneStyles: {
minWidth: '0',
},
secondaryPaneStyles: {
minWidth: '0',
},
}),
optionsPane: new PanelOptionsPane({}),
vizManager: vizPanelMgr,
});
}
// This function is used to conditionally add the data pane to the panel editor,
// depending on the type of a panel being edited.
function conditionalDataPaneBehavior(scene: SplitLayout) {
const dashboard = getDashboardSceneFor(scene);
const editor = dashboard.state.editPanel;
if (!editor) {
return;
}
const panelManager = editor.state.panelRef.resolve();
const panel = panelManager.state.panel;
const getDataPane = () =>
new SceneFlexItem({
body: new PanelDataPane(panelManager),
});
if (!config.panels[panel.state.pluginId].skipDataQuery) {
scene.setState({
secondary: getDataPane(),
});
}
const sub = panelManager.subscribeToState((n, p) => {
const hadDataSupport = !config.panels[p.panel.state.pluginId].skipDataQuery;
const willHaveDataSupport = !config.panels[n.panel.state.pluginId].skipDataQuery;
if (hadDataSupport && !willHaveDataSupport) {
locationService.partial({ tab: null }, true);
scene.setState({ secondary: undefined });
} else if (!hadDataSupport && willHaveDataSupport) {
scene.setState({ secondary: getDataPane() });
}
});
return () => {
sub.unsubscribe();
};
}
@@ -3,16 +3,17 @@ import React from 'react';
import { GrafanaTheme2 } from '@grafana/data';
import { SceneComponentProps } from '@grafana/scenes';
import { useStyles2 } from '@grafana/ui';
import { Splitter, useStyles2 } from '@grafana/ui';
import { NavToolbarActions } from '../scene/NavToolbarActions';
import { getDashboardSceneFor } from '../utils/utils';
import { PanelEditor } from './PanelEditor';
import { VisualizationButton } from './PanelOptionsPane';
export function PanelEditorRenderer({ model }: SceneComponentProps<PanelEditor>) {
const dashboard = getDashboardSceneFor(model);
const { body } = model.useState();
const { optionsPane, vizManager, dataPane } = model.useState();
const { controls } = dashboard.useState();
const styles = useStyles2(getStyles);
@@ -25,10 +26,34 @@ export function PanelEditorRenderer({ model }: SceneComponentProps<PanelEditor>)
{controls.map((control) => (
<control.Component key={control.state.key} model={control} />
))}
{!optionsPane && (
<VisualizationButton
pluginId={vizManager.state.panel.state.pluginId}
onOpen={() => model.toggleOptionsPane(true)}
isOpen={false}
onTogglePane={() => model.toggleOptionsPane()}
/>
)}
</div>
)}
<div className={styles.body}>
<body.Component model={body} />
<Splitter
direction="row"
dragPosition="end"
initialSize={0.75}
primaryPaneStyles={{ paddingBottom: !dataPane ? 16 : 0 }}
>
<Splitter
direction="column"
primaryPaneStyles={{ minHeight: 0, paddingRight: !optionsPane ? 16 : 0 }}
secondaryPaneStyles={{ minHeight: 0, overflow: 'hidden' }}
dragPosition="start"
>
<vizManager.Component model={vizManager} />
{dataPane && <dataPane.Component model={dataPane} />}
</Splitter>
{optionsPane && <optionsPane.Component model={optionsPane} />}
</Splitter>
</div>
</div>
</>
@@ -11,8 +11,8 @@ import { getPanelFrameCategory2 } from 'app/features/dashboard/components/PanelE
import { getVisualizationOptions2 } from 'app/features/dashboard/components/PanelEditor/getVisualizationOptions';
import { getAllPanelPluginMeta } from 'app/features/panel/state/util';
import { PanelEditor } from './PanelEditor';
import { PanelVizTypePicker } from './PanelVizTypePicker';
import { VizPanelManager } from './VizPanelManager';
export interface PanelOptionsPaneState extends SceneObjectState {
isVizPickerOpen?: boolean;
@@ -21,15 +21,16 @@ export interface PanelOptionsPaneState extends SceneObjectState {
}
export class PanelOptionsPane extends SceneObjectBase<PanelOptionsPaneState> {
public panelManager: VizPanelManager;
public constructor(panelMgr: VizPanelManager) {
public constructor(state: Partial<PanelOptionsPaneState>) {
super({
searchQuery: '',
listMode: OptionFilter.All,
...state,
});
}
this.panelManager = panelMgr;
public getVizManager() {
return sceneGraph.getAncestor(this, PanelEditor).state.vizManager;
}
onToggleVizPicker = () => {
@@ -44,11 +45,14 @@ export class PanelOptionsPane extends SceneObjectBase<PanelOptionsPaneState> {
this.setState({ listMode });
};
onCollapsePane = () => {};
onCollapsePane = () => {
const editor = sceneGraph.getAncestor(this, PanelEditor);
editor.toggleOptionsPane();
};
static Component = ({ model }: SceneComponentProps<PanelOptionsPane>) => {
const { isVizPickerOpen, searchQuery, listMode } = model.useState();
const { panelManager } = model;
const panelManager = model.getVizManager();
const { panel } = panelManager.state;
const dataObject = sceneGraph.getData(panel);
const { data } = dataObject.useState();
@@ -506,11 +506,9 @@ describe('VizPanelManager', () => {
describe('change transformations', () => {
it('should update and reprocess transformations', () => {
const { scene, panel } = setupTest('panel-3');
scene.setState({
editPanel: buildPanelEditScene(panel),
});
scene.setState({ editPanel: buildPanelEditScene(panel) });
const vizPanelManager = scene.state.editPanel!.state.panelRef.resolve();
const vizPanelManager = scene.state.editPanel!.state.vizManager;
vizPanelManager.activate();
vizPanelManager.state.panel.state.$data?.activate();
@@ -560,11 +558,9 @@ describe('VizPanelManager', () => {
describe('dashboard queries', () => {
it('should update queries', () => {
const { scene, panel } = setupTest('panel-3');
scene.setState({
editPanel: buildPanelEditScene(panel),
});
scene.setState({ editPanel: buildPanelEditScene(panel) });
const vizPanelManager = scene.state.editPanel!.state.panelRef.resolve();
const vizPanelManager = scene.state.editPanel!.state.vizManager;
vizPanelManager.activate();
vizPanelManager.state.panel.state.$data?.activate();
@@ -578,6 +574,7 @@ describe('VizPanelManager', () => {
panelId: panelWithTransformations.id,
},
]);
expect(vizPanelManager.panelData).toBeInstanceOf(SceneDataTransformer);
expect(vizPanelManager.queryRunner.state.queries[0].panelId).toEqual(panelWithTransformations.id);
@@ -71,8 +71,7 @@ describe('getSaveDashboardChange', () => {
dashboard.onEnterEditMode();
dashboard.setState({ editPanel: editScene });
const vizManager = editScene.state.panelRef.resolve();
vizManager.state.panel.setState({ title: 'changed title' });
editScene.state.vizManager.state.panel.setState({ title: 'changed title' });
const result = getSaveDashboardChange(dashboard, false, true);
const panelSaveModel = result.changedSaveModel.panels![0];
@@ -147,7 +147,7 @@ class ResolveInspectPanelByKey extends SceneObjectBase<ResolveInspectPanelByKeyS
let panel = findVizPanelByKey(dashboard, panelId);
if (dashboard.state.editPanel) {
panel = dashboard.state.editPanel.state.panelRef.resolve().state.panel;
panel = dashboard.state.editPanel.state.vizManager.state.panel;
}
if (dashboard.state.viewPanelScene && dashboard.state.viewPanelScene.state.body) {
@@ -1,9 +1,9 @@
import 'whatwg-fetch';
import { screen, waitFor } from '@testing-library/react';
import userEvent from '@testing-library/user-event';
import { rest } from 'msw';
import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
import 'whatwg-fetch';
import { BootData, DataQuery } from '@grafana/data/src';
import { selectors as e2eSelectors } from '@grafana/e2e-selectors/src';
import { reportInteraction, setEchoSrv } from '@grafana/runtime';
@@ -87,20 +87,27 @@ afterEach(() => {
});
const getNonExistentPublicDashboardResponse = () =>
rest.get('/api/dashboards/uid/:dashboardUid/public-dashboards', (req, res, ctx) => {
return res(
ctx.status(404),
ctx.json({
http.get('/api/dashboards/uid/:dashboardUid/public-dashboards', () => {
return HttpResponse.json(
{
message: 'Public dashboard not found',
messageId: 'publicdashboards.notFound',
statusCode: 404,
traceID: '',
})
},
{
status: 404,
}
);
});
const getErrorPublicDashboardResponse = () =>
rest.get('/api/dashboards/uid/:dashboardUid/public-dashboards', (req, res, ctx) => {
return res(ctx.status(500));
http.get('/api/dashboards/uid/:dashboardUid/public-dashboards', () => {
return HttpResponse.json(
{},
{
status: 500,
}
);
});
const alertTests = () => {
@@ -277,14 +284,11 @@ describe('SharePublic - Already persisted', () => {
});
it('when modal is opened, then time range switch is enabled and not checked when its not checked in the db', async () => {
server.use(
rest.get('/api/dashboards/uid/:dashboardUid/public-dashboards', (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
...pubdashResponse,
timeSelectionEnabled: false,
})
);
http.get('/api/dashboards/uid/:dashboardUid/public-dashboards', () => {
return HttpResponse.json({
...pubdashResponse,
timeSelectionEnabled: false,
});
})
);
@@ -303,17 +307,16 @@ describe('SharePublic - Already persisted', () => {
});
it('when pubdash is disabled in the db, then link url is not copyable and switch is checked', async () => {
server.use(
rest.get('/api/dashboards/uid/:dashboardUid/public-dashboards', (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
isEnabled: false,
annotationsEnabled: false,
uid: 'a-uid',
dashboardUid: req.params.dashboardUid,
accessToken: 'an-access-token',
})
);
http.get('/api/dashboards/uid/:dashboardUid/public-dashboards', ({ request }) => {
const url = new URL(request.url);
const dashboardUid = url.searchParams.get('dashboardUid');
return HttpResponse.json({
isEnabled: false,
annotationsEnabled: false,
uid: 'a-uid',
dashboardUid,
accessToken: 'an-access-token',
});
})
);
@@ -339,15 +342,14 @@ describe('SharePublic - Report interactions', () => {
jest.clearAllMocks();
server.use(getExistentPublicDashboardResponse());
server.use(
rest.patch('/api/dashboards/uid/:dashboardUid/public-dashboards/:uid', (req, res, ctx) =>
res(
ctx.status(200),
ctx.json({
...pubdashResponse,
dashboardUid: req.params.dashboardUid,
})
)
)
http.patch('/api/dashboards/uid/:dashboardUid/public-dashboards/:uid', ({ request }) => {
const url = new URL(request.url);
const dashboardUid = url.searchParams.get('dashboardUid');
return HttpResponse.json({
...pubdashResponse,
dashboardUid,
});
})
);
});
@@ -1,5 +1,6 @@
import 'whatwg-fetch';
import { fireEvent, render, screen, waitFor, waitForElementToBeRemoved } from '@testing-library/react';
import { rest } from 'msw';
import { http, HttpResponse } from 'msw';
import React from 'react';
import { Provider } from 'react-redux';
@@ -32,15 +33,14 @@ export const pubdashResponse: sharePublicDashboardUtils.PublicDashboard = {
};
export const getExistentPublicDashboardResponse = (publicDashboard?: Partial<PublicDashboard>) =>
rest.get('/api/dashboards/uid/:dashboardUid/public-dashboards', (req, res, ctx) => {
return res(
ctx.status(200),
ctx.json({
...pubdashResponse,
...publicDashboard,
dashboardUid: req.params.dashboardUid,
})
);
http.get('/api/dashboards/uid/:dashboardUid/public-dashboards', ({ request }) => {
const url = new URL(request.url);
const dashboardUid = url.searchParams.get('dashboardUid');
return HttpResponse.json({
...pubdashResponse,
...publicDashboard,
dashboardUid,
});
});
export const renderSharePublicDashboard = async (
@@ -164,7 +164,7 @@ describe('LogsTable', () => {
});
});
it('should not render `tsNs`', async () => {
it('should not render `tsNs` column', async () => {
setup(undefined, getMockLokiFrame());
await waitFor(() => {
@@ -174,6 +174,28 @@ describe('LogsTable', () => {
});
});
it('should render numeric field aligned right', async () => {
setup(
{
columnsWithMeta: {
Time: { active: true, percentOfLinesWithLabel: 100, index: 0 },
line: { active: true, percentOfLinesWithLabel: 100, index: 1 },
tsNs: { active: true, percentOfLinesWithLabel: 100, index: 2 },
},
},
getMockLokiFrame()
);
await waitFor(() => {
const columns = screen.queryAllByRole('columnheader', { name: 'tsNs' });
expect(columns.length).toBe(1);
});
const cells = screen.queryAllByRole('cell');
expect(cells[cells.length - 1].style.textAlign).toBe('right');
});
it('should not render `labels`', async () => {
setup();
@@ -9,6 +9,7 @@ import {
DataTransformerConfig,
Field,
FieldType,
guessFieldTypeForField,
LogsSortOrder,
sortDataFrame,
SplitOpen,
@@ -86,6 +87,9 @@ export function LogsTable(props: Props) {
// This sets the individual field value as filterable
filterable: isFieldFilterable(field, logsFrame?.bodyField.name ?? '', logsFrame?.timeField.name ?? ''),
};
// If it's a string, then try to guess for a better type for numeric support in viz
field.type = field.type === FieldType.string ? guessFieldTypeForField(field) ?? FieldType.string : field.type;
}
return frameWithOverrides;
@@ -1,8 +1,8 @@
import 'whatwg-fetch';
import { render, screen, waitForElementToBeRemoved, within } from '@testing-library/react';
import { rest } from 'msw';
import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
import React from 'react';
import 'whatwg-fetch';
import { BrowserRouter } from 'react-router-dom';
import { TestProvider } from 'test/helpers/TestProvider';
import { getGrafanaContextMock } from 'test/mocks/getGrafanaContextMock';
@@ -60,10 +60,13 @@ const paginationResponse: Omit<PublicDashboardListWithPaginationResponse, 'publi
};
const server = setupServer(
rest.get('/api/dashboards/public-dashboards', (_, res, ctx) =>
res(ctx.status(200), ctx.json({ ...paginationResponse, publicDashboards: publicDashboardListResponse }))
http.get('/api/dashboards/public-dashboards', () =>
HttpResponse.json({
...paginationResponse,
publicDashboards: publicDashboardListResponse,
})
),
rest.delete('/api/dashboards/uid/:dashboardUid/public-dashboards/:uid', (_, res, ctx) => res(ctx.status(200)))
http.delete('/api/dashboards/uid/:dashboardUid/public-dashboards/:uid', () => HttpResponse.json({}))
);
jest.mock('@grafana/runtime', () => ({
@@ -122,8 +125,8 @@ describe('Show table', () => {
};
server.use(
rest.get('/api/dashboards/public-dashboards', (req, res, ctx) => {
return res(ctx.status(200), ctx.json(emptyListRS));
http.get('/api/dashboards/public-dashboards', () => {
return HttpResponse.json(emptyListRS);
})
);
@@ -171,8 +174,8 @@ describe('Orphaned public dashboard', () => {
publicDashboards: [...publicDashboardListResponse, ...orphanedDashboardListResponse],
};
server.use(
rest.get('/api/dashboards/public-dashboards', (req, res, ctx) => {
return res(ctx.status(200), ctx.json(response));
http.get('/api/dashboards/public-dashboards', () => {
return HttpResponse.json(response);
})
);
jest.spyOn(contextSrv, 'hasPermission').mockReturnValue(true);
@@ -11,6 +11,7 @@ export default {
small: 'https://grafana.com/api/plugins/alexanderzobnin-zabbix-app/versions/4.2.2/logos/small',
large: 'https://grafana.com/api/plugins/alexanderzobnin-zabbix-app/versions/4.2.2/logos/large',
},
keywords: ['zabbix', 'monitoring', 'dashboard'],
},
isCore: false,
isDev: false,
@@ -9,6 +9,7 @@ export default {
downloads: 33645089,
featured: 180,
id: 74,
keywords: ['zabbix', 'monitoring', 'dashboard'],
typeId: 1,
typeName: 'Application',
internal: false,
@@ -17,6 +17,7 @@ const plugin: CatalogPlugin = {
id: 'test-plugin',
info: {
logos: { small: '', large: '' },
keywords: ['test', 'plugin'],
},
name: 'Testing Plugin',
orgName: 'Test',
@@ -15,6 +15,7 @@ const plugin: CatalogPlugin = {
id: 'test-plugin',
info: {
logos: { small: '', large: '' },
keywords: ['test', 'plugin'],
},
name: 'Testing Plugin',
orgName: 'Test',
@@ -32,6 +32,7 @@ const getMockPlugin = (id: string): CatalogPlugin => {
small: 'https://grafana.com/api/plugins/test-plugin/versions/0.0.10/logos/small',
large: 'https://grafana.com/api/plugins/test-plugin/versions/0.0.10/logos/large',
},
keywords: ['test', 'plugin'],
},
name: 'Testing Plugin',
orgName: 'Test',
@@ -42,6 +42,7 @@ describe('PluginListItem', () => {
small: 'https://grafana.com/api/plugins/test-plugin/versions/0.0.10/logos/small',
large: 'https://grafana.com/api/plugins/test-plugin/versions/0.0.10/logos/large',
},
keywords: ['test', 'plugin'],
},
name: 'Testing Plugin',
orgName: 'Test',
@@ -18,6 +18,7 @@ describe('PluginListItemBadges', () => {
small: 'https://grafana.com/api/plugins/test-plugin/versions/0.0.10/logos/small',
large: 'https://grafana.com/api/plugins/test-plugin/versions/0.0.10/logos/large',
},
keywords: ['test', 'plugin'],
},
name: 'Testing Plugin',
orgName: 'Test',
@@ -140,6 +140,7 @@ describe('Plugins/Helpers', () => {
large: 'https://grafana.com/api/plugins/alexanderzobnin-zabbix-app/versions/4.1.5/logos/large',
small: 'https://grafana.com/api/plugins/alexanderzobnin-zabbix-app/versions/4.1.5/logos/small',
},
keywords: ['zabbix', 'monitoring', 'dashboard'],
},
error: undefined,
isCore: false,
@@ -266,6 +267,7 @@ describe('Plugins/Helpers', () => {
small: 'https://grafana.com/api/plugins/alexanderzobnin-zabbix-app/versions/4.1.5/logos/small',
large: 'https://grafana.com/api/plugins/alexanderzobnin-zabbix-app/versions/4.1.5/logos/large',
},
keywords: ['zabbix', 'monitoring', 'dashboard'],
},
error: undefined,
isCore: false,
+31 -2
View File
@@ -1,3 +1,5 @@
import uFuzzy from '@leeoniya/ufuzzy';
import { PluginSignatureStatus, dateTimeParse, PluginError, PluginType, PluginErrorCode } from '@grafana/data';
import { config, featureEnabled } from '@grafana/runtime';
import configCore, { Settings } from 'app/core/config';
@@ -86,6 +88,7 @@ export function mapRemoteToCatalog(plugin: RemotePlugin, error?: PluginError): C
createdAt: publishedAt,
status,
angularDetected,
keywords,
} = plugin;
const isDisabled = !!error || isDisabledSecretsPlugin(typeCode);
@@ -98,6 +101,7 @@ export function mapRemoteToCatalog(plugin: RemotePlugin, error?: PluginError): C
small: `https://grafana.com/api/plugins/${id}/versions/${version}/logos/small`,
large: `https://grafana.com/api/plugins/${id}/versions/${version}/logos/large`,
},
keywords,
},
name,
orgName,
@@ -123,7 +127,7 @@ export function mapRemoteToCatalog(plugin: RemotePlugin, error?: PluginError): C
export function mapLocalToCatalog(plugin: LocalPlugin, error?: PluginError): CatalogPlugin {
const {
name,
info: { description, version, logos, updated, author },
info: { description, version, logos, updated, author, keywords },
id,
dev,
type,
@@ -140,7 +144,7 @@ export function mapLocalToCatalog(plugin: LocalPlugin, error?: PluginError): Cat
description,
downloads: 0,
id,
info: { logos },
info: { logos, keywords },
name,
orgName: author.name,
popularity: 0,
@@ -173,6 +177,7 @@ export function mapToCatalogPlugin(local?: LocalPlugin, remote?: RemotePlugin, e
const id = remote?.slug || local?.id || '';
const type = local?.type || remote?.typeCode;
const isDisabled = !!error || isDisabledSecretsPlugin(type);
const keywords = remote?.keywords || local?.info.keywords || [];
let logos = {
small: `/public/img/icn-${type}.svg`,
@@ -195,6 +200,7 @@ export function mapToCatalogPlugin(local?: LocalPlugin, remote?: RemotePlugin, e
id,
info: {
logos,
keywords,
},
isCore: Boolean(remote?.internal || local?.signature === PluginSignatureStatus.internal),
isDev: Boolean(local?.dev),
@@ -345,3 +351,26 @@ function isDisabledSecretsPlugin(type?: PluginType): boolean {
export function isLocalCorePlugin(local?: LocalPlugin): boolean {
return Boolean(local?.signature === 'internal');
}
function getId(inputString: string): string {
const parts = inputString.split(' - ');
return parts[0];
}
function getPluginDetailsForFuzzySearch(plugins: CatalogPlugin[]): string[] {
return plugins.reduce((result: string[], { id, name, type, orgName, info }: CatalogPlugin) => {
const keywordsForSearch = info.keywords?.join(' ').toLowerCase();
const pluginString = `${id} - ${name} - ${type} - ${orgName} - ${keywordsForSearch}`;
result.push(pluginString);
return result;
}, []);
}
export function filterByKeyword(plugins: CatalogPlugin[], query: string) {
const dataArray = getPluginDetailsForFuzzySearch(plugins);
let uf = new uFuzzy({});
let idxs = uf.filter(dataArray, query);
if (idxs === null) {
return null;
}
return idxs.map((id) => getId(dataArray[id]));
}
@@ -183,13 +183,19 @@ describe('Browse list of plugins', () => {
describe('when searching', () => {
it('should only list plugins matching search', async () => {
const { queryByText } = renderBrowse('/plugins?filterBy=all&q=zabbix', [
getCatalogPluginMock({ id: 'zabbix', name: 'Zabbix' }),
getCatalogPluginMock({ id: 'plugin-2', name: 'Plugin 2' }),
getCatalogPluginMock({ id: 'plugin-3', name: 'Plugin 3' }),
const { queryByText } = renderBrowse('/plugins?filterBy=all&q=matches', [
getCatalogPluginMock({ id: 'matches-the-search', name: 'Matches the search' }),
getCatalogPluginMock({
id: 'plugin-2',
name: 'Plugin 2',
}),
getCatalogPluginMock({
id: 'plugin-3',
name: 'Plugin 3',
}),
]);
await waitFor(() => expect(queryByText('Zabbix')).toBeInTheDocument());
await waitFor(() => expect(queryByText('Matches the search')).toBeInTheDocument());
// Other plugin types shouldn't be shown
expect(queryByText('Plugin 2')).not.toBeInTheDocument();
@@ -39,6 +39,7 @@ export default function Browse({ route }: GrafanaRouteComponentProps): ReactElem
},
sortBy
);
const filterByOptions = [
{ value: 'all', label: 'All' },
{ value: 'installed', label: 'Installed' },
@@ -2,6 +2,7 @@ import { createSelector } from '@reduxjs/toolkit';
import { PluginError, PluginType, unEscapeStringFromRegex } from '@grafana/data';
import { filterByKeyword } from '../helpers';
import { RequestStatus, PluginCatalogStoreState } from '../types';
import { pluginsAdapter } from './reducer';
@@ -32,11 +33,14 @@ export type PluginFilters = {
export const selectPlugins = (filters: PluginFilters) =>
createSelector(selectAll, (plugins) => {
const keyword = filters.keyword ? unEscapeStringFromRegex(filters.keyword.toLowerCase()) : '';
const filteredPluginIds = keyword !== '' ? filterByKeyword(plugins, keyword) : null;
return plugins.filter((plugin) => {
const fieldsToSearchIn = [plugin.name, plugin.orgName].filter(Boolean).map((f) => f.toLowerCase());
if (keyword && filteredPluginIds == null) {
return false;
}
if (keyword && !fieldsToSearchIn.some((f) => f.includes(keyword))) {
if (keyword && !filteredPluginIds?.includes(plugin.id)) {
return false;
}
@@ -83,6 +83,7 @@ export interface CatalogPluginInfo {
large: string;
small: string;
};
keywords: string[];
}
export type RemotePlugin = {
@@ -93,6 +94,7 @@ export type RemotePlugin = {
featured: number;
id: number;
internal: boolean;
keywords: string[];
json?: {
dependencies: PluginDependencies;
iam?: IdentityAccessManagement;
@@ -161,6 +163,7 @@ export type LocalPlugin = WithAccessControlMetadata & {
small: string;
large: string;
};
keywords: string[];
build: Build;
screenshots?: Array<{
path: string;
@@ -1,4 +1,5 @@
import { rest } from 'msw';
import 'whatwg-fetch';
import { http, HttpResponse } from 'msw';
import { setupServer } from 'msw/node';
export const mockSystemModule = `System.register(['./dependencyA'], function (_export, _context) {
@@ -85,38 +86,104 @@ export const mockModuleWithDefineMethod = `ace.define(function() {
});`;
const server = setupServer(
rest.get('/public/plugins/mockAmdModule/module.js', async (_req, res, ctx) =>
res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockAmdModule))
http.get(
'/public/plugins/mockAmdModule/module.js',
() =>
new HttpResponse(mockAmdModule, {
headers: {
'Content-Type': 'text/javascript',
},
})
),
rest.get('/public/plugins/mockSystemModule/module.js', async (_req, res, ctx) =>
res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockSystemModule))
http.get(
'/public/plugins/mockSystemModule/module.js',
() =>
new HttpResponse(mockSystemModule, {
headers: {
'Content-Type': 'text/javascript',
},
})
),
rest.get('http://my-cdn.com/plugins/my-plugin/v1.0.0/public/plugins/my-plugin/module.js', async (_req, res, ctx) =>
res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockAmdModule))
http.get(
'http://my-cdn.com/plugins/my-plugin/v1.0.0/public/plugins/my-plugin/module.js',
() =>
new HttpResponse(mockAmdModule, {
headers: {
'Content-Type': 'text/javascript',
},
})
),
rest.get('/public/plugins/mockAmdModuleNamedNoDeps/module.js', async (_req, res, ctx) =>
res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockAmdModuleNamedNoDeps))
http.get(
'/public/plugins/mockAmdModuleNamedNoDeps/module.js',
() =>
new HttpResponse(mockAmdModuleNamedNoDeps, {
headers: {
'Content-Type': 'text/javascript',
},
})
),
rest.get('/public/plugins/mockAmdModuleNamedWithDeps/module.js', async (_req, res, ctx) =>
res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockAmdModuleNamedWithDeps))
http.get(
'/public/plugins/mockAmdModuleNamedWithDeps/module.js',
() =>
new HttpResponse(mockAmdModuleNamedWithDeps, {
headers: {
'Content-Type': 'text/javascript',
},
})
),
rest.get('/public/plugins/mockAmdModuleNamedWithDeps2/module.js', async (_req, res, ctx) =>
res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockAmdModuleNamedWithDeps2))
http.get(
'/public/plugins/mockAmdModuleNamedWithDeps2/module.js',
() =>
new HttpResponse(mockAmdModuleNamedWithDeps2, {
headers: {
'Content-Type': 'text/javascript',
},
})
),
rest.get('/public/plugins/mockAmdModuleNamedWithDeps3/module.js', async (_req, res, ctx) =>
res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockAmdModuleNamedWithDeps3))
http.get(
'/public/plugins/mockAmdModuleNamedWithDeps3/module.js',
() =>
new HttpResponse(mockAmdModuleNamedWithDeps3, {
headers: {
'Content-Type': 'text/javascript',
},
})
),
rest.get('/public/plugins/mockAmdModuleOnlyFunction/module.js', async (_req, res, ctx) =>
res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockAmdModuleOnlyFunction))
http.get(
'/public/plugins/mockAmdModuleOnlyFunction/module.js',
() =>
new HttpResponse(mockAmdModuleOnlyFunction, {
headers: {
'Content-Type': 'text/javascript',
},
})
),
rest.get('/public/plugins/mockAmdModuleWithComments/module.js', async (_req, res, ctx) =>
res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockAmdModuleWithComments))
http.get(
'/public/plugins/mockAmdModuleWithComments/module.js',
() =>
new HttpResponse(mockAmdModuleWithComments, {
headers: {
'Content-Type': 'text/javascript',
},
})
),
rest.get('/public/plugins/mockAmdModuleWithComments2/module.js', async (_req, res, ctx) =>
res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockAmdModuleWithComments2))
http.get(
'/public/plugins/mockAmdModuleWithComments2/module.js',
() =>
new HttpResponse(mockAmdModuleWithComments2, {
headers: {
'Content-Type': 'text/javascript',
},
})
),
rest.get('/public/plugins/mockModuleWithDefineMethod/module.js', async (_req, res, ctx) =>
res(ctx.status(200), ctx.set('Content-Type', 'text/javascript'), ctx.body(mockModuleWithDefineMethod))
http.get(
'/public/plugins/mockModuleWithDefineMethod/module.js',
() =>
new HttpResponse(mockModuleWithDefineMethod, {
headers: {
'Content-Type': 'text/javascript',
},
})
)
);
@@ -28,11 +28,13 @@ describe('SystemJS Loader Hooks', () => {
const originalFetch = systemJSPrototype.fetch;
const originalResolve = systemJSPrototype.resolve;
systemJSPrototype.resolve = (moduleId: string) => moduleId;
systemJSPrototype.shouldFetch = () => true;
beforeAll(() => {
server.listen();
systemJSPrototype.resolve = (moduleId: string) => moduleId;
systemJSPrototype.shouldFetch = () => true;
// because server.listen() patches fetch, we need to reassign this to the systemJSPrototype
// this is identical to what happens in the original code: https://github.com/systemjs/systemjs/blob/main/src/features/fetch-load.js#L12
systemJSPrototype.fetch = window.fetch;
});
afterEach(() => server.resetHandlers());
afterAll(() => {
@@ -43,7 +45,11 @@ describe('SystemJS Loader Hooks', () => {
describe('decorateSystemJSFetch', () => {
it('wraps AMD modules in an AMD iife', async () => {
const basicResult = await decorateSystemJSFetch(originalFetch, '/public/plugins/mockAmdModule/module.js', {});
const basicResult = await decorateSystemJSFetch(
systemJSPrototype.fetch,
'/public/plugins/mockAmdModule/module.js',
{}
);
const basicSource = await basicResult.text();
const basicExpected = `(function(define) {
${mockAmdModule}
@@ -51,7 +57,7 @@ describe('SystemJS Loader Hooks', () => {
expect(basicSource).toBe(basicExpected);
const mockAmdModuleNamedNoDepsResult = await decorateSystemJSFetch(
originalFetch,
systemJSPrototype.fetch,
'/public/plugins/mockAmdModuleNamedNoDeps/module.js',
{}
);
@@ -63,7 +69,7 @@ describe('SystemJS Loader Hooks', () => {
expect(mockAmdModuleNamedNoDepsSource).toBe(mockAmdModuleNamedNoDepsExpected);
const mockAmdModuleNamedWithDepsResult = await decorateSystemJSFetch(
originalFetch,
systemJSPrototype.fetch,
'/public/plugins/mockAmdModuleNamedWithDeps/module.js',
{}
);
@@ -75,7 +81,7 @@ describe('SystemJS Loader Hooks', () => {
expect(mockAmdModuleNamedWithDepsSource).toBe(mockAmdModuleNamedWithDepsExpected);
const mockAmdModuleNamedWithDeps2Result = await decorateSystemJSFetch(
originalFetch,
systemJSPrototype.fetch,
'/public/plugins/mockAmdModuleNamedWithDeps2/module.js',
{}
);
@@ -87,7 +93,7 @@ describe('SystemJS Loader Hooks', () => {
expect(mockAmdModuleNamedWithDeps2Source).toBe(mockAmdModuleNamedWithDeps2Expected);
const mockAmdModuleNamedWithDeps3Result = await decorateSystemJSFetch(
originalFetch,
systemJSPrototype.fetch,
'/public/plugins/mockAmdModuleNamedWithDeps3/module.js',
{}
);
@@ -99,7 +105,7 @@ describe('SystemJS Loader Hooks', () => {
expect(mockAmdModuleNamedWithDeps3Source).toBe(mockAmdModuleNamedWithDeps3Expected);
const mockAmdModuleOnlyFunctionResult = await decorateSystemJSFetch(
originalFetch,
systemJSPrototype.fetch,
'/public/plugins/mockAmdModuleOnlyFunction/module.js',
{}
);
@@ -111,7 +117,7 @@ describe('SystemJS Loader Hooks', () => {
expect(mockAmdModuleOnlyFunctionSource).toBe(mockAmdModuleOnlyFunctionExpected);
const mockAmdModuleWithCommentsResult = await decorateSystemJSFetch(
originalFetch,
systemJSPrototype.fetch,
'/public/plugins/mockAmdModuleWithComments/module.js',
{}
);
@@ -123,7 +129,7 @@ describe('SystemJS Loader Hooks', () => {
expect(mockAmdModuleWithCommentsSource).toBe(mockAmdModuleWithCommentsExpected);
const mockAmdModuleWithComments2Result = await decorateSystemJSFetch(
originalFetch,
systemJSPrototype.fetch,
'/public/plugins/mockAmdModuleWithComments2/module.js',
{}
);
@@ -136,14 +142,14 @@ describe('SystemJS Loader Hooks', () => {
});
it("doesn't wrap system modules in an AMD iife", async () => {
const url = '/public/plugins/mockSystemModule/module.js';
const result = await decorateSystemJSFetch(originalFetch, url, {});
const result = await decorateSystemJSFetch(systemJSPrototype.fetch, url, {});
const source = await result.text();
expect(source).toBe(mockSystemModule);
});
it("doesn't wrap modules with a define method in an AMD iife", async () => {
const url = '/public/plugins/mockModuleWithDefineMethod/module.js';
const result = await decorateSystemJSFetch(originalFetch, url, {});
const result = await decorateSystemJSFetch(systemJSPrototype.fetch, url, {});
const source = await result.text();
expect(source).toBe(mockModuleWithDefineMethod);
@@ -151,13 +157,13 @@ describe('SystemJS Loader Hooks', () => {
it('only transforms plugin source code hosted on cdn with cdn paths', async () => {
config.pluginsCDNBaseURL = 'http://my-cdn.com/plugins';
const cdnUrl = 'http://my-cdn.com/plugins/my-plugin/v1.0.0/public/plugins/my-plugin/module.js';
const cdnResult = await decorateSystemJSFetch(originalFetch, cdnUrl, {});
const cdnResult = await decorateSystemJSFetch(systemJSPrototype.fetch, cdnUrl, {});
const cdnSource = await cdnResult.text();
expect(cdnSource).toContain('var pluginPath = "http://my-cdn.com/plugins/my-plugin/v1.0.0/public/plugins/";');
const url = '/public/plugins/mockAmdModule/module.js';
const result = await decorateSystemJSFetch(originalFetch, url, {});
const result = await decorateSystemJSFetch(systemJSPrototype.fetch, url, {});
const source = await result.text();
expect(source).toContain('var pluginPath = "/public/plugins/";');
});
+17
View File
@@ -27,6 +27,23 @@ module.exports = (path, options) => {
delete pkg['exports'];
delete pkg['module'];
}
// Jest + jsdom acts like a browser (i.e., it looks for "browser" imports
// under pkg.exports), but msw knows that you're operating in a Node
// environment:
//
// https://github.com/mswjs/msw/issues/1786#issuecomment-1782559851
//
// The MSW project's recommended workaround is to disable Jest's
// customExportConditions completely, so no packages use their browser's
// versions. We'll instead clear export conditions only for MSW.
//
// Taken from https://github.com/mswjs/msw/issues/1786#issuecomment-1787730599
if (pkg.name === 'msw') {
delete pkg.exports['./node'].browser;
}
if (pkg.name === '@mswjs/interceptors') {
delete pkg.exports;
}
return pkg;
},
});
+235 -8
View File
@@ -1896,6 +1896,24 @@ __metadata:
languageName: node
linkType: hard
"@bundled-es-modules/cookie@npm:^2.0.0":
version: 2.0.0
resolution: "@bundled-es-modules/cookie@npm:2.0.0"
dependencies:
cookie: "npm:^0.5.0"
checksum: 10/c8ef02aa5d3f6c786cfa407e1c93b4af29c600eb09990973f47a7a49e4771c1bec37c8f8e567638bb9cbc41f4e38d065ff1d8eaf9bf91f0c3613a6d60bc82c8c
languageName: node
linkType: hard
"@bundled-es-modules/statuses@npm:^1.0.1":
version: 1.0.1
resolution: "@bundled-es-modules/statuses@npm:1.0.1"
dependencies:
statuses: "npm:^2.0.1"
checksum: 10/9bf6a2bcf040a66fb805da0e1446041fd9def7468bb5da29c5ce02adf121a3f7cec123664308059a62a46fcaee666add83094b76df6dce72e5cafa8e6bebe60d
languageName: node
linkType: hard
"@colors/colors@npm:1.5.0":
version: 1.5.0
resolution: "@colors/colors@npm:1.5.0"
@@ -4340,6 +4358,45 @@ __metadata:
languageName: node
linkType: hard
"@inquirer/confirm@npm:^3.0.0":
version: 3.0.0
resolution: "@inquirer/confirm@npm:3.0.0"
dependencies:
"@inquirer/core": "npm:^7.0.0"
"@inquirer/type": "npm:^1.2.0"
checksum: 10/ed16dc0e5b22115474853ca57dbe3dacdcd15bcb37cc50020e8e76ff8d0875d62d8b63b93b3092c653faeb6c83a139eac997ff05638b0f1f78ae919f29ee29d4
languageName: node
linkType: hard
"@inquirer/core@npm:^7.0.0":
version: 7.0.0
resolution: "@inquirer/core@npm:7.0.0"
dependencies:
"@inquirer/type": "npm:^1.2.0"
"@types/mute-stream": "npm:^0.0.4"
"@types/node": "npm:^20.11.16"
"@types/wrap-ansi": "npm:^3.0.0"
ansi-escapes: "npm:^4.3.2"
chalk: "npm:^4.1.2"
cli-spinners: "npm:^2.9.2"
cli-width: "npm:^4.1.0"
figures: "npm:^3.2.0"
mute-stream: "npm:^1.0.0"
run-async: "npm:^3.0.0"
signal-exit: "npm:^4.1.0"
strip-ansi: "npm:^6.0.1"
wrap-ansi: "npm:^6.2.0"
checksum: 10/78c0ef4bb82cb7be23f16a80c9cff02839c77e378d272327f49878788a4c3b1cc00137387317053d242a87634954850a4d2546b3e48b1abd27130a21f598afef
languageName: node
linkType: hard
"@inquirer/type@npm:^1.2.0":
version: 1.2.0
resolution: "@inquirer/type@npm:1.2.0"
checksum: 10/12f68a16d8995efb409bd243d6ccc501b366e8009630a075071a9d9497cebd36bbd6c46d7d59b37435629e5e50236394679f414f7676b68b913ecc28a85cba0a
languageName: node
linkType: hard
"@internationalized/date@npm:^3.5.1":
version: 3.5.1
resolution: "@internationalized/date@npm:3.5.1"
@@ -5207,6 +5264,13 @@ __metadata:
languageName: node
linkType: hard
"@mswjs/cookies@npm:^1.1.0":
version: 1.1.0
resolution: "@mswjs/cookies@npm:1.1.0"
checksum: 10/168ed1966e579a4f454e6d2af5a015150cca570ac4c660f5b656e7bc021afacbf0b3d4ed3d03e9293550f3965c28ce1e293fa7037c6cf46ed7e268e21a1053a4
languageName: node
linkType: hard
"@mswjs/interceptors@npm:^0.17.10":
version: 0.17.10
resolution: "@mswjs/interceptors@npm:0.17.10"
@@ -5223,6 +5287,20 @@ __metadata:
languageName: node
linkType: hard
"@mswjs/interceptors@npm:^0.25.16":
version: 0.25.16
resolution: "@mswjs/interceptors@npm:0.25.16"
dependencies:
"@open-draft/deferred-promise": "npm:^2.2.0"
"@open-draft/logger": "npm:^0.3.0"
"@open-draft/until": "npm:^2.0.0"
is-node-process: "npm:^1.2.0"
outvariant: "npm:^1.2.1"
strict-event-emitter: "npm:^0.5.1"
checksum: 10/d8fb74db45a63971e9da7367c8d120343c8f49fec7bcc3f0c77c04c3f628d307b70875f52e4a99df561547b92d0d53edacc421e42d69940d44999254b5d028b5
languageName: node
linkType: hard
"@ndelangen/get-tarball@npm:^3.0.7":
version: 3.0.7
resolution: "@ndelangen/get-tarball@npm:3.0.7"
@@ -5655,6 +5733,23 @@ __metadata:
languageName: node
linkType: hard
"@open-draft/deferred-promise@npm:^2.2.0":
version: 2.2.0
resolution: "@open-draft/deferred-promise@npm:2.2.0"
checksum: 10/bc3bb1668a555bb87b33383cafcf207d9561e17d2ca0d9e61b7ce88e82b66e36a333d3676c1d39eb5848022c03c8145331fcdc828ba297f88cb1de9c5cef6c19
languageName: node
linkType: hard
"@open-draft/logger@npm:^0.3.0":
version: 0.3.0
resolution: "@open-draft/logger@npm:0.3.0"
dependencies:
is-node-process: "npm:^1.2.0"
outvariant: "npm:^1.4.0"
checksum: 10/7a280f170bcd4e91d3eedbefe628efd10c3bd06dd2461d06a7fdbced89ef457a38785847f88cc630fb4fd7dfa176d6f77aed17e5a9b08000baff647433b5ff78
languageName: node
linkType: hard
"@open-draft/until@npm:^1.0.3":
version: 1.0.3
resolution: "@open-draft/until@npm:1.0.3"
@@ -5662,6 +5757,13 @@ __metadata:
languageName: node
linkType: hard
"@open-draft/until@npm:^2.0.0, @open-draft/until@npm:^2.1.0":
version: 2.1.0
resolution: "@open-draft/until@npm:2.1.0"
checksum: 10/622be42950afc8e89715d0fd6d56cbdcd13e36625e23b174bd3d9f06f80e25f9adf75d6698af93bca1e1bf465b9ce00ec05214a12189b671fb9da0f58215b6f4
languageName: node
linkType: hard
"@opentelemetry/api-logs@npm:0.45.1":
version: 0.45.1
resolution: "@opentelemetry/api-logs@npm:0.45.1"
@@ -8750,6 +8852,13 @@ __metadata:
languageName: node
linkType: hard
"@types/cookie@npm:^0.6.0":
version: 0.6.0
resolution: "@types/cookie@npm:0.6.0"
checksum: 10/b883348d5bf88695fbc2c2276b1c49859267a55cae3cf11ea1dccc1b3be15b466e637ce3242109ba27d616c77c6aa4efe521e3d557110b4fdd9bc332a12445c2
languageName: node
linkType: hard
"@types/cross-spawn@npm:^6.0.2":
version: 6.0.3
resolution: "@types/cross-spawn@npm:6.0.3"
@@ -9532,6 +9641,15 @@ __metadata:
languageName: node
linkType: hard
"@types/mute-stream@npm:^0.0.4":
version: 0.0.4
resolution: "@types/mute-stream@npm:0.0.4"
dependencies:
"@types/node": "npm:*"
checksum: 10/af8d83ad7b68ea05d9357985daf81b6c9b73af4feacb2f5c2693c7fd3e13e5135ef1bd083ce8d5bdc8e97acd28563b61bb32dec4e4508a8067fcd31b8a098632
languageName: node
linkType: hard
"@types/node-fetch@npm:^2.6.4":
version: 2.6.4
resolution: "@types/node-fetch@npm:2.6.4"
@@ -9567,7 +9685,7 @@ __metadata:
languageName: node
linkType: hard
"@types/node@npm:20.11.17":
"@types/node@npm:20.11.17, @types/node@npm:^20.11.16":
version: 20.11.17
resolution: "@types/node@npm:20.11.17"
dependencies:
@@ -9986,6 +10104,13 @@ __metadata:
languageName: node
linkType: hard
"@types/statuses@npm:^2.0.4":
version: 2.0.4
resolution: "@types/statuses@npm:2.0.4"
checksum: 10/3a806c3b96d1845e3e7441fbf0839037e95f717334760ddb7c29223c9a34a7206b68e2998631f89f1a1e3ef5b67b15652f6e8fa14987ebd7f6d38587c1bffd18
languageName: node
linkType: hard
"@types/string-hash@npm:1.1.3":
version: 1.1.3
resolution: "@types/string-hash@npm:1.1.3"
@@ -10090,6 +10215,13 @@ __metadata:
languageName: node
linkType: hard
"@types/wrap-ansi@npm:^3.0.0":
version: 3.0.0
resolution: "@types/wrap-ansi@npm:3.0.0"
checksum: 10/8aa644946ca4e859668c36b8e2bcf2ac4bdee59dac760414730ea57be8a93ae9166ebd40a088f2ab714843aaea2a2a67f0e6e6ec11cfc9c8701b2466ca1c4089
languageName: node
linkType: hard
"@types/ws@npm:^8.5.5":
version: 8.5.5
resolution: "@types/ws@npm:8.5.5"
@@ -13023,6 +13155,13 @@ __metadata:
languageName: node
linkType: hard
"cli-spinners@npm:^2.9.2":
version: 2.9.2
resolution: "cli-spinners@npm:2.9.2"
checksum: 10/a0a863f442df35ed7294424f5491fa1756bd8d2e4ff0c8736531d886cec0ece4d85e8663b77a5afaf1d296e3cbbebff92e2e99f52bbea89b667cbe789b994794
languageName: node
linkType: hard
"cli-table3@npm:^0.6.1, cli-table3@npm:~0.6.1":
version: 0.6.3
resolution: "cli-table3@npm:0.6.3"
@@ -13053,6 +13192,13 @@ __metadata:
languageName: node
linkType: hard
"cli-width@npm:^4.1.0":
version: 4.1.0
resolution: "cli-width@npm:4.1.0"
checksum: 10/b58876fbf0310a8a35c79b72ecfcf579b354e18ad04e6b20588724ea2b522799a758507a37dfe132fafaf93a9922cafd9514d9e1598e6b2cd46694853aed099f
languageName: node
linkType: hard
"cliui@npm:^7.0.2":
version: 7.0.4
resolution: "cliui@npm:7.0.4"
@@ -13637,6 +13783,13 @@ __metadata:
languageName: node
linkType: hard
"cookie@npm:^0.5.0":
version: 0.5.0
resolution: "cookie@npm:0.5.0"
checksum: 10/aae7911ddc5f444a9025fbd979ad1b5d60191011339bce48e555cb83343d0f98b865ff5c4d71fecdfb8555a5cafdc65632f6fce172f32aaf6936830a883a0380
languageName: node
linkType: hard
"copy-to-clipboard@npm:^3.3.1":
version: 3.3.1
resolution: "copy-to-clipboard@npm:3.3.1"
@@ -18470,7 +18623,7 @@ __metadata:
mousetrap: "npm:1.6.5"
mousetrap-global-bind: "npm:1.1.0"
moveable: "npm:0.53.0"
msw: "npm:1.3.2"
msw: "npm:2.2.0"
mutationobserver-shim: "npm:0.3.7"
nanoid: "npm:^5.0.4"
ngtemplate-loader: "npm:2.1.0"
@@ -18805,6 +18958,13 @@ __metadata:
languageName: node
linkType: hard
"headers-polyfill@npm:^4.0.2":
version: 4.0.2
resolution: "headers-polyfill@npm:4.0.2"
checksum: 10/70b53abf48a1d50760150624d6c7ca974a0d286ba102e411538f6dad6687ce51ce7cc60197e326df96f844548d6ff77d900e28c3cdbc0ba1fe09a05eae47156a
languageName: node
linkType: hard
"heimdalljs-logger@npm:^0.1.10, heimdalljs-logger@npm:^0.1.7":
version: 0.1.10
resolution: "heimdalljs-logger@npm:0.1.10"
@@ -23005,6 +23165,38 @@ __metadata:
languageName: node
linkType: hard
"msw@npm:2.2.0":
version: 2.2.0
resolution: "msw@npm:2.2.0"
dependencies:
"@bundled-es-modules/cookie": "npm:^2.0.0"
"@bundled-es-modules/statuses": "npm:^1.0.1"
"@inquirer/confirm": "npm:^3.0.0"
"@mswjs/cookies": "npm:^1.1.0"
"@mswjs/interceptors": "npm:^0.25.16"
"@open-draft/until": "npm:^2.1.0"
"@types/cookie": "npm:^0.6.0"
"@types/statuses": "npm:^2.0.4"
chalk: "npm:^4.1.2"
graphql: "npm:^16.8.1"
headers-polyfill: "npm:^4.0.2"
is-node-process: "npm:^1.2.0"
outvariant: "npm:^1.4.2"
path-to-regexp: "npm:^6.2.0"
strict-event-emitter: "npm:^0.5.1"
type-fest: "npm:^4.9.0"
yargs: "npm:^17.7.2"
peerDependencies:
typescript: ">= 4.7.x <= 5.3.x"
peerDependenciesMeta:
typescript:
optional: true
bin:
msw: cli/index.js
checksum: 10/36e6a1f0bc89d1c84bf24c1cf7ca7c3fe5d5b032c825d52a832e9b815830976a86c17a8c3f1f506db720f44e99d04c9302e014cf569b51b2d2af62562a9fe62a
languageName: node
linkType: hard
"multicast-dns@npm:^7.2.4":
version: 7.2.4
resolution: "multicast-dns@npm:7.2.4"
@@ -23044,7 +23236,7 @@ __metadata:
languageName: node
linkType: hard
"mute-stream@npm:~1.0.0":
"mute-stream@npm:^1.0.0, mute-stream@npm:~1.0.0":
version: 1.0.0
resolution: "mute-stream@npm:1.0.0"
checksum: 10/36fc968b0e9c9c63029d4f9dc63911950a3bdf55c9a87f58d3a266289b67180201cade911e7699f8b2fa596b34c9db43dad37649e3f7fdd13c3bb9edb0017ee7
@@ -23940,10 +24132,10 @@ __metadata:
languageName: node
linkType: hard
"outvariant@npm:^1.2.1, outvariant@npm:^1.4.0":
version: 1.4.0
resolution: "outvariant@npm:1.4.0"
checksum: 10/07b9bcb9b3a2ff1b3db02af6b07d70e663082b30ddc08ff475d7c85fc623fdcc4433a4ab5b88f6902b62dbb284eef1be386aa537e14cef0519fad887ec483054
"outvariant@npm:^1.2.1, outvariant@npm:^1.4.0, outvariant@npm:^1.4.2":
version: 1.4.2
resolution: "outvariant@npm:1.4.2"
checksum: 10/f16ba035fb65d1cbe7d2e06693dd42183c46bc8456713d9ddb5182d067defa7d78217edab0a2d3e173d3bacd627b2bd692195c7087c225b82548fbf52c677b38
languageName: node
linkType: hard
@@ -27670,6 +27862,13 @@ __metadata:
languageName: node
linkType: hard
"run-async@npm:^3.0.0":
version: 3.0.0
resolution: "run-async@npm:3.0.0"
checksum: 10/97fb8747f7765b77ebcd311d3a33548099336f04c6434e0763039b98c1de0f1b4421000695aff8751f309c0b995d8dfd620c1f1e4c35572da38c101488165305
languageName: node
linkType: hard
"run-parallel@npm:^1.1.9":
version: 1.2.0
resolution: "run-parallel@npm:1.2.0"
@@ -28113,6 +28312,13 @@ __metadata:
languageName: node
linkType: hard
"signal-exit@npm:^4.1.0":
version: 4.1.0
resolution: "signal-exit@npm:4.1.0"
checksum: 10/c9fa63bbbd7431066174a48ba2dd9986dfd930c3a8b59de9c29d7b6854ec1c12a80d15310869ea5166d413b99f041bfa3dd80a7947bcd44ea8e6eb3ffeabfa1f
languageName: node
linkType: hard
"sigstore@npm:^1.4.0":
version: 1.9.0
resolution: "sigstore@npm:1.9.0"
@@ -28792,6 +28998,13 @@ __metadata:
languageName: node
linkType: hard
"statuses@npm:^2.0.1":
version: 2.0.1
resolution: "statuses@npm:2.0.1"
checksum: 10/18c7623fdb8f646fb213ca4051be4df7efb3484d4ab662937ca6fbef7ced9b9e12842709872eb3020cc3504b93bde88935c9f6417489627a7786f24f8031cbcb
languageName: node
linkType: hard
"std-env@npm:^3.6.0":
version: 3.7.0
resolution: "std-env@npm:3.7.0"
@@ -28941,6 +29154,13 @@ __metadata:
languageName: node
linkType: hard
"strict-event-emitter@npm:^0.5.1":
version: 0.5.1
resolution: "strict-event-emitter@npm:0.5.1"
checksum: 10/25c84d88be85940d3547db665b871bfecea4ea0bedfeb22aae8db48126820cfb2b0bc2fba695392592a09b1aa36b686d6eede499e1ecd151593c03fe5a50d512
languageName: node
linkType: hard
"string-hash@npm:^1.1.3":
version: 1.1.3
resolution: "string-hash@npm:1.1.3"
@@ -30253,6 +30473,13 @@ __metadata:
languageName: node
linkType: hard
"type-fest@npm:^4.9.0":
version: 4.10.2
resolution: "type-fest@npm:4.10.2"
checksum: 10/2b1ad1270d9fabeeb506ba831d513caeb05bfc852e5e012511d785ce9dc68d773fe0a42bddf857a362c7f3406244809c5b8a698b743bb7617d4a8c470672087f
languageName: node
linkType: hard
"type-is@npm:~1.6.18":
version: 1.6.18
resolution: "type-is@npm:1.6.18"
@@ -31930,7 +32157,7 @@ __metadata:
languageName: node
linkType: hard
"yargs@npm:17.7.2, yargs@npm:^17.3.1, yargs@npm:^17.5.1, yargs@npm:^17.6.2":
"yargs@npm:17.7.2, yargs@npm:^17.3.1, yargs@npm:^17.5.1, yargs@npm:^17.6.2, yargs@npm:^17.7.2":
version: 17.7.2
resolution: "yargs@npm:17.7.2"
dependencies: