DaanHoogland commented on code in PR #8942:
URL: https://github.com/apache/cloudstack/pull/8942#discussion_r1677903550


##########
api/src/main/java/org/apache/cloudstack/api/command/user/gui/themes/CreateGuiThemeCmd.java:
##########
@@ -0,0 +1,131 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.gui.themes;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.GuiThemeResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.gui.themes.GuiThemeJoinVO;
+import org.apache.cloudstack.gui.themes.GuiThemeVO;
+import org.apache.cloudstack.gui.themes.GuiThemeService;
+
+import javax.inject.Inject;
+
+@APICommand(name = "createGuiTheme", description = "Creates a customized GUI 
theme for a set of Common Names (fixed or wildcard), a set of domain UUIDs, 
and/or a set of " +
+        "account UUIDs.", responseObject = GuiThemeResponse.class, entityType 
= {GuiThemeVO.class}, requestHasSensitiveInfo = false, responseHasSensitiveInfo 
= false,
+        since = "4.20.0.0", authorized = {RoleType.Admin})
+public class CreateGuiThemeCmd extends BaseCmd {
+
+    @Inject
+    GuiThemeService guiThemeService;
+
+    @Parameter(name = ApiConstants.NAME, required = true, type = 
CommandType.STRING, length = 2048, description = "A name to identify the 
theme.")
+    private String name;
+
+    @Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, 
length = 4096, description = "A description for the theme.")
+    private String description;
+
+    @Parameter(name = ApiConstants.CSS, type = CommandType.STRING, length = 
65535, description = "The CSS to be retrieved and imported into the GUI " +
+            "when matching the theme access configurations.")
+    private String css;
+
+    @Parameter(name = ApiConstants.JSON_CONFIGURATION, type = 
CommandType.STRING, length = 65535, description = "The JSON with the 
configurations to be " +
+            "retrieved and imported into the GUI when matching the theme 
access configurations.")
+    private String jsonConfiguration;
+
+    @Parameter(name = ApiConstants.COMMON_NAMES, type = CommandType.STRING, 
length = 65535, description = "A set of Common Names (CN) (fixed or " +
+            "wildcard) separated by comma that can retrieve the theme; e.g.: 
*acme.com,acme2.com")
+    private String commonNames;
+
+    @Parameter(name = ApiConstants.DOMAIN_IDS, type = CommandType.STRING, 
length = 65535, description = "A set of domain UUIDs (also known as ID for " +
+            "the end-user) separated by comma that can retrieve the theme.")
+    private String domainIds;
+
+    @Parameter(name = ApiConstants.ACCOUNT_IDS, type = CommandType.STRING, 
length = 65535, description = "A set of account UUIDs (also known as ID for" +
+            " the end-user) separated by comma that can retrieve the theme.")
+    private String accountIds;
+
+    @Parameter(name = ApiConstants.IS_PUBLIC, type = CommandType.BOOLEAN, 
description = "Defines whether a theme can be retrieved by anyone when only " +
+            "the `commonNames` is informed. If the `domainIds` or `accountIds` 
is informed, it is considered as `false`.")
+    private Boolean isPublic = true;
+
+    @Parameter(name = ApiConstants.RECURSIVE_DOMAINS, type = 
CommandType.BOOLEAN, description = "Defines whether the subdomains of the 
informed domains are considered. Default " +
+            "value is false.")
+    private Boolean recursiveDomains = false;
+
+    public String getName() {
+        return name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public String getCss() {
+        return css;
+    }
+
+    public String getJsonConfiguration() {
+        return jsonConfiguration;
+    }
+
+    public String getCommonNames() {
+        return commonNames;
+    }
+
+    public String getDomainIds() {
+        return domainIds;
+    }
+
+    public String getAccountIds() {
+        return accountIds;
+    }
+
+    public Boolean getPublic() {
+        return isPublic;
+    }
+
+    public Boolean getRecursiveDomains() {
+        return recursiveDomains;
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails(String.format("Name: %s, 
AccountIDs: %s, DomainIDs: %s, RecursiveDomains: %s, CommonNames: %s", 
getName(), getAccountIds(),

Review Comment:
   i would rather exprect this on the service call and not in the command 
class. What were your considderations to put it here @BryanMLima ?



##########
api/src/main/java/org/apache/cloudstack/api/command/user/gui/themes/RemoveGuiThemeCmd.java:
##########
@@ -0,0 +1,61 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.gui.themes;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.response.GuiThemeResponse;
+import org.apache.cloudstack.api.response.SuccessResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.gui.themes.GuiThemeVO;
+import org.apache.cloudstack.gui.themes.GuiThemeService;
+
+import javax.inject.Inject;
+
+@APICommand(name = "removeGuiTheme", description = "Removes an existing GUI 
theme.", responseObject = GuiThemeResponse.class, entityType = 
{GuiThemeVO.class},
+        since = "4.20.0.0", requestHasSensitiveInfo = false, 
responseHasSensitiveInfo = false, authorized = {RoleType.Admin})
+public class RemoveGuiThemeCmd extends BaseCmd {
+
+    @Inject
+    GuiThemeService guiThemeService;
+
+    @Parameter(name = ApiConstants.ID, type = CommandType.UUID, entityType = 
GuiThemeResponse.class, required = true,
+            description = "The unique identifier of the GUI theme to be 
removed.")
+    private Long id;
+
+    public Long getId() {
+        return id;
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails(String.format("ID: %s", 
getId()));

Review Comment:
   same here, could this be on the service call?



##########
api/src/main/java/org/apache/cloudstack/api/command/user/gui/themes/UpdateGuiThemeCmd.java:
##########
@@ -0,0 +1,138 @@
+// Licensed to the Apache Software Foundation (ASF) under one
+// or more contributor license agreements.  See the NOTICE file
+// distributed with this work for additional information
+// regarding copyright ownership.  The ASF licenses this file
+// to you under the Apache License, Version 2.0 (the
+// "License"); you may not use this file except in compliance
+// with the License.  You may obtain a copy of the License at
+//
+//   http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing,
+// software distributed under the License is distributed on an
+// "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+// KIND, either express or implied.  See the License for the
+// specific language governing permissions and limitations
+// under the License.
+package org.apache.cloudstack.api.command.user.gui.themes;
+
+import org.apache.cloudstack.acl.RoleType;
+import org.apache.cloudstack.api.APICommand;
+import org.apache.cloudstack.api.ApiConstants;
+import org.apache.cloudstack.api.ApiErrorCode;
+import org.apache.cloudstack.api.BaseCmd;
+import org.apache.cloudstack.api.Parameter;
+import org.apache.cloudstack.api.ServerApiException;
+import org.apache.cloudstack.api.response.GuiThemeResponse;
+import org.apache.cloudstack.context.CallContext;
+import org.apache.cloudstack.gui.themes.GuiThemeJoinVO;
+import org.apache.cloudstack.gui.themes.GuiThemeVO;
+import org.apache.cloudstack.gui.themes.GuiThemeService;
+
+import javax.inject.Inject;
+
+
+@APICommand(name = "updateGuiTheme", description = "Updates an existing GUI 
theme.", responseObject = GuiThemeResponse.class, entityType = 
{GuiThemeVO.class},
+        since = "4.20.0.0", requestHasSensitiveInfo = false, 
responseHasSensitiveInfo = false, authorized = {RoleType.Admin})
+public class UpdateGuiThemeCmd extends BaseCmd {
+
+    @Inject
+    GuiThemeService guiThemeService;
+
+    @Parameter(name = ApiConstants.ID, required = true, type = 
CommandType.UUID, entityType = GuiThemeResponse.class, description = "The ID of 
the theme to be updated.")
+    private Long id;
+
+    @Parameter(name = ApiConstants.NAME, type = CommandType.STRING, length = 
2048, description = "A name to identify the theme.")
+    private String name;
+
+    @Parameter(name = ApiConstants.DESCRIPTION, type = CommandType.STRING, 
length = 4096, description = "A description for the theme.")
+    private String description;
+
+    @Parameter(name = ApiConstants.CSS, type = CommandType.STRING, length = 
65535, description = "The CSS to be retrieved and imported into the GUI " +
+            "when matching the theme access configurations.")
+    private String css;
+
+    @Parameter(name = ApiConstants.JSON_CONFIGURATION, type = 
CommandType.STRING, length = 65535, description = "The JSON with the 
configurations to be " +
+            "retrieved and imported into the GUI when matching the theme 
access configurations.")
+    private String jsonConfiguration;
+
+    @Parameter(name = ApiConstants.COMMON_NAMES, type = CommandType.STRING, 
length = 65535, description = "A set of Common Names (CN) (fixed or " +
+            "wildcard) separated by comma that can retrieve the theme; e.g.: 
*acme.com,acme2.com")
+    private String commonNames;
+
+    @Parameter(name = ApiConstants.DOMAIN_IDS, type = CommandType.STRING, 
length = 65535, description = "A set of domain UUIDs (also known as ID for " +
+            "the end-user) separated by comma that can retrieve the theme.")
+    private String domainIds;
+
+    @Parameter(name = ApiConstants.RECURSIVE_DOMAINS, type = 
CommandType.BOOLEAN, description = "Defines whether the subdomains of the 
informed domains are considered. Default " +
+            "value is false.")
+    private Boolean recursiveDomains = false;
+
+    @Parameter(name = ApiConstants.ACCOUNT_IDS, type = CommandType.STRING, 
length = 65535, description = "A set of account UUIDs (also known as ID for" +
+            " the end-user) separated by comma that can retrieve the theme.")
+    private String accountIds;
+
+    @Parameter(name = ApiConstants.IS_PUBLIC, type = CommandType.BOOLEAN, 
description = "Defines whether a theme can be retrieved by anyone when only " +
+            "the `commonNames` is informed. If the `domainIds` or `accountIds` 
is informed, it is considered as `false`.")
+    private Boolean isPublic = true;
+
+    public Long getId() {
+        return id;
+    }
+
+    public String getName() {
+        return name;
+    }
+
+    public String getDescription() {
+        return description;
+    }
+
+    public String getCss() {
+        return css;
+    }
+
+    public String getJsonConfiguration() {
+        return jsonConfiguration;
+    }
+
+    public String getCommonNames() {
+        return commonNames;
+    }
+
+    public String getDomainIds() {
+        return domainIds;
+    }
+
+    public String getAccountIds() {
+        return accountIds;
+    }
+
+    public Boolean getRecursiveDomains() {
+        return recursiveDomains;
+    }
+
+    public Boolean getIsPublic() {
+        return isPublic;
+    }
+
+    @Override
+    public void execute() {
+        CallContext.current().setEventDetails(String.format("ID: %s, Name: %s, 
AccountIDs: %s, DomainIDs: %s, RecursiveDomains: %s, CommonNames: %s", getId(), 
getName(),

Review Comment:
   and here



##########
engine/schema/src/main/resources/META-INF/db/schema-41900to42000.sql:
##########
@@ -0,0 +1,124 @@
+-- Licensed to the Apache Software Foundation (ASF) under one
+-- or more contributor license agreements.  See the NOTICE file
+-- distributed with this work for additional information
+-- regarding copyright ownership.  The ASF licenses this file
+-- to you under the Apache License, Version 2.0 (the
+-- "License"); you may not use this file except in compliance
+-- with the License.  You may obtain a copy of the License at
+--
+--   http://www.apache.org/licenses/LICENSE-2.0
+--
+-- Unless required by applicable law or agreed to in writing,
+-- software distributed under the License is distributed on an
+-- "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+-- KIND, either express or implied.  See the License for the
+-- specific language governing permissions and limitations
+-- under the License.
+
+--;
+-- Schema upgrade from 4.19.0.0 to 4.20.0.0
+--;
+
+-- Add tag column to tables
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.resource_limit', 'tag', 
'varchar(64) DEFAULT NULL COMMENT "tag for the limit" ');
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.resource_count', 'tag', 
'varchar(64) DEFAULT NULL COMMENT "tag for the resource count" ');
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.resource_reservation', 'tag', 
'varchar(64) DEFAULT NULL COMMENT "tag for the resource reservation" ');
+ALTER TABLE `resource_count`
+DROP INDEX `i_resource_count__type_accountId`,
+DROP INDEX `i_resource_count__type_domaintId`,
+ADD UNIQUE INDEX `i_resource_count__type_tag_accountId` 
(`type`,`tag`,`account_id`),
+ADD UNIQUE INDEX `i_resource_count__type_tag_domaintId` 
(`type`,`tag`,`domain_id`);
+
+
+ALTER TABLE `cloud`.`resource_reservation`
+    ADD COLUMN `resource_id` bigint unsigned NULL;
+
+ALTER TABLE `cloud`.`resource_reservation`
+    MODIFY COLUMN `amount` bigint NOT NULL;
+
+
+-- Update Default System offering for Router to 512MiB
+UPDATE `cloud`.`service_offering` SET ram_size = 512 WHERE unique_name IN 
("Cloud.Com-SoftwareRouter", "Cloud.Com-SoftwareRouter-Local",
+                                                                           
"Cloud.Com-InternalLBVm", "Cloud.Com-InternalLBVm-Local",
+                                                                           
"Cloud.Com-ElasticLBVm", "Cloud.Com-ElasticLBVm-Local")
+                                                       AND system_use = 1 AND 
ram_size < 512;
+
+-- NSX Plugin --
+CREATE TABLE `cloud`.`nsx_providers` (
+                                         `id` bigint unsigned NOT NULL 
auto_increment COMMENT 'id',
+                                         `uuid` varchar(40),
+                                         `zone_id` bigint unsigned NOT NULL 
COMMENT 'Zone ID',
+                                         `host_id` bigint unsigned NOT NULL 
COMMENT 'Host ID',
+                                         `provider_name` varchar(40),
+                                         `hostname` varchar(255) NOT NULL,
+                                         `port` varchar(255),
+                                         `username` varchar(255) NOT NULL,
+                                         `password` varchar(255) NOT NULL,
+                                         `tier0_gateway` varchar(255),
+                                         `edge_cluster` varchar(255),
+                                         `transport_zone` varchar(255),
+                                         `created` datetime NOT NULL COMMENT 
'date created',
+                                         `removed` datetime COMMENT 'date 
removed if not null',
+                                         PRIMARY KEY (`id`),
+                                         CONSTRAINT 
`fk_nsx_providers__zone_id` FOREIGN KEY `fk_nsx_providers__zone_id` (`zone_id`) 
REFERENCES `data_center`(`id`) ON DELETE CASCADE,
+                                         INDEX 
`i_nsx_providers__zone_id`(`zone_id`)
+) ENGINE=InnoDB DEFAULT CHARSET=utf8;
+
+-- NSX Plugin --
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.network_offerings','for_nsx', 
'int(1) unsigned DEFAULT "0" COMMENT "is nsx enabled for the resource"');
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.network_offerings','nsx_mode', 
'varchar(32) COMMENT "mode in which the network would route traffic"');
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vpc_offerings','for_nsx', 'int(1) 
unsigned DEFAULT "0" COMMENT "is nsx enabled for the resource"');
+CALL `cloud`.`IDEMPOTENT_ADD_COLUMN`('cloud.vpc_offerings','nsx_mode', 
'varchar(32) COMMENT "mode in which the network would route traffic"');
+
+
+-- Create table to persist quota email template configurations
+CREATE TABLE IF NOT EXISTS `cloud_usage`.`quota_email_configuration`(
+    `account_id` int(11) NOT NULL,
+    `email_template_id` bigint(20) NOT NULL,
+    `enabled` int(1) UNSIGNED NOT NULL,
+    PRIMARY KEY (`account_id`, `email_template_id`),
+    CONSTRAINT `FK_quota_email_configuration_account_id` FOREIGN KEY 
(`account_id`) REFERENCES `cloud_usage`.`quota_account`(`account_id`),
+    CONSTRAINT `FK_quota_email_configuration_email_template_id` FOREIGN KEY 
(`email_template_id`) REFERENCES `cloud_usage`.`quota_email_templates`(`id`));
+
+-- Whitelabel GUI
+CREATE TABLE IF NOT EXISTS `cloud`.`gui_themes` (
+    `id` bigint(20) unsigned NOT NULL auto_increment,
+    `uuid` varchar(255) UNIQUE,
+    `name` varchar(2048) NOT NULL COMMENT 'A name to identify the theme.',
+    `description` varchar(4096) DEFAULT NULL COMMENT 'A description for the 
theme.',
+    `css` text DEFAULT NULL COMMENT 'The CSS to be retrieved and imported into 
the GUI when matching the theme access configurations.',
+    `json_configuration` text DEFAULT NULL COMMENT 'The JSON with the 
configurations to be retrieved and imported into the GUI when matching the 
theme access configurations.',
+    `recursive_domains` tinyint(1) DEFAULT 0 COMMENT 'Defines whether the 
subdomains of the informed domains are considered. Default value is false.',
+    `is_public` tinyint(1) default 1 COMMENT 'Defines whether a theme can be 
retrieved by anyone when only the `internet_domains_names` is informed. If the 
`domain_uuids` or `account_uuids` is informed, it is considered as `false`.',
+    `created` datetime NOT NULL,
+    `removed` datetime DEFAULT NULL,
+    PRIMARY KEY (`id`)
+);
+
+CREATE TABLE IF NOT EXISTS `cloud`.`gui_themes_details` (
+    `id` bigint(20) unsigned NOT NULL auto_increment,
+    `gui_theme_id` bigint(20) unsigned NOT NULL COMMENT 'Foreign key 
referencing the GUI theme on `gui_themes` table.',
+    `type` varchar(100) DEFAULT NULL COMMENT 'The type of GUI theme details. 
Valid options are: `account`, `domain` and `commonName`',
+    `value` text COMMENT 'The value of the `type` details. Can be an UUID 
(account or domain) or internet common name.',
+    PRIMARY KEY (`id`),
+    CONSTRAINT `fk_gui_themes_details__gui_theme_id` FOREIGN KEY 
(`gui_theme_id`) REFERENCES `gui_themes`(`id`)
+);
+
+CREATE OR REPLACE
+    VIEW `cloud`.`gui_themes_view` AS
+SELECT
+    `cloud`.`gui_themes`.`id` AS `id`,
+    `cloud`.`gui_themes`.`uuid` AS `uuid`,
+    `cloud`.`gui_themes`.`name` AS `name`,
+    `cloud`.`gui_themes`.`description` AS `description`,
+    `cloud`.`gui_themes`.`css` AS `css`,
+    `cloud`.`gui_themes`.`json_configuration` AS `json_configuration`,
+    (SELECT group_concat(gtd.`value` separator ',') FROM 
`cloud`.`gui_themes_details` gtd WHERE gtd.`type` = 'commonName' AND 
gtd.gui_theme_id = `cloud`.`gui_themes`.`id`) common_names,
+    (SELECT group_concat(gtd.`value` separator ',') FROM 
`cloud`.`gui_themes_details` gtd WHERE gtd.`type` = 'domain' AND 
gtd.gui_theme_id = `cloud`.`gui_themes`.`id`) domains,
+    (SELECT group_concat(gtd.`value` separator ',') FROM 
`cloud`.`gui_themes_details` gtd WHERE gtd.`type` = 'account' AND 
gtd.gui_theme_id = `cloud`.`gui_themes`.`id`) accounts,
+    `cloud`.`gui_themes`.`recursive_domains` AS `recursive_domains`,
+    `cloud`.`gui_themes`.`is_public` AS `is_public`,
+    `cloud`.`gui_themes`.`created` AS `created`,
+    `cloud`.`gui_themes`.`removed` AS `removed`
+FROM `cloud`.`gui_themes` LEFT JOIN `cloud`.`gui_themes_details` ON 
`cloud`.`gui_themes_details`.`gui_theme_id` = `cloud`.`gui_themes`.`id`
+GROUP BY `cloud`.`gui_themes`.`id`;

Review Comment:
   this should be in a view file



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: commits-unsubscr...@cloudstack.apache.org

For queries about this service, please contact Infrastructure at:
us...@infra.apache.org

Reply via email to