diff --git a/docs/.github/img/kouncil_cluster_form.png b/docs/.github/img/kouncil_cluster_form.png new file mode 100644 index 00000000..da792aea Binary files /dev/null and b/docs/.github/img/kouncil_cluster_form.png differ diff --git a/docs/.github/img/kouncil_cluster_form_cluster_security.png b/docs/.github/img/kouncil_cluster_form_cluster_security.png new file mode 100644 index 00000000..78e8fcc3 Binary files /dev/null and b/docs/.github/img/kouncil_cluster_form_cluster_security.png differ diff --git a/docs/.github/img/kouncil_cluster_form_schema_registry.png b/docs/.github/img/kouncil_cluster_form_schema_registry.png new file mode 100644 index 00000000..c04cec58 Binary files /dev/null and b/docs/.github/img/kouncil_cluster_form_schema_registry.png differ diff --git a/docs/.github/img/kouncil_user_groups_permissions.png b/docs/.github/img/kouncil_user_groups_permissions.png new file mode 100644 index 00000000..06a091c5 Binary files /dev/null and b/docs/.github/img/kouncil_user_groups_permissions.png differ diff --git a/docs/.github/img/kouncil_user_groups_permissions_relogin.png b/docs/.github/img/kouncil_user_groups_permissions_relogin.png new file mode 100644 index 00000000..aa66ad59 Binary files /dev/null and b/docs/.github/img/kouncil_user_groups_permissions_relogin.png differ diff --git a/docs/SUMMARY.md b/docs/SUMMARY.md index 01d7bbb2..dcff3ce8 100644 --- a/docs/SUMMARY.md +++ b/docs/SUMMARY.md @@ -9,6 +9,7 @@ * [Authentication](configuration/security/AUTHENTICATION.md) * [Authorization](configuration/security/AUTHORIZATION.md) * SSL/TLS Configuration + * [Configuration](configuration/KAFKA_CLUSTER.md) * Kafka * [TLS configuration](configuration/kafka/TLS.md) * [Broker SSL configuration](configuration/kafka/SASL_PLAIN.md) diff --git a/docs/configuration/KAFKA_CLUSTER.md b/docs/configuration/KAFKA_CLUSTER.md new file mode 100644 index 00000000..67b694dd --- /dev/null +++ b/docs/configuration/KAFKA_CLUSTER.md @@ -0,0 +1,29 @@ +## Managing Kafka clusters + +Starting from version 1.9 you will be able to configure and secure your Kafka clusters from UI. To +do it log in to the app and select Clusters menu item. You will see your clusters list. To add new +cluster click `Add new cluster` button and cluster form will be opened. + +

+ +

+ +### Cluster SSL/TLS configuration + +If your Kafka cluster requires any authentication you are able to configure `SASL`, `SSL` +or `AWS MSK` authentication. + +

+ +

+ +### Schema registry + +Within this form you are able to add Schema Registry to your cluster. + +

+ +

+ +If your Schema Registry requires any authentication you are able to configure `SSL` +or `SSL with basic authentication` security. diff --git a/docs/configuration/kafka/AWS_MSK.md b/docs/configuration/kafka/AWS_MSK.md index 30ad95f4..9af26d36 100644 --- a/docs/configuration/kafka/AWS_MSK.md +++ b/docs/configuration/kafka/AWS_MSK.md @@ -1,5 +1,11 @@ ## Advanced config - Amazon MSK Kafka cluster +{% hint style="warning" %} +**WARNING** + +This configuration will be deprecated in version 1.9 and removed in the future. In version 1.9 this configuration will be used to preload your clusters. +{% endhint %} + If one of your brokers in cluster environment is located in Amazon MSK cluster you should specify `saslMechanism`, `saslProtocol`, `saslJassConfig` and `saslCallbackHandler` for this broker, like this: ```yaml diff --git a/docs/configuration/kafka/SASL_PLAIN.md b/docs/configuration/kafka/SASL_PLAIN.md index 513e6974..ddffa963 100644 --- a/docs/configuration/kafka/SASL_PLAIN.md +++ b/docs/configuration/kafka/SASL_PLAIN.md @@ -1,5 +1,11 @@ ## Advanced config - SASL Plain Authentication +{% hint style="warning" %} +**WARNING** + +This configuration will be deprecated in version 1.9 and removed in the future. In version 1.9 this configuration will be used to preload your clusters. +{% endhint %} + If one of your brokers in cluster environment needs SASL authentication you should specify `saslMechanism`, `saslProtocol` and `saslJassConfig` for this broker, like this: ```yaml diff --git a/docs/configuration/kafka/TLS.md b/docs/configuration/kafka/TLS.md index 07dc5555..7b91bb07 100644 --- a/docs/configuration/kafka/TLS.md +++ b/docs/configuration/kafka/TLS.md @@ -1,5 +1,11 @@ ## Advanced config - TLS +{% hint style="warning" %} +**WARNING** + +This configuration will be deprecated in version 1.9 and removed in the future. In version 1.9 this configuration will be used to preload your clusters. +{% endhint %} + Let's assume that your Kafka is secured and you need mTLS to connect. You need to provide a client truststore, containing CA public certificate and keystore with both client private key and CA signed certificate. Then add "kafka" node to your yaml with the following values: diff --git a/docs/configuration/schema-registry/SCHEMA_REGISTRY_SSL.md b/docs/configuration/schema-registry/SCHEMA_REGISTRY_SSL.md index f71b3d63..25683afd 100644 --- a/docs/configuration/schema-registry/SCHEMA_REGISTRY_SSL.md +++ b/docs/configuration/schema-registry/SCHEMA_REGISTRY_SSL.md @@ -1,5 +1,11 @@ ## Advanced config - SSL Schema registry +{% hint style="warning" %} +**WARNING** + +This configuration will be deprecated in version 1.9 and removed in the future. In version 1.9 this configuration will be used to preload your clusters. +{% endhint %} + Let's assume that your SchemaRegistry is secured and you need SSL to connect. You need to provide a client truststore, containing CA public certificate and keystore with both client private key and CA signed certificate. ```yaml diff --git a/docs/configuration/schema-registry/SCHEMA_REGISTRY_SSL_BASIC_AUTH.md b/docs/configuration/schema-registry/SCHEMA_REGISTRY_SSL_BASIC_AUTH.md index 89c08dc2..e5924e10 100644 --- a/docs/configuration/schema-registry/SCHEMA_REGISTRY_SSL_BASIC_AUTH.md +++ b/docs/configuration/schema-registry/SCHEMA_REGISTRY_SSL_BASIC_AUTH.md @@ -1,5 +1,11 @@ ## Advanced config - Schema registry SSL and BASIC Authentication +{% hint style="warning" %} +**WARNING** + +This configuration will be deprecated in version 1.9 and removed in the future. In version 1.9 this configuration will be used to preload your clusters. +{% endhint %} + Let's assume that your SchemaRegistry is secured and you need SSL and BASIC authentication to connect. You need to provide a client truststore, containing CA public certificate and keystore with both client private key and CA signed certificate. And fot the BASIC authentication you need to provide user-info which will be use to authenticate when Kouncil will connect to Schema Registry. diff --git a/docs/configuration/security/AUTHORIZATION.md b/docs/configuration/security/AUTHORIZATION.md index 9a73eec9..a8f6c635 100644 --- a/docs/configuration/security/AUTHORIZATION.md +++ b/docs/configuration/security/AUTHORIZATION.md @@ -1,14 +1,29 @@ ## Authorization -Kouncil allows to restrict access to pages and functions for users. To achieve that you should add to you configuration file appropriate properties. -There are three of them, `kouncil.authorization.role-admin`, `kouncil.authorization.role-editor`, `kouncil.authorization.role-viewer`. + +{% hint style="warning" %} +**WARNING** + +This configuration will be deprecated in version 1.9 and removed in 1.10. In version 1.9 this +configuration will be used to preload user groups and based on that create permissions for each +group. +{% endhint %} + +Kouncil allows to restrict access to pages and functions for users. To achieve that you should add +to you configuration file appropriate properties. +There are three of +them, `kouncil.authorization.role-admin`, `kouncil.authorization.role-editor`, `kouncil.authorization.role-viewer`. Each one of this will allow user to do specific actions in Kouncil. Users with roles assigned to: + * `kouncil.authorization.role-admin` can view brokers and consumer groups pages. -* `kouncil.authorization.role-editor` can view topics, event tracker pages and sent messages to topics. +* `kouncil.authorization.role-editor` can view topics, event tracker pages and sent messages to + topics. * `kouncil.authorization.role-viewer` can only view topics and event tracker pages. -As a values in these parameters you should provide semicolon (`;`) separated list of groups defined in selected authentication provider (`inmemory`, `LDAP`, `AD`, `SSO`). +As a values in these parameters you should provide semicolon (`;`) separated list of groups defined +in selected authentication provider (`inmemory`, `LDAP`, `AD`, `SSO`). For the default configuration, we have defined user groups: + ```yaml kouncil: authorization: @@ -16,9 +31,12 @@ kouncil: role-editor: editor_group role-viewer: viewer_group ``` -These will be used in any authentication method unless you override them in any of your configuration files, which are used by Kouncil. + +These will be used in any authentication method unless you override them in any of your +configuration files, which are used by Kouncil. Example roles configuration: + ```yaml kouncil: authorization: @@ -27,7 +45,9 @@ kouncil: role-viewer: KOUNCIL_VIEWER;viewer_group ``` -To get LDAP user groups in LDAP configuration we have to add few additional parameters (`group-search-base`, `group-search-filter`, `group-role-attribute`) +To get LDAP user groups in LDAP configuration we have to add few additional +parameters (`group-search-base`, `group-search-filter`, `group-role-attribute`) + ```yaml kouncil: auth: @@ -42,3 +62,22 @@ kouncil: group-search-filter: "(memberuid={0})" group-role-attribute: "cn" ``` + +### Configuration + +Since version 1.9 configuration of user groups and user groups permissions is available from UI. + +

+ +

+ +When permissions will change users will see the message that re-login is required. + +

+ +

+ +By default, users with groups assigned to `kouncil.authorization.role-admin` will +be able to manage user groups and user groups permissions. + + diff --git a/kouncil-backend/src/main/java/com/consdata/kouncil/config/cluster/ClusterConfigReader.java b/kouncil-backend/src/main/java/com/consdata/kouncil/config/cluster/ClusterConfigReader.java index 2976c5f8..2348bb1c 100644 --- a/kouncil-backend/src/main/java/com/consdata/kouncil/config/cluster/ClusterConfigReader.java +++ b/kouncil-backend/src/main/java/com/consdata/kouncil/config/cluster/ClusterConfigReader.java @@ -39,9 +39,9 @@ import org.springframework.stereotype.Component; /** - * @deprecated will be removed in version 1.10. + * @deprecated will be removed in the future. */ -@Deprecated(since = "version 1.10") +@Deprecated @Component @Data @RequiredArgsConstructor diff --git a/kouncil-backend/src/main/java/com/consdata/kouncil/config/security/UserGroupsConfigReader.java b/kouncil-backend/src/main/java/com/consdata/kouncil/config/security/UserGroupsConfigReader.java index 6254b3b5..b4661fb5 100644 --- a/kouncil-backend/src/main/java/com/consdata/kouncil/config/security/UserGroupsConfigReader.java +++ b/kouncil-backend/src/main/java/com/consdata/kouncil/config/security/UserGroupsConfigReader.java @@ -24,9 +24,9 @@ import org.springframework.stereotype.Component; /** - * @deprecated will be removed in version 1.10. + * @deprecated will be removed in the future. */ -@Deprecated(since = "version 1.10") +@Deprecated @Component @Data @RequiredArgsConstructor diff --git a/kouncil-frontend/apps/kouncil/src/app/topic/toolbar/topic-toolbar.component.scss b/kouncil-frontend/apps/kouncil/src/app/topic/toolbar/topic-toolbar.component.scss index a88d37ac..f44c4f28 100644 --- a/kouncil-frontend/apps/kouncil/src/app/topic/toolbar/topic-toolbar.component.scss +++ b/kouncil-frontend/apps/kouncil/src/app/topic/toolbar/topic-toolbar.component.scss @@ -14,7 +14,7 @@ align-items: center; & > * { - margin-right: 16px; + margin-right: 8px; } } @@ -25,7 +25,7 @@ font-weight: 500; border-radius: $default-border-radius; height: 40px; - padding: 0 12px; + padding: 0 8px; background: $main-0; border: 1px solid $main-20; @@ -113,6 +113,14 @@ } .offset-wrapper { + @media screen and (max-width: 1680px) { + max-width: 175px; + } + + @media screen and (max-width: 1440px) { + max-width: 150px; + } + .offset-input { font-size: 14px; line-height: $default-line-height; diff --git a/kouncil-frontend/apps/kouncil/src/app/topic/topic-partitions.component.scss b/kouncil-frontend/apps/kouncil/src/app/topic/topic-partitions.component.scss index 65d7a021..2aac4ee2 100644 --- a/kouncil-frontend/apps/kouncil/src/app/topic/topic-partitions.component.scss +++ b/kouncil-frontend/apps/kouncil/src/app/topic/topic-partitions.component.scss @@ -1 +1,12 @@ @import '../../styles/palette'; + + +.partitions { + @media screen and (max-width: 1680px) { + max-width: 170px; + } + + @media screen and (max-width: 1440px) { + max-width: 150px; + } +} diff --git a/kouncil-frontend/apps/kouncil/src/app/topic/topic-partitions.component.ts b/kouncil-frontend/apps/kouncil/src/app/topic/topic-partitions.component.ts index 7f3c94b2..fd486ed7 100644 --- a/kouncil-frontend/apps/kouncil/src/app/topic/topic-partitions.component.ts +++ b/kouncil-frontend/apps/kouncil/src/app/topic/topic-partitions.component.ts @@ -6,7 +6,7 @@ import {ServersService} from '@app/common-servers'; @Component({ selector: 'app-topic-partitions', template: ` - + All partitions {{i}} diff --git a/kouncil-frontend/libs/common-components/src/lib/text-field/text-field.component.ts b/kouncil-frontend/libs/common-components/src/lib/text-field/text-field.component.ts index 6fe6c997..ed00bdd0 100644 --- a/kouncil-frontend/libs/common-components/src/lib/text-field/text-field.component.ts +++ b/kouncil-frontend/libs/common-components/src/lib/text-field/text-field.component.ts @@ -21,7 +21,7 @@ import {FormGroup, NG_VALUE_ACCESSOR} from '@angular/forms'; Field value is not unique - + Field value is incorrect diff --git a/kouncil-frontend/libs/feat-topic-form/src/lib/topic/topic-form.component.scss b/kouncil-frontend/libs/feat-topic-form/src/lib/topic/topic-form.component.scss index 0b3c7820..8a8e36b3 100644 --- a/kouncil-frontend/libs/feat-topic-form/src/lib/topic/topic-form.component.scss +++ b/kouncil-frontend/libs/feat-topic-form/src/lib/topic/topic-form.component.scss @@ -1,5 +1,6 @@ @use '../../../../../apps/kouncil/src/styles/buttons'; @import '../../../../../apps/kouncil/src/styles/palette'; +@import "../../../../../apps/kouncil/src/styles/spaces"; :host { .topic-form { @@ -10,18 +11,16 @@ display: flex; flex-wrap: wrap; justify-content: space-between; - margin-bottom: 20px; width: 100%; .topic-form-field { width: 100%; - padding-bottom: 10px; + padding-bottom: $space-4; } } .actions { - float: right; - margin-top: 20px; + margin-top: $space-6; .action-button-blue { @include buttons.button-blue; @@ -33,7 +32,7 @@ .action-button-white { @include buttons.button-white; - margin-right: 10px; + margin-right: $space-4; } } } diff --git a/kouncil-frontend/libs/feat-topic-form/src/lib/topic/topic-form.component.ts b/kouncil-frontend/libs/feat-topic-form/src/lib/topic/topic-form.component.ts index 0fc72c8b..831954ac 100644 --- a/kouncil-frontend/libs/feat-topic-form/src/lib/topic/topic-form.component.ts +++ b/kouncil-frontend/libs/feat-topic-form/src/lib/topic/topic-form.component.ts @@ -12,49 +12,47 @@ import {SnackBarComponent, SnackBarData, ViewMode} from '@app/common-utils'; @Component({ selector: 'app-topic-form', template: ` - -
-
-
- {{ header }} -
-
- close -
- -
-
- -
+
+
+ {{ header }} +
+
+ close +
-
- -
+ +
+
+ +
-
- -
+
+
-
- - +
+
- - +
+ + +
+ + +
`, styleUrls: ['./topic-form.component.scss'] }) diff --git a/kouncil-frontend/libs/feat-user-groups/src/lib/user-groups/form/user-group-form.component.scss b/kouncil-frontend/libs/feat-user-groups/src/lib/user-groups/form/user-group-form.component.scss index 734e0297..8dfa732a 100644 --- a/kouncil-frontend/libs/feat-user-groups/src/lib/user-groups/form/user-group-form.component.scss +++ b/kouncil-frontend/libs/feat-user-groups/src/lib/user-groups/form/user-group-form.component.scss @@ -10,7 +10,6 @@ display: flex; flex-wrap: wrap; justify-content: space-between; - margin-bottom: $space-6; width: 100%; .user-group-form-field { @@ -20,7 +19,6 @@ } .actions { - float: right; margin-top: $space-6; .action-button-blue { diff --git a/kouncil-frontend/libs/feat-user-groups/src/lib/user-groups/form/user-group-form.component.ts b/kouncil-frontend/libs/feat-user-groups/src/lib/user-groups/form/user-group-form.component.ts index a64e7f53..53c1d3ab 100644 --- a/kouncil-frontend/libs/feat-user-groups/src/lib/user-groups/form/user-group-form.component.ts +++ b/kouncil-frontend/libs/feat-user-groups/src/lib/user-groups/form/user-group-form.component.ts @@ -19,40 +19,38 @@ import {UserGroup} from '../../user-groups-functions-matrix/user-groups.model'; @Component({ selector: 'app-user-group-form', template: ` - -
-
-
- {{ header }} -
-
- close -
- -
-
- -
+
+
+ {{ header }} +
+
+ close +
-
- -
+ +
+
+
-
- - +
+
- - +
+ + +
+ + +
`, styleUrls: ['./user-group-form.component.scss'] }) @@ -63,11 +61,11 @@ export class UserGroupFormComponent implements OnInit, OnDestroy { userGroupForm: FormGroup = new FormGroup({ id: new FormControl(), code: new FormControl('', { - validators: [Validators.required], + validators: [Validators.required, this.noOnlyWhitespace], asyncValidators: this.isUserGroupCodeUnique(), updateOn: 'change' }), - name: new FormControl('', [Validators.required]), + name: new FormControl('', [Validators.required, this.noOnlyWhitespace]), }); viewMode: ViewMode = ViewMode.CREATE; ViewMode: typeof ViewMode = ViewMode; @@ -149,4 +147,12 @@ export class UserGroupFormComponent implements OnInit, OnDestroy { : of(null); }; } + + noOnlyWhitespace(control: FormControl): ValidationErrors | null { + if (control.value) { + const isWhitespace = (control.value || '').trim().length === 0; + return !isWhitespace ? null : {'noOnlyWhitespace': true}; + } + return null; + } }