From 9622f2ae9bd7a42182ee9e4889048cf8e524c129 Mon Sep 17 00:00:00 2001 From: gitlab-cicd Date: Fri, 31 Jan 2025 01:02:09 +0000 Subject: [PATCH] CICD for commit 0a7873f798e70d030a0244007c8bcd0c4b471bb7 --- local-libs/vcluster/LICENSE | 2 +- .../commands/cluster_command_launcher.go | 7 +- .../commands/cluster_command_launcher_test.go | 2 +- local-libs/vcluster/commands/cmd_add_node.go | 2 +- .../vcluster/commands/cmd_add_subcluster.go | 2 +- local-libs/vcluster/commands/cmd_base.go | 2 +- .../vcluster/commands/cmd_check_connection.go | 2 +- .../vcluster/commands/cmd_cluster_health.go | 220 ++++++++++++ .../vcluster/commands/cmd_config_recover.go | 2 +- .../vcluster/commands/cmd_config_show.go | 2 +- .../vcluster/commands/cmd_connection.go | 2 +- .../vcluster/commands/cmd_create_archive.go | 2 +- .../commands/cmd_create_connection.go | 4 +- local-libs/vcluster/commands/cmd_create_db.go | 2 +- local-libs/vcluster/commands/cmd_drop_db.go | 2 +- .../commands/cmd_get_draining_status.go | 2 +- .../commands/cmd_get_replication_status.go | 2 +- .../vcluster/commands/cmd_install_packages.go | 2 +- .../vcluster/commands/cmd_list_all_nodes.go | 2 +- .../vcluster/commands/cmd_manage_config.go | 2 +- .../vcluster/commands/cmd_promote_sandbox.go | 2 +- local-libs/vcluster/commands/cmd_re_ip.go | 2 +- .../vcluster/commands/cmd_remove_node.go | 2 +- .../commands/cmd_remove_subcluster.go | 2 +- .../vcluster/commands/cmd_replication.go | 2 +- .../vcluster/commands/cmd_restart_node.go | 2 +- local-libs/vcluster/commands/cmd_revive_db.go | 2 +- local-libs/vcluster/commands/cmd_sandbox.go | 2 +- .../commands/cmd_save_restore_point.go | 2 +- .../vcluster/commands/cmd_scrutinize.go | 2 +- .../commands/cmd_show_restore_points.go | 2 +- local-libs/vcluster/commands/cmd_start_db.go | 2 +- .../commands/cmd_start_replication.go | 15 +- .../vcluster/commands/cmd_start_subcluster.go | 2 +- local-libs/vcluster/commands/cmd_stop_db.go | 2 +- local-libs/vcluster/commands/cmd_stop_node.go | 2 +- .../vcluster/commands/cmd_stop_subcluster.go | 2 +- local-libs/vcluster/commands/cmd_unsandbox.go | 2 +- .../vcluster/commands/cmd_upgrade_license.go | 3 +- local-libs/vcluster/commands/helpers.go | 12 +- local-libs/vcluster/commands/init.go | 2 +- .../vcluster/commands/scrutinize_test.go | 2 +- .../vcluster/commands/user_input_test.go | 2 +- local-libs/vcluster/logging-utils.sh | 2 +- local-libs/vcluster/main.go | 2 +- local-libs/vcluster/rfc7807/errors.go | 7 +- local-libs/vcluster/rfc7807/rfc7807.go | 2 +- local-libs/vcluster/rfc7807/rfc7807_test.go | 2 +- local-libs/vcluster/sync-to-github.sh | 12 +- .../vcluster/vclusterops/adapter_pool.go | 2 +- local-libs/vcluster/vclusterops/add_node.go | 2 +- .../vcluster/vclusterops/add_subcluster.go | 2 +- .../vclusterops/alter_subcluster_type.go | 2 +- .../vclusterops/alter_subcluster_type_test.go | 2 +- .../vclusterops/check_vcluster_server_pid.go | 2 +- .../vcluster/vclusterops/cluster_health.go | 321 ++++++++++++++++++ local-libs/vcluster/vclusterops/cluster_op.go | 3 +- .../vcluster/vclusterops/cluster_op_engine.go | 2 +- .../vclusterops/cluster_op_engine_context.go | 11 +- .../vclusterops/cluster_op_engine_test.go | 2 +- .../vcluster/vclusterops/cluster_op_test.go | 2 +- local-libs/vcluster/vclusterops/cmd_type.go | 2 + .../vclusterops/coordinator_database.go | 2 +- .../vcluster/vclusterops/create_archive.go | 2 +- local-libs/vcluster/vclusterops/create_db.go | 2 +- .../vcluster/vclusterops/create_db_test.go | 2 +- local-libs/vcluster/vclusterops/drop_db.go | 2 +- .../vcluster/vclusterops/fetch_database.go | 2 +- .../vclusterops/fetch_nodes_details.go | 2 +- .../vclusterops/fetch_nodes_details_test.go | 2 +- .../vclusterops/get_config_parameter.go | 2 +- .../vclusterops/get_config_parameter_test.go | 2 +- .../vclusterops/get_draining_status.go | 2 +- local-libs/vcluster/vclusterops/helpers.go | 20 +- .../vcluster/vclusterops/helpers_test.go | 2 +- .../vcluster/vclusterops/http_adapter.go | 2 +- .../vcluster/vclusterops/http_adapter_test.go | 2 +- .../vcluster/vclusterops/http_request.go | 2 +- .../vclusterops/http_request_dispatcher.go | 2 +- .../vclusterops/https_add_subcluster_op.go | 2 +- .../vclusterops/https_check_db_running_op.go | 2 +- .../vclusterops/https_check_subcluster_op.go | 2 +- .../https_check_subcluster_sandbox_op.go | 29 +- .../https_convert_sandbox_to_main_op.go | 2 +- .../vclusterops/https_create_archive_op.go | 2 +- .../https_create_cluster_depot_op.go | 2 +- .../vclusterops/https_create_node_op.go | 2 +- .../https_create_nodes_depot_op.go | 2 +- .../https_create_tls_authentication_op.go | 2 +- .../vclusterops/https_demote_subcluster_op.go | 2 +- .../https_disallow_multiple_namespaces_op.go | 2 +- .../vclusterops/https_drop_node_op.go | 2 +- .../vclusterops/https_drop_subcluster_op.go | 2 +- .../vclusterops/https_find_subcluster_op.go | 2 +- .../vclusterops/https_get_cluster_info_op.go | 2 +- .../https_get_draining_status_op.go | 2 +- .../https_get_local_node_state_op.go | 2 +- .../https_get_local_storage_locations.go | 2 +- .../vclusterops/https_get_nodes_info_op.go | 2 +- .../vclusterops/https_get_system_tables_op.go | 2 +- .../vclusterops/https_get_up_nodes_op.go | 2 +- .../https_grant_authentication_op.go | 2 +- .../vclusterops/https_install_license_op.go | 2 +- .../vclusterops/https_install_packages_op.go | 2 +- .../vclusterops/https_mark_design_ksafe_op.go | 2 +- .../https_mark_nodes_ephemeral_op.go | 2 +- .../https_poll_node_state_indirect_op.go | 2 +- .../vclusterops/https_poll_node_state_op.go | 2 +- .../https_poll_node_state_op_test.go | 2 +- .../https_poll_subcluster_node_state_op.go | 2 +- .../https_poll_subscription_state_op.go | 2 +- .../https_promote_subcluster_op.go | 2 +- .../vcluster/vclusterops/https_re_ip_op.go | 2 +- .../vclusterops/https_rebalance_cluster_op.go | 2 +- .../https_rebalance_subcluster_shards_op.go | 2 +- .../vclusterops/https_reload_spread_op.go | 2 +- .../vclusterops/https_rename_subcluster_op.go | 2 +- .../https_sandbox_subcluster_op.go | 2 +- .../vclusterops/https_session_starts_op.go | 162 +++++++++ .../vclusterops/https_slow_event_op.go | 220 ++++++++++++ .../https_spread_remove_node_op.go | 2 +- .../https_stage_system_tables_op.go | 2 +- .../vclusterops/https_start_replication_op.go | 2 +- .../vclusterops/https_startup_command_op.go | 2 +- .../vcluster/vclusterops/https_stop_db_op.go | 2 +- .../vclusterops/https_stop_node_op.go | 2 +- .../vclusterops/https_stop_subcluster_op.go | 2 +- .../vclusterops/https_sync_catalog_op.go | 2 +- .../https_transaction_starts_op.go | 138 ++++++++ .../https_unsandbox_subcluster_op.go | 2 +- .../vclusterops/https_update_node_state_op.go | 2 +- .../vcluster/vclusterops/install_packages.go | 2 +- .../vclusterops/manage_connection_draining.go | 2 +- .../manage_connection_draining_test.go | 2 +- .../vcluster/vclusterops/network_adapter.go | 2 +- .../vclusterops/nma_bootstrap_catalog_op.go | 2 +- .../nma_check_cluster_version_op.go | 2 +- .../nma_check_vcluster_server_pid_op.go | 2 +- .../nma_clean_communal_storage_op.go | 2 +- .../vclusterops/nma_delete_file_op.go | 114 +++++++ .../vclusterops/nma_download_config.go | 35 +- .../vclusterops/nma_download_file_op.go | 2 +- .../vclusterops/nma_download_file_op_test.go | 2 +- .../nma_get_config_parameter_op.go | 2 +- .../nma_get_config_parameter_op_test.go | 2 +- .../vclusterops/nma_get_healthy_nodes_op.go | 2 +- .../vclusterops/nma_get_nodes_info_op.go | 2 +- .../vclusterops/nma_get_scrutinize_tar_op.go | 2 +- .../vcluster/vclusterops/nma_health_op.go | 2 +- .../vclusterops/nma_load_remote_catalog_op.go | 2 +- .../vclusterops/nma_manage_connections_op.go | 2 +- .../nma_manage_connections_op_test.go | 2 +- .../vclusterops/nma_network_profile_op.go | 2 +- .../nma_poll_replication_status.go | 2 +- .../vclusterops/nma_prepare_directories_op.go | 2 +- .../nma_prepare_scrutinizer_directories_op.go | 2 +- .../vcluster/vclusterops/nma_re_ip_op.go | 2 +- .../vclusterops/nma_read_catalog_editor_op.go | 2 +- .../vclusterops/nma_replication_start.go | 2 +- .../vclusterops/nma_replication_status.go | 2 +- .../vclusterops/nma_save_restore_points_op.go | 2 +- .../nma_set_config_parameter_op.go | 2 +- .../nma_set_config_parameter_op_test.go | 2 +- .../vclusterops/nma_show_restore_points_op.go | 2 +- .../nma_show_restore_points_op_test.go | 2 +- .../vclusterops/nma_spread_security_op.go | 2 +- .../nma_spread_security_op_test.go | 2 +- .../vclusterops/nma_stage_dc_tables_op.go | 2 +- .../vclusterops/nma_stage_vertica_logs_op.go | 2 +- .../vcluster/vclusterops/nma_start_node_op.go | 2 +- .../vcluster/vclusterops/nma_upload_config.go | 45 ++- .../vclusterops/nma_vertica_version_op.go | 2 +- .../nma_vertica_version_op_test.go | 2 +- local-libs/vcluster/vclusterops/node_info.go | 2 +- .../vcluster/vclusterops/node_info_test.go | 2 +- .../vcluster/vclusterops/poll_sc_state.go | 2 +- .../vclusterops/promote_sandbox_to_main.go | 2 +- .../promote_sandbox_to_main_test.go | 2 +- local-libs/vcluster/vclusterops/re_ip.go | 2 +- local-libs/vcluster/vclusterops/re_ip_test.go | 2 +- .../vcluster/vclusterops/remove_node.go | 2 +- .../vcluster/vclusterops/remove_subcluster.go | 2 +- .../vclusterops/remove_subcluster_test.go | 2 +- .../vcluster/vclusterops/rename_subcluster.go | 2 +- .../vclusterops/rename_subcluster_test.go | 2 +- .../vcluster/vclusterops/replication.go | 2 +- .../vclusterops/replication_status.go | 17 +- .../vclusterops/replication_status_test.go | 6 +- local-libs/vcluster/vclusterops/revive_db.go | 2 +- local-libs/vcluster/vclusterops/sandbox.go | 2 +- .../vclusterops/save_restore_points.go | 2 +- local-libs/vcluster/vclusterops/scrutinize.go | 4 +- .../vcluster/vclusterops/scrutinize_op.go | 2 +- .../vclusterops/set_config_parameter.go | 2 +- .../vclusterops/set_config_parameter_test.go | 2 +- .../vclusterops/show_restore_points.go | 2 +- .../vclusterops/sql_endpoint_common.go | 2 +- local-libs/vcluster/vclusterops/start_db.go | 2 +- local-libs/vcluster/vclusterops/start_node.go | 2 +- .../vcluster/vclusterops/start_subcluster.go | 2 +- .../vcluster/vclusterops/state_poller.go | 2 +- local-libs/vcluster/vclusterops/stop_db.go | 2 +- local-libs/vcluster/vclusterops/stop_node.go | 2 +- .../vcluster/vclusterops/stop_subcluster.go | 2 +- local-libs/vcluster/vclusterops/unsandbox.go | 2 +- .../vcluster/vclusterops/upgrade_license.go | 111 ++++-- .../vcluster/vclusterops/util/defaults.go | 2 +- local-libs/vcluster/vclusterops/util/util.go | 4 +- .../vcluster/vclusterops/util/util_test.go | 2 +- .../vclusterops/vcluster_database_options.go | 2 +- .../vcluster_database_options_test.go | 2 +- .../vcluster/vclusterops/vcluster_version.go | 4 +- .../vclusterops/vcluster_version_test.go | 2 +- .../vcluster/vclusterops/vlog/printer.go | 2 +- .../vcluster/vclusterops/vlog/printer_test.go | 2 +- .../vcluster/vclusterops/vstruct/vstruct.go | 2 +- 216 files changed, 1648 insertions(+), 258 deletions(-) create mode 100644 local-libs/vcluster/commands/cmd_cluster_health.go create mode 100644 local-libs/vcluster/vclusterops/cluster_health.go create mode 100644 local-libs/vcluster/vclusterops/https_session_starts_op.go create mode 100644 local-libs/vcluster/vclusterops/https_slow_event_op.go create mode 100644 local-libs/vcluster/vclusterops/https_transaction_starts_op.go create mode 100644 local-libs/vcluster/vclusterops/nma_delete_file_op.go diff --git a/local-libs/vcluster/LICENSE b/local-libs/vcluster/LICENSE index 36881f09b..ba2f72745 100644 --- a/local-libs/vcluster/LICENSE +++ b/local-libs/vcluster/LICENSE @@ -186,7 +186,7 @@ same "printed page" as the copyright notice for easier identification within third-party archives. - Copyright [2023-2024] Open Text. + Copyright [2023-2025] Open Text. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/local-libs/vcluster/commands/cluster_command_launcher.go b/local-libs/vcluster/commands/cluster_command_launcher.go index fbc434493..e552c43db 100644 --- a/local-libs/vcluster/commands/cluster_command_launcher.go +++ b/local-libs/vcluster/commands/cluster_command_launcher.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 @@ -113,8 +113,6 @@ const ( ) // Flag and key for database replication -// -//nolint:dupl const ( targetDBNameFlag = "target-db-name" targetDBNameKey = "targetDBName" @@ -217,7 +215,6 @@ var keyEnvVarMap = map[string]string{ tlsModeKey: vclusterTLSModeEnv, } -//nolint:dupl const ( createDBSubCmd = "create_db" stopDBSubCmd = "stop_db" @@ -254,6 +251,7 @@ const ( getDrainingStatusSubCmd = "get_draining_status" upgradeLicenseCmd = "upgrade_license" checkConnectionSubCmd = "check" + clusterHealth = "cluster_health" ) // cmdGlobals holds global variables shared by multiple @@ -640,6 +638,7 @@ func constructCmds() []*cobra.Command { makeCmdCreateArchive(), makeCmdSaveRestorePoint(), makeCmdUpgradeLicense(), + makeCmdClusterHealth(), } } diff --git a/local-libs/vcluster/commands/cluster_command_launcher_test.go b/local-libs/vcluster/commands/cluster_command_launcher_test.go index 6baa1b087..7cad744df 100644 --- a/local-libs/vcluster/commands/cluster_command_launcher_test.go +++ b/local-libs/vcluster/commands/cluster_command_launcher_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_add_node.go b/local-libs/vcluster/commands/cmd_add_node.go index f194e25d9..dd405bdb6 100644 --- a/local-libs/vcluster/commands/cmd_add_node.go +++ b/local-libs/vcluster/commands/cmd_add_node.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_add_subcluster.go b/local-libs/vcluster/commands/cmd_add_subcluster.go index b912ccc6a..41de8185c 100644 --- a/local-libs/vcluster/commands/cmd_add_subcluster.go +++ b/local-libs/vcluster/commands/cmd_add_subcluster.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_base.go b/local-libs/vcluster/commands/cmd_base.go index a5d699280..5a42daa68 100644 --- a/local-libs/vcluster/commands/cmd_base.go +++ b/local-libs/vcluster/commands/cmd_base.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_check_connection.go b/local-libs/vcluster/commands/cmd_check_connection.go index 4f5f28838..8a609da90 100644 --- a/local-libs/vcluster/commands/cmd_check_connection.go +++ b/local-libs/vcluster/commands/cmd_check_connection.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_cluster_health.go b/local-libs/vcluster/commands/cmd_cluster_health.go new file mode 100644 index 000000000..e73e9d2bd --- /dev/null +++ b/local-libs/vcluster/commands/cmd_cluster_health.go @@ -0,0 +1,220 @@ +/* + (c) Copyright [2023-2024] Open Text. + Licensed 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 commands + +import ( + "encoding/json" + "fmt" + "strconv" + + "github.com/spf13/cobra" + "github.com/vertica/vcluster/vclusterops" + "github.com/vertica/vcluster/vclusterops/vlog" +) + +/* CmdClusterHealth + * + * Implements ClusterCommand interface + */ +type CmdClusterHealth struct { + clusterHealthOptions *vclusterops.VClusterHealthOptions + + CmdBase +} + +func makeCmdClusterHealth() *cobra.Command { + // CmdClusterHealth + newCmd := &CmdClusterHealth{} + opt := vclusterops.VClusterHealthFactory() + newCmd.clusterHealthOptions = &opt + + cmd := makeBasicCobraCmd( + newCmd, + clusterHealth, + "Checks the database cluster health. This is used for testing and debugging only.", + `Checks the database cluster health. + +This is used for testing and debugging only. + +Examples: + # Check the cluster health + vcluster cluster_health +`, + // TODO: modify this + []string{dbNameFlag, configFlag, hostsFlag, ipv6Flag, passwordFlag, outputFileFlag}, + ) + + // local flags + newCmd.setLocalFlags(cmd) + + return cmd +} + +// setLocalFlags will set the local flags the command has +func (c *CmdClusterHealth) setLocalFlags(cmd *cobra.Command) { + // TODO: add some code here + // local flag of CmdClusterHealth, + // --operation : the operation type, including "check", "get_slow_events", "get_transaction_starts", "get_session_starts" + // --txn-id : the transaction id (for slow event and trsanction start) + // --node-name : the node name (for all operations) + // --start-time : the start time (for all operations) + // --end-time : the end time (for all operations) + // --session-id : the session id (for session start and slow event) + // --debug : debug mode (for all operations) + // --threadhold : the threadhold of seconds for slow events (for get_slow_events) + // --thread-id : the thread id (for get_slow_events) + // --phase-duration-desc : the phase duration description (for get_slow_events) + // --event-desc : the event description (for get_slow_events) + // --user-name : the user name (for get_slow_events) + + cmd.Flags().StringVar( + &c.clusterHealthOptions.Operation, + "operation", + "", + "The operation type, including 'cascade', 'get_slow_events', 'get_transaction_starts', 'get_session_starts'.", + ) + cmd.Flags().StringVar( + &c.clusterHealthOptions.TxnID, + "txn-id", + "", + "The transaction id (for slow event and transaction start).", + ) + cmd.Flags().StringVar( + &c.clusterHealthOptions.NodeName, + "node-name", + "", + "The node name (for all operations).", + ) + cmd.Flags().StringVar( + &c.clusterHealthOptions.StartTime, + "start-time", + "", + "The start time (for all operations).", + ) + cmd.Flags().StringVar( + &c.clusterHealthOptions.EndTime, + "end-time", + "", + "The end time (for all operations).", + ) + cmd.Flags().StringVar( + &c.clusterHealthOptions.SessionID, + "session-id", + "", + "The session id (for session start and slow event).", + ) + cmd.Flags().BoolVar( + &c.clusterHealthOptions.Debug, + "debug", + false, + "Debug mode (for all operations).", + ) + cmd.Flags().StringVar( + &c.clusterHealthOptions.Threadhold, + "threadhold", + "", + "The threadhold of seconds for slow events (for get_slow_events).", + ) + cmd.Flags().StringVar( + &c.clusterHealthOptions.ThreadID, + "thread-id", + "", + "The thread id (for get_slow_events).", + ) + cmd.Flags().StringVar( + &c.clusterHealthOptions.PhaseDurationDesc, + "phase-duration-desc", + "", + "The phase duration description (for get_slow_events).", + ) + cmd.Flags().StringVar( + &c.clusterHealthOptions.EventDesc, + "event-desc", + "", + "The event description (for get_slow_events).", + ) +} + +func (c *CmdClusterHealth) Parse(inputArgv []string, logger vlog.Printer) error { + c.argv = inputArgv + logger.LogMaskedArgParse(c.argv) + + // for some options, we do not want to use their default values, + // if they are not provided in cli, + // reset the value of those options to nil + c.ResetUserInputOptions(&c.clusterHealthOptions.DatabaseOptions) + return c.validateParse(logger) +} + +func (c *CmdClusterHealth) validateParse(logger vlog.Printer) error { + logger.Info("Called validateParse()") + + if !c.usePassword() { + err := c.getCertFilesFromCertPaths(&c.clusterHealthOptions.DatabaseOptions) + if err != nil { + return err + } + } + + // validate txn id is integer + if c.clusterHealthOptions.TxnID != "" { + _, err := c.validateInt(c.clusterHealthOptions.TxnID, "txn-id") + if err != nil { + return err + } + } + err := c.ValidateParseBaseOptions(&c.clusterHealthOptions.DatabaseOptions) + if err != nil { + return err + } + return c.setDBPassword(&c.clusterHealthOptions.DatabaseOptions) +} + +// validateInt checks if the given string is a valid integer +func (c *CmdClusterHealth) validateInt(value, fieldName string) (int, error) { + intValue, err := strconv.Atoi(value) + if err != nil { + return 0, fmt.Errorf("%s must be an integer", fieldName) + } + return intValue, nil +} + +func (c *CmdClusterHealth) Run(vcc vclusterops.ClusterCommands) error { + vcc.LogInfo("Called method Run()") + + options := c.clusterHealthOptions + + err := vcc.VClusterHealth(options) + if err != nil { + vcc.LogError(err, "failed to check cluster health.") + return err + } + + bytes, err := json.MarshalIndent(options.CascadeStack, "", " ") + if err != nil { + return fmt.Errorf("failed to marshal the traceback result, details: %w", err) + } + + c.writeCmdOutputToFile(globals.file, bytes, vcc.GetLog()) + vcc.LogInfo("Slow event traceback: ", "slow events", string(bytes)) + + return nil +} + +// SetDatabaseOptions will assign a vclusterops.DatabaseOptions instance to the one in CmdClusterHealth +func (c *CmdClusterHealth) SetDatabaseOptions(opt *vclusterops.DatabaseOptions) { + c.clusterHealthOptions.DatabaseOptions = *opt +} diff --git a/local-libs/vcluster/commands/cmd_config_recover.go b/local-libs/vcluster/commands/cmd_config_recover.go index 5f9148081..080990cb7 100644 --- a/local-libs/vcluster/commands/cmd_config_recover.go +++ b/local-libs/vcluster/commands/cmd_config_recover.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_config_show.go b/local-libs/vcluster/commands/cmd_config_show.go index 5fa7db263..0bd4c6a3d 100644 --- a/local-libs/vcluster/commands/cmd_config_show.go +++ b/local-libs/vcluster/commands/cmd_config_show.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_connection.go b/local-libs/vcluster/commands/cmd_connection.go index 39d0e5a3c..2d3c1dc7e 100644 --- a/local-libs/vcluster/commands/cmd_connection.go +++ b/local-libs/vcluster/commands/cmd_connection.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_create_archive.go b/local-libs/vcluster/commands/cmd_create_archive.go index 2d5818d8f..ff71e72ac 100644 --- a/local-libs/vcluster/commands/cmd_create_archive.go +++ b/local-libs/vcluster/commands/cmd_create_archive.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_create_connection.go b/local-libs/vcluster/commands/cmd_create_connection.go index ea711ee26..a54501f6b 100644 --- a/local-libs/vcluster/commands/cmd_create_connection.go +++ b/local-libs/vcluster/commands/cmd_create_connection.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 @@ -146,7 +146,7 @@ func (c *CmdCreateConnection) Run(vcc vclusterops.ClusterCommands) error { // write target db info to vcluster connection file err := c.writeConn() if err != nil { - vcc.DisplayError("failed to write the connection file: " + err.Error()) + vcc.DisplayError("Failed to write the connection file: " + err.Error()) return nil } vcc.DisplayInfo("Successfully wrote the connection file in %s", globals.connFile) diff --git a/local-libs/vcluster/commands/cmd_create_db.go b/local-libs/vcluster/commands/cmd_create_db.go index 722bb6f3c..7da32872f 100644 --- a/local-libs/vcluster/commands/cmd_create_db.go +++ b/local-libs/vcluster/commands/cmd_create_db.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_drop_db.go b/local-libs/vcluster/commands/cmd_drop_db.go index a0dbc7576..15d747c52 100644 --- a/local-libs/vcluster/commands/cmd_drop_db.go +++ b/local-libs/vcluster/commands/cmd_drop_db.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_get_draining_status.go b/local-libs/vcluster/commands/cmd_get_draining_status.go index eda973c8a..1c2ddb8ed 100644 --- a/local-libs/vcluster/commands/cmd_get_draining_status.go +++ b/local-libs/vcluster/commands/cmd_get_draining_status.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_get_replication_status.go b/local-libs/vcluster/commands/cmd_get_replication_status.go index 61e99f39f..6cb200f02 100644 --- a/local-libs/vcluster/commands/cmd_get_replication_status.go +++ b/local-libs/vcluster/commands/cmd_get_replication_status.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_install_packages.go b/local-libs/vcluster/commands/cmd_install_packages.go index 255192c49..2e5b93124 100644 --- a/local-libs/vcluster/commands/cmd_install_packages.go +++ b/local-libs/vcluster/commands/cmd_install_packages.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_list_all_nodes.go b/local-libs/vcluster/commands/cmd_list_all_nodes.go index 68e7cc71c..1172c4e8c 100644 --- a/local-libs/vcluster/commands/cmd_list_all_nodes.go +++ b/local-libs/vcluster/commands/cmd_list_all_nodes.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_manage_config.go b/local-libs/vcluster/commands/cmd_manage_config.go index 7a420ba11..4f51dfbaa 100644 --- a/local-libs/vcluster/commands/cmd_manage_config.go +++ b/local-libs/vcluster/commands/cmd_manage_config.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_promote_sandbox.go b/local-libs/vcluster/commands/cmd_promote_sandbox.go index 4f723cc72..0d272147a 100644 --- a/local-libs/vcluster/commands/cmd_promote_sandbox.go +++ b/local-libs/vcluster/commands/cmd_promote_sandbox.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_re_ip.go b/local-libs/vcluster/commands/cmd_re_ip.go index d2133b830..2357bc81d 100644 --- a/local-libs/vcluster/commands/cmd_re_ip.go +++ b/local-libs/vcluster/commands/cmd_re_ip.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_remove_node.go b/local-libs/vcluster/commands/cmd_remove_node.go index 0fbfecc3a..1a8505fcb 100644 --- a/local-libs/vcluster/commands/cmd_remove_node.go +++ b/local-libs/vcluster/commands/cmd_remove_node.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_remove_subcluster.go b/local-libs/vcluster/commands/cmd_remove_subcluster.go index e79753d98..8daa64808 100644 --- a/local-libs/vcluster/commands/cmd_remove_subcluster.go +++ b/local-libs/vcluster/commands/cmd_remove_subcluster.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_replication.go b/local-libs/vcluster/commands/cmd_replication.go index 9cfdc3205..7e134da49 100644 --- a/local-libs/vcluster/commands/cmd_replication.go +++ b/local-libs/vcluster/commands/cmd_replication.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_restart_node.go b/local-libs/vcluster/commands/cmd_restart_node.go index a83012eaa..e99dfac1c 100644 --- a/local-libs/vcluster/commands/cmd_restart_node.go +++ b/local-libs/vcluster/commands/cmd_restart_node.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_revive_db.go b/local-libs/vcluster/commands/cmd_revive_db.go index f7593980e..3e91555b2 100644 --- a/local-libs/vcluster/commands/cmd_revive_db.go +++ b/local-libs/vcluster/commands/cmd_revive_db.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_sandbox.go b/local-libs/vcluster/commands/cmd_sandbox.go index bd6bf5d63..8388b239a 100644 --- a/local-libs/vcluster/commands/cmd_sandbox.go +++ b/local-libs/vcluster/commands/cmd_sandbox.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_save_restore_point.go b/local-libs/vcluster/commands/cmd_save_restore_point.go index be1d89c4c..3afea1f54 100644 --- a/local-libs/vcluster/commands/cmd_save_restore_point.go +++ b/local-libs/vcluster/commands/cmd_save_restore_point.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_scrutinize.go b/local-libs/vcluster/commands/cmd_scrutinize.go index 3b54527fb..35bf90d0a 100644 --- a/local-libs/vcluster/commands/cmd_scrutinize.go +++ b/local-libs/vcluster/commands/cmd_scrutinize.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_show_restore_points.go b/local-libs/vcluster/commands/cmd_show_restore_points.go index db623f0b9..602308b56 100644 --- a/local-libs/vcluster/commands/cmd_show_restore_points.go +++ b/local-libs/vcluster/commands/cmd_show_restore_points.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_start_db.go b/local-libs/vcluster/commands/cmd_start_db.go index 00758a048..f2f769d4e 100644 --- a/local-libs/vcluster/commands/cmd_start_db.go +++ b/local-libs/vcluster/commands/cmd_start_db.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_start_replication.go b/local-libs/vcluster/commands/cmd_start_replication.go index d03d2fdd2..65a1755ab 100644 --- a/local-libs/vcluster/commands/cmd_start_replication.go +++ b/local-libs/vcluster/commands/cmd_start_replication.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 @@ -17,6 +17,7 @@ package commands import ( "fmt" + "strings" "github.com/spf13/cobra" "github.com/spf13/viper" @@ -262,8 +263,16 @@ func (c *CmdStartReplication) Run(vcc vclusterops.ClusterCommands) error { transactionID, err := vcc.VReplicateDatabase(options) if err != nil { - vcc.LogError(err, "failed to replicate to database", "targetDB", options.TargetDB.DBName) - return err + errMsg := err.Error() + // when no table matches include pattern, errMsg contains "ERROR 4089: [22023] No objects specified" + // when no table matches table-or-schema-name, errMsg contains "ERROR 11781: [22023] Unknown or unsupported table name" + if !strings.Contains(errMsg, "22023") { + vcc.LogError(err, "failed to replicate to database", "targetDB", options.TargetDB.DBName) + return err + } + vcc.DisplayWarning("No data is replicated to database %s: %s", + options.TargetDB.DBName, errMsg) + return nil } if options.Async { diff --git a/local-libs/vcluster/commands/cmd_start_subcluster.go b/local-libs/vcluster/commands/cmd_start_subcluster.go index deaceb95d..c536e9220 100644 --- a/local-libs/vcluster/commands/cmd_start_subcluster.go +++ b/local-libs/vcluster/commands/cmd_start_subcluster.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_stop_db.go b/local-libs/vcluster/commands/cmd_stop_db.go index 1c53361c8..6e544c2fc 100644 --- a/local-libs/vcluster/commands/cmd_stop_db.go +++ b/local-libs/vcluster/commands/cmd_stop_db.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_stop_node.go b/local-libs/vcluster/commands/cmd_stop_node.go index bfd1d7e79..5b8be7851 100644 --- a/local-libs/vcluster/commands/cmd_stop_node.go +++ b/local-libs/vcluster/commands/cmd_stop_node.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_stop_subcluster.go b/local-libs/vcluster/commands/cmd_stop_subcluster.go index f9e33ff4a..473421baf 100644 --- a/local-libs/vcluster/commands/cmd_stop_subcluster.go +++ b/local-libs/vcluster/commands/cmd_stop_subcluster.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_unsandbox.go b/local-libs/vcluster/commands/cmd_unsandbox.go index d2f971500..b4fc4cf9c 100644 --- a/local-libs/vcluster/commands/cmd_unsandbox.go +++ b/local-libs/vcluster/commands/cmd_unsandbox.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/cmd_upgrade_license.go b/local-libs/vcluster/commands/cmd_upgrade_license.go index 284487753..2bb2f32ae 100644 --- a/local-libs/vcluster/commands/cmd_upgrade_license.go +++ b/local-libs/vcluster/commands/cmd_upgrade_license.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 @@ -61,7 +61,6 @@ Examples: // require license file path markFlagsRequired(cmd, licenseFileFlag) - markFlagsRequired(cmd, licenseHostFlag) return cmd } diff --git a/local-libs/vcluster/commands/helpers.go b/local-libs/vcluster/commands/helpers.go index 1c1073071..23263771a 100644 --- a/local-libs/vcluster/commands/helpers.go +++ b/local-libs/vcluster/commands/helpers.go @@ -1,5 +1,5 @@ /* -(c) Copyright [2023-2024] Open Text. +(c) Copyright [2023-2025] Open Text. Licensed 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 @@ -77,17 +77,17 @@ func converErrorMessage(err error, logger vlog.Printer) string { errMsg := err.Error() logger.Error(err, "error to be converted into err msg") if strings.Contains(errMsg, "down database") { - return "failed to vertify connection parameters. please check your db name and host list" + return "Failed to verify connection parameters. Please check your db name and host list" } else if strings.Contains(errMsg, "Wrong password") { - return "failed to vertify connection parameters. please check your db username and password" + return "Failed to verify connection parameters. Please check your db username and password" } else if strings.Contains(errMsg, "rather than database") { - return "failed to vertify connection parameters. please check your db name" + return "Failed to verify connection parameters. Please check your db name" } else if strings.Contains(errMsg, "no such host") || strings.Contains(errMsg, "network is unreachable") || strings.Contains(errMsg, "fail to send request") || strings.Contains(errMsg, "server misbehaving") || strings.Contains(errMsg, "i/o timeout") { - return "failed to vertify connection parameters. please check your host list" + return "Failed to verify connection parameters. Please check your host list" } - return "failed to vertify connection parameters: " + errMsg + return "Failed to verify connection parameters: " + errMsg } // this function calls ClusterCommand.FetchNodesDetails() for each input hosts and return both valid and invalid hosts diff --git a/local-libs/vcluster/commands/init.go b/local-libs/vcluster/commands/init.go index c1d7c01a4..af87c470a 100644 --- a/local-libs/vcluster/commands/init.go +++ b/local-libs/vcluster/commands/init.go @@ -1,5 +1,5 @@ /* -(c) Copyright [2023-2024] Open Text. +(c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/scrutinize_test.go b/local-libs/vcluster/commands/scrutinize_test.go index 9fba1c027..d0579da0b 100644 --- a/local-libs/vcluster/commands/scrutinize_test.go +++ b/local-libs/vcluster/commands/scrutinize_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/commands/user_input_test.go b/local-libs/vcluster/commands/user_input_test.go index bc8ed0a5b..2232ce6c1 100644 --- a/local-libs/vcluster/commands/user_input_test.go +++ b/local-libs/vcluster/commands/user_input_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/logging-utils.sh b/local-libs/vcluster/logging-utils.sh index 17cfef951..3e0f5fa21 100644 --- a/local-libs/vcluster/logging-utils.sh +++ b/local-libs/vcluster/logging-utils.sh @@ -1,6 +1,6 @@ #!/bin/bash -# (c) Copyright [2023-2024] Open Text. +# (c) Copyright [2023-2025] Open Text. # Licensed 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 diff --git a/local-libs/vcluster/main.go b/local-libs/vcluster/main.go index e29b96cd4..f590d47be 100644 --- a/local-libs/vcluster/main.go +++ b/local-libs/vcluster/main.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/rfc7807/errors.go b/local-libs/vcluster/rfc7807/errors.go index a95ff6e7d..a1d0d7f65 100644 --- a/local-libs/vcluster/rfc7807/errors.go +++ b/local-libs/vcluster/rfc7807/errors.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 @@ -242,6 +242,11 @@ var ( "Failed to create file", http.StatusInternalServerError, ) + GenericDeleteFileError = newProblemID( + path.Join(errorEndpointsPrefix, "delete-file-failure-error"), + "Failed to delete file", + http.StatusInternalServerError, + ) MessageQueueFull = newProblemID( path.Join(errorEndpointsPrefix, "message-queue-full"), "Message queue is full", diff --git a/local-libs/vcluster/rfc7807/rfc7807.go b/local-libs/vcluster/rfc7807/rfc7807.go index 04c9e8b1f..64ee17fba 100644 --- a/local-libs/vcluster/rfc7807/rfc7807.go +++ b/local-libs/vcluster/rfc7807/rfc7807.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/rfc7807/rfc7807_test.go b/local-libs/vcluster/rfc7807/rfc7807_test.go index 769eeb08a..1a6ac7736 100644 --- a/local-libs/vcluster/rfc7807/rfc7807_test.go +++ b/local-libs/vcluster/rfc7807/rfc7807_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/sync-to-github.sh b/local-libs/vcluster/sync-to-github.sh index bb7b49c1b..c922859f9 100755 --- a/local-libs/vcluster/sync-to-github.sh +++ b/local-libs/vcluster/sync-to-github.sh @@ -1,6 +1,6 @@ #!/bin/bash -# (c) Copyright [2023-2024] Open Text. +# (c) Copyright [2023-2025] Open Text. # Licensed 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 @@ -23,6 +23,7 @@ set -o nounset SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" &> /dev/null && pwd )" FORCE= SKIP_COMMIT= +IGNORE_ROOT_PATH_CHECK= DRY_RUN_OPT= source $SCRIPT_DIR/logging-utils.sh @@ -34,6 +35,7 @@ function usage() { echo " -f Force, even when there are uncommitted files." echo " -s Skip git commit at the destination. Just sync the files." echo " -d Dry run only. Don't change anything in the destination repo." + echo " -i Ignore destination root path check. This option allows syncing the source directory to a subdirectory within the destination repo." echo " -v Verbose output." echo echo "Positional Arguments:" @@ -43,13 +45,14 @@ function usage() { exit 1 } -while getopts "hfsdv" opt +while getopts "hfsidv" opt do case $opt in h) usage;; f) FORCE=1;; v) set -o xtrace;; s) SKIP_COMMIT=1;; + i) IGNORE_ROOT_PATH_CHECK=1;; d) DRY_RUN_OPT="--dry-run" SKIP_COMMIT=1 ;; @@ -76,7 +79,7 @@ then logError "Destination directory isn't a git repo" exit 1 fi -if [[ "$DEST_GITROOT" != "$DEST_DIR" ]] +if [[ "$DEST_GITROOT" != "$DEST_DIR" && -z "$IGNORE_ROOT_PATH_CHECK" ]] then logError "Destination directory isn't git's root directory" exit 1 @@ -102,6 +105,7 @@ logAndRunCommand "rsync $DRY_RUN_OPT --archive \ --verbose \ --delete \ --exclude .git \ + --exclude .github \ --exclude vendor \ --exclude bin \ --exclude coverage.out \ @@ -119,7 +123,7 @@ logInfo "Changing directory to $DEST_DIR" cd $DEST_DIR logAndRunCommand "git add --all ." -MSG_FILE=$(mktemp git-commit-msg-XXXXX) +MSG_FILE=$(mktemp git-commit-msg-XXXXXX) trap "rm $MSG_FILE" EXIT echo "Sync from server repo ($SERVER_GITREF)" > $MSG_FILE logAndRunCommand "git commit --file $MSG_FILE" diff --git a/local-libs/vcluster/vclusterops/adapter_pool.go b/local-libs/vcluster/vclusterops/adapter_pool.go index a7927b393..e8cdd6c4d 100644 --- a/local-libs/vcluster/vclusterops/adapter_pool.go +++ b/local-libs/vcluster/vclusterops/adapter_pool.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/add_node.go b/local-libs/vcluster/vclusterops/add_node.go index 95344ca70..260b96112 100644 --- a/local-libs/vcluster/vclusterops/add_node.go +++ b/local-libs/vcluster/vclusterops/add_node.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/add_subcluster.go b/local-libs/vcluster/vclusterops/add_subcluster.go index 05ab9f7d7..858e355a6 100644 --- a/local-libs/vcluster/vclusterops/add_subcluster.go +++ b/local-libs/vcluster/vclusterops/add_subcluster.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/alter_subcluster_type.go b/local-libs/vcluster/vclusterops/alter_subcluster_type.go index 713fd3e55..15b301874 100644 --- a/local-libs/vcluster/vclusterops/alter_subcluster_type.go +++ b/local-libs/vcluster/vclusterops/alter_subcluster_type.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/alter_subcluster_type_test.go b/local-libs/vcluster/vclusterops/alter_subcluster_type_test.go index d7b831073..87f60ada8 100644 --- a/local-libs/vcluster/vclusterops/alter_subcluster_type_test.go +++ b/local-libs/vcluster/vclusterops/alter_subcluster_type_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/check_vcluster_server_pid.go b/local-libs/vcluster/vclusterops/check_vcluster_server_pid.go index 50c5a0189..4195417d4 100644 --- a/local-libs/vcluster/vclusterops/check_vcluster_server_pid.go +++ b/local-libs/vcluster/vclusterops/check_vcluster_server_pid.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/cluster_health.go b/local-libs/vcluster/vclusterops/cluster_health.go new file mode 100644 index 000000000..c71650544 --- /dev/null +++ b/local-libs/vcluster/vclusterops/cluster_health.go @@ -0,0 +1,321 @@ +/* + (c) Copyright [2023-2024] Open Text. + Licensed 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 vclusterops + +import ( + "fmt" + "math/big" + "regexp" + "time" + + "github.com/vertica/vcluster/vclusterops/util" + "github.com/vertica/vcluster/vclusterops/vlog" +) + +// VClusterHealthOptions represents the available options to check the cluster health +type VClusterHealthOptions struct { + DatabaseOptions + Operation string + TxnID string + NodeName string + StartTime string + EndTime string + SessionID string + Debug bool + Threadhold string + ThreadID string + PhaseDurationDesc string + EventDesc string + UserName string + + // hidden option + CascadeStack []SlowEventNode +} + +type SlowEventNode struct { + Depth int `json:"depth"` + Event *dcSlowEvent `json:"slow_event"` + Leaf bool `json:"leaf"` +} + +func VClusterHealthFactory() VClusterHealthOptions { + options := VClusterHealthOptions{} + // set default values to the params + options.setDefaultValues() + options.Debug = false + + return options +} + +func (options *VClusterHealthOptions) setDefaultValues() { + options.DatabaseOptions.setDefaultValues() +} + +func (options *VClusterHealthOptions) validateRequiredOptions(logger vlog.Printer) error { + err := options.validateBaseOptions(ClusterHealthCmd, logger) + if err != nil { + return err + } + return nil +} + +func (options *VClusterHealthOptions) validateExtraOptions() error { + // data prefix + if options.DataPrefix != "" { + return util.ValidateRequiredAbsPath(options.DataPrefix, "data path") + } + return nil +} + +func (options *VClusterHealthOptions) validateParseOptions(logger vlog.Printer) error { + // batch 1: validate required params + err := options.validateRequiredOptions(logger) + if err != nil { + return err + } + // batch 2: validate all other params + err = options.validateExtraOptions() + if err != nil { + return err + } + return nil +} + +func (options *VClusterHealthOptions) analyzeOptions() (err error) { + // we analyze host names when it is set in user input, otherwise we use hosts in yaml config + if len(options.RawHosts) > 0 { + // resolve RawHosts to be IP addresses + options.Hosts, err = util.ResolveRawHostsToAddresses(options.RawHosts, options.IPv6) + if err != nil { + return err + } + options.normalizePaths() + } + return nil +} + +func (options *VClusterHealthOptions) validateAnalyzeOptions(log vlog.Printer) error { + if err := options.validateParseOptions(log); err != nil { + return err + } + err := options.analyzeOptions() + if err != nil { + return err + } + return options.setUsePasswordAndValidateUsernameIfNeeded(log) +} + +func (vcc VClusterCommands) VClusterHealth(options *VClusterHealthOptions) error { + vdb := makeVCoordinationDatabase() + + // validate and analyze options + err := options.validateAnalyzeOptions(vcc.Log) + if err != nil { + return err + } + + err = vcc.getVDBFromRunningDB(&vdb, &options.DatabaseOptions) + if err != nil { + return err + } + + operation := options.Operation + var runError error + switch operation { + case "get_slow_events": + _, runError = options.getSlowEvents(vcc.Log, vdb.PrimaryUpNodes, options.ThreadID, options.StartTime, options.EndTime) + case "get_session_starts": + runError = options.getSessionStarts(vcc.Log, vdb.PrimaryUpNodes) + case "get_transaction_starts": + runError = options.getTransactionStarts(vcc.Log, vdb.PrimaryUpNodes) + default: // by default, we will build a cascade graph + runError = options.buildCascadeGraph(vcc.Log, vdb.PrimaryUpNodes) + } + + return runError +} + +func (options *VClusterHealthOptions) buildCascadeGraph(logger vlog.Printer, upHosts []string) error { + // get slow events during the given time + slowEvents, err := options.getSlowEvents(logger, upHosts, + "" /*thread_id*/, options.StartTime, options.EndTime) + if err != nil { + return err + } + + // find the slowest event during the given time + var slowestIdx int + var maxDuration int64 + if len(slowEvents.SlowEventList) > 0 { + for idx := range slowEvents.SlowEventList { + event := slowEvents.SlowEventList[idx] + if event.DurationUs > maxDuration { + slowestIdx = idx + maxDuration = event.DurationUs + } + } + } + + // analyze the slowest event's info + slowestEvent := slowEvents.SlowEventList[slowestIdx] + threadIDStr, startTime, endTime, err := analyzeSlowEvent(&slowestEvent) + if err != nil { + return err + } + + options.CascadeStack = append(options.CascadeStack, SlowEventNode{0, &slowestEvent, false}) + + // recursively traceback + const recursiveDepth = 1 + err = options.recursiveTraceback(logger, upHosts, threadIDStr, + startTime, endTime, recursiveDepth) + if err != nil { + return err + } + + fmt.Println("[DEBUG INFO]: cascade traceback done.") + + return err +} + +func (options *VClusterHealthOptions) recursiveTraceback(logger vlog.Printer, + upHosts []string, + threadID, startTime, endTime string, + depth int) error { + slowEvents, err := options.getSlowEvents(logger, upHosts, threadID, startTime, endTime) + if err != nil { + return err + } + + // update the leaf node info + if len(slowEvents.SlowEventList) == 0 { + length := len(options.CascadeStack) + options.CascadeStack[length-1].Leaf = true + return nil + } + + for idx := range slowEvents.SlowEventList { + event := slowEvents.SlowEventList[idx] + + // TODO: get txn desc and session desc here + + callerThreadID, callerStartTime, callerEndTime, err := analyzeSlowEvent(&event) + if err != nil { + return err + } + + // record the event + var leaf bool + if callerThreadID == "" { + leaf = true + } + options.CascadeStack = append(options.CascadeStack, SlowEventNode{depth, &event, leaf}) + + // go to trace the caller event + if callerThreadID != "" && callerStartTime != "" && callerEndTime != "" { + e := options.recursiveTraceback(logger, upHosts, + callerThreadID, callerStartTime, callerEndTime, + depth+1, + ) + if e != nil { + return e + } + } + } + + return nil +} + +func analyzeSlowEvent(event *dcSlowEvent) ( + threadIDStr, startTime, endTime string, err error) { + const timeLayout = "2006-01-02 15:04:05.000000" + + phasesDurationUs := event.PhasesDurationUs + re := regexp.MustCompile(`\[.+\]`) + matched := re.Find([]byte(phasesDurationUs)) + matchedLengh := len(matched) + if matchedLengh > 0 { + threadIDHex := string(matched[1 : matchedLengh-1]) + threadIDDec := new(big.Int) + const hex = 16 + threadIDDec.SetString(threadIDHex, hex) + threadIDStr = threadIDDec.String() + end, err := time.Parse(timeLayout, event.Time) + if err != nil { + return threadIDStr, startTime, endTime, err + } + // we search for the caller events that + // - have the thread_id mentioned in phases_duration_us, and + // - happened before (the event time) and after (the event time minus the event duration) + start := end.Add(time.Duration(-event.DurationUs) * time.Microsecond) + + return threadIDStr, start.Format(timeLayout), end.Format(timeLayout), nil + } + + return threadIDStr, startTime, endTime, nil +} + +func (options *VClusterHealthOptions) getSlowEvents(logger vlog.Printer, upHosts []string, + threadID, startTime, endTime string) (slowEvents *dcSlowEvents, err error) { + var instructions []clusterOp + + httpsSlowEventOp := makeHTTPSSlowEventOp(upHosts, startTime, endTime, + options.TxnID, options.NodeName, threadID, + options.PhaseDurationDesc, options.EventDesc, options.Debug) + instructions = append(instructions, &httpsSlowEventOp) + + clusterOpEngine := makeClusterOpEngine(instructions, &options.DatabaseOptions) + err = clusterOpEngine.run(logger) + if err != nil { + return slowEvents, fmt.Errorf("fail to retrieve database configurations, %w", err) + } + + return clusterOpEngine.execContext.slowEvents, nil +} + +func (options *VClusterHealthOptions) getSessionStarts(logger vlog.Printer, upHosts []string) error { + var instructions []clusterOp + + httpsSessionStartsOp := makeHTTPSSessionStartsOp(upHosts, options.SessionID, options.StartTime, options.EndTime, false) + instructions = append(instructions, &httpsSessionStartsOp) + + clusterOpEngine := makeClusterOpEngine(instructions, &options.DatabaseOptions) + err := clusterOpEngine.run(logger) + if err != nil { + return fmt.Errorf("fail to retrieve database configurations, %w", err) + } + + fmt.Printf("[DEBUG INFO] %+v\n", clusterOpEngine.execContext.dcSessionStarts) + + return nil +} + +func (options *VClusterHealthOptions) getTransactionStarts(logger vlog.Printer, upHosts []string) error { + var instructions []clusterOp + + httpsTransactionStartsOp := makeHTTPSTransactionStartsOp(upHosts, options.TxnID, options.StartTime, options.EndTime, false) + instructions = append(instructions, &httpsTransactionStartsOp) + + clusterOpEngine := makeClusterOpEngine(instructions, &options.DatabaseOptions) + err := clusterOpEngine.run(logger) + if err != nil { + return fmt.Errorf("fail to retrieve database configurations, %w", err) + } + + fmt.Printf("[DEBUG INFO] %+v\n", clusterOpEngine.execContext.dcTransactionStarts) + + return nil +} diff --git a/local-libs/vcluster/vclusterops/cluster_op.go b/local-libs/vcluster/vclusterops/cluster_op.go index 4023da7f2..169755851 100644 --- a/local-libs/vcluster/vclusterops/cluster_op.go +++ b/local-libs/vcluster/vclusterops/cluster_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 @@ -613,6 +613,7 @@ type ClusterCommands interface { VStopSubcluster(options *VStopSubclusterOptions) error VUnsandbox(options *VUnsandboxOptions) error VUpgradeLicense(options *VUpgradeLicenseOptions) error + VClusterHealth(options *VClusterHealthOptions) error } type VClusterCommandsLogger struct { diff --git a/local-libs/vcluster/vclusterops/cluster_op_engine.go b/local-libs/vcluster/vclusterops/cluster_op_engine.go index 3810d09d4..66465e731 100644 --- a/local-libs/vcluster/vclusterops/cluster_op_engine.go +++ b/local-libs/vcluster/vclusterops/cluster_op_engine.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/cluster_op_engine_context.go b/local-libs/vcluster/vclusterops/cluster_op_engine_context.go index 540cf5bcc..3e931abf2 100644 --- a/local-libs/vcluster/vclusterops/cluster_op_engine_context.go +++ b/local-libs/vcluster/vclusterops/cluster_op_engine_context.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 @@ -50,6 +50,15 @@ type opEngineExecContext struct { sandbox string // this vdb will only be used to get sandbox info of the nodes vdbForSandboxInfo *VCoordinationDatabase + + // slow events + slowEvents *dcSlowEvents + + // transaction starts + dcTransactionStarts dcTransactionStarts + + // session starts + dcSessionStarts dcSessionStarts } func makeOpEngineExecContext(logger vlog.Printer) opEngineExecContext { diff --git a/local-libs/vcluster/vclusterops/cluster_op_engine_test.go b/local-libs/vcluster/vclusterops/cluster_op_engine_test.go index 8c7a240af..79857fb9e 100644 --- a/local-libs/vcluster/vclusterops/cluster_op_engine_test.go +++ b/local-libs/vcluster/vclusterops/cluster_op_engine_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/cluster_op_test.go b/local-libs/vcluster/vclusterops/cluster_op_test.go index 4caeeff97..8d2eb89a2 100644 --- a/local-libs/vcluster/vclusterops/cluster_op_test.go +++ b/local-libs/vcluster/vclusterops/cluster_op_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/cmd_type.go b/local-libs/vcluster/vclusterops/cmd_type.go index 3f562ec3c..ef63253f0 100644 --- a/local-libs/vcluster/vclusterops/cmd_type.go +++ b/local-libs/vcluster/vclusterops/cmd_type.go @@ -44,6 +44,7 @@ const ( CreateArchiveCmd PollSubclusterStateCmd UpgradeLicenseCmd + ClusterHealthCmd ) var cmdStringMap = map[CmdType]string{ @@ -86,6 +87,7 @@ var cmdStringMap = map[CmdType]string{ CreateArchiveCmd: "create_archive", PollSubclusterStateCmd: "poll_subcluster_state", UpgradeLicenseCmd: "upgrade_license", + ClusterHealthCmd: "cluster_health", } func (cmd CmdType) CmdString() string { diff --git a/local-libs/vcluster/vclusterops/coordinator_database.go b/local-libs/vcluster/vclusterops/coordinator_database.go index 67cfff2d0..85ee95b64 100644 --- a/local-libs/vcluster/vclusterops/coordinator_database.go +++ b/local-libs/vcluster/vclusterops/coordinator_database.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/create_archive.go b/local-libs/vcluster/vclusterops/create_archive.go index cb2a64051..ee56af423 100644 --- a/local-libs/vcluster/vclusterops/create_archive.go +++ b/local-libs/vcluster/vclusterops/create_archive.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/create_db.go b/local-libs/vcluster/vclusterops/create_db.go index ed8979174..dd1ac3d68 100644 --- a/local-libs/vcluster/vclusterops/create_db.go +++ b/local-libs/vcluster/vclusterops/create_db.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/create_db_test.go b/local-libs/vcluster/vclusterops/create_db_test.go index 8c3872496..7af93d307 100644 --- a/local-libs/vcluster/vclusterops/create_db_test.go +++ b/local-libs/vcluster/vclusterops/create_db_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/drop_db.go b/local-libs/vcluster/vclusterops/drop_db.go index dda610edd..9c5118a19 100644 --- a/local-libs/vcluster/vclusterops/drop_db.go +++ b/local-libs/vcluster/vclusterops/drop_db.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/fetch_database.go b/local-libs/vcluster/vclusterops/fetch_database.go index b863e98e0..89697bddf 100644 --- a/local-libs/vcluster/vclusterops/fetch_database.go +++ b/local-libs/vcluster/vclusterops/fetch_database.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/fetch_nodes_details.go b/local-libs/vcluster/vclusterops/fetch_nodes_details.go index abb53ddef..d14bbf2d1 100644 --- a/local-libs/vcluster/vclusterops/fetch_nodes_details.go +++ b/local-libs/vcluster/vclusterops/fetch_nodes_details.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/fetch_nodes_details_test.go b/local-libs/vcluster/vclusterops/fetch_nodes_details_test.go index 5b5c96835..e0131929b 100644 --- a/local-libs/vcluster/vclusterops/fetch_nodes_details_test.go +++ b/local-libs/vcluster/vclusterops/fetch_nodes_details_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/get_config_parameter.go b/local-libs/vcluster/vclusterops/get_config_parameter.go index de9d08634..d4c6a0546 100644 --- a/local-libs/vcluster/vclusterops/get_config_parameter.go +++ b/local-libs/vcluster/vclusterops/get_config_parameter.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/get_config_parameter_test.go b/local-libs/vcluster/vclusterops/get_config_parameter_test.go index c5b7ac89e..5c7aa18b6 100644 --- a/local-libs/vcluster/vclusterops/get_config_parameter_test.go +++ b/local-libs/vcluster/vclusterops/get_config_parameter_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/get_draining_status.go b/local-libs/vcluster/vclusterops/get_draining_status.go index 59bef526c..825a8a95f 100644 --- a/local-libs/vcluster/vclusterops/get_draining_status.go +++ b/local-libs/vcluster/vclusterops/get_draining_status.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/helpers.go b/local-libs/vcluster/vclusterops/helpers.go index 7e3fc0839..d25e186d0 100644 --- a/local-libs/vcluster/vclusterops/helpers.go +++ b/local-libs/vcluster/vclusterops/helpers.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 @@ -33,7 +33,7 @@ const ( nmaSuccessfulReturnCode = 0 ) -// produceTransferConfigOps generates instructions to transfert some config +// produceTransferConfigOps generates instructions to transfer some config // files from a sourceConfig node to target nodes. func produceTransferConfigOps(instructions *[]clusterOp, sourceConfigHost, targetHosts []string, vdb *VCoordinationDatabase, sandbox *string) { @@ -55,6 +55,22 @@ func produceTransferConfigOps(instructions *[]clusterOp, sourceConfigHost, ) } +// produceTransferLicenseOps generates instructions to transfer a license +// file from a source node to a target node. +func produceTransferLicenseOps(instructions *[]clusterOp, sourceHost, + targetHost, sourceFilePath, targetFilePath string) { + var licenseContent string + nmaDownloadLicenseOp := makeNMADownloadLicenseOp( + sourceHost, sourceFilePath, &licenseContent) + nmaUploadLicenseOp := makeNMAUploadLicenseOp( + sourceHost, targetHost, targetFilePath, &licenseContent) + + *instructions = append(*instructions, + &nmaDownloadLicenseOp, + &nmaUploadLicenseOp, + ) +} + // Get catalog path after we have db information from /catalog/database endpoint func updateCatalogPathMapFromCatalogEditor(hosts []string, nmaVDB *nmaVDatabase, catalogPathMap map[string]string) error { if len(hosts) == 0 { diff --git a/local-libs/vcluster/vclusterops/helpers_test.go b/local-libs/vcluster/vclusterops/helpers_test.go index 3dc20e5a6..b49771b67 100644 --- a/local-libs/vcluster/vclusterops/helpers_test.go +++ b/local-libs/vcluster/vclusterops/helpers_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/http_adapter.go b/local-libs/vcluster/vclusterops/http_adapter.go index 32dc1998d..f452d6b56 100644 --- a/local-libs/vcluster/vclusterops/http_adapter.go +++ b/local-libs/vcluster/vclusterops/http_adapter.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/http_adapter_test.go b/local-libs/vcluster/vclusterops/http_adapter_test.go index 76ee34837..dbc975f55 100644 --- a/local-libs/vcluster/vclusterops/http_adapter_test.go +++ b/local-libs/vcluster/vclusterops/http_adapter_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/http_request.go b/local-libs/vcluster/vclusterops/http_request.go index c37d1f777..6dc12b86c 100644 --- a/local-libs/vcluster/vclusterops/http_request.go +++ b/local-libs/vcluster/vclusterops/http_request.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/http_request_dispatcher.go b/local-libs/vcluster/vclusterops/http_request_dispatcher.go index 0bc1caaa7..7afd8c845 100644 --- a/local-libs/vcluster/vclusterops/http_request_dispatcher.go +++ b/local-libs/vcluster/vclusterops/http_request_dispatcher.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_add_subcluster_op.go b/local-libs/vcluster/vclusterops/https_add_subcluster_op.go index 2f228cb8b..090b2bb1c 100644 --- a/local-libs/vcluster/vclusterops/https_add_subcluster_op.go +++ b/local-libs/vcluster/vclusterops/https_add_subcluster_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_check_db_running_op.go b/local-libs/vcluster/vclusterops/https_check_db_running_op.go index 31d49cda4..cca84804e 100644 --- a/local-libs/vcluster/vclusterops/https_check_db_running_op.go +++ b/local-libs/vcluster/vclusterops/https_check_db_running_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_check_subcluster_op.go b/local-libs/vcluster/vclusterops/https_check_subcluster_op.go index 02406043a..8b43694fc 100644 --- a/local-libs/vcluster/vclusterops/https_check_subcluster_op.go +++ b/local-libs/vcluster/vclusterops/https_check_subcluster_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_check_subcluster_sandbox_op.go b/local-libs/vcluster/vclusterops/https_check_subcluster_sandbox_op.go index 63c38a8a8..4ea8ba992 100644 --- a/local-libs/vcluster/vclusterops/https_check_subcluster_sandbox_op.go +++ b/local-libs/vcluster/vclusterops/https_check_subcluster_sandbox_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 @@ -157,6 +157,11 @@ func (op *httpsCheckSubclusterSandboxOp) processResult(execContext *opEngineExec // Use updated scInfo for host, sb := range existingSandboxedHosts { + // Check if existing sandbox is aware of the new subcluster or not + if !op.checkScAwareness(host) { + return fmt.Errorf("target sandbox %s is unaware of the subcluster to be sandboxed - %s\n"+ + "Hint: try recreating the sandbox after unsandboxing the existing sandboxed subclusters", op.Sandbox, op.ScToSandbox) + } // Just need one up host from the existing sandbox // This will be used to add new subcluster to an existing sandbox execContext.upHostsToSandboxes[host] = sb @@ -170,8 +175,30 @@ func (op *httpsCheckSubclusterSandboxOp) processResult(execContext *opEngineExec break } } + return allErrs } + +// Check whether the input host(sandboxed UP host) is aware of the sc to be sandboxed +func (op *httpsCheckSubclusterSandboxOp) checkScAwareness(host string) bool { + for reqHost, result := range op.clusterHTTPRequest.ResultCollection { + if host == reqHost { + subclusterResp := scResps{} + err := op.parseAndCheckResponse(host, result.content, &subclusterResp) + if err != nil { + return false + } + // Check results to see if the sandbox is aware of the target sc to be sandboxed + for _, scInfo := range subclusterResp.SCInfoList { + if scInfo.SCName == op.ScToSandbox { + return true + } + } + } + } + return false +} + func (op *httpsCheckSubclusterSandboxOp) processScInfo(scInfo subclusterSandboxInfo, execContext *opEngineExecContext) (mainClusterHosts, existingSandboxedHosts map[string]string, keysToRemove map[string]struct{}) { keysToRemove = make(map[string]struct{}) diff --git a/local-libs/vcluster/vclusterops/https_convert_sandbox_to_main_op.go b/local-libs/vcluster/vclusterops/https_convert_sandbox_to_main_op.go index e087b4025..a7520495d 100644 --- a/local-libs/vcluster/vclusterops/https_convert_sandbox_to_main_op.go +++ b/local-libs/vcluster/vclusterops/https_convert_sandbox_to_main_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_create_archive_op.go b/local-libs/vcluster/vclusterops/https_create_archive_op.go index ae699c046..af7934ab4 100644 --- a/local-libs/vcluster/vclusterops/https_create_archive_op.go +++ b/local-libs/vcluster/vclusterops/https_create_archive_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_create_cluster_depot_op.go b/local-libs/vcluster/vclusterops/https_create_cluster_depot_op.go index 8cc692148..0f99a84ff 100644 --- a/local-libs/vcluster/vclusterops/https_create_cluster_depot_op.go +++ b/local-libs/vcluster/vclusterops/https_create_cluster_depot_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_create_node_op.go b/local-libs/vcluster/vclusterops/https_create_node_op.go index c9b4537ae..2e5fd1494 100644 --- a/local-libs/vcluster/vclusterops/https_create_node_op.go +++ b/local-libs/vcluster/vclusterops/https_create_node_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_create_nodes_depot_op.go b/local-libs/vcluster/vclusterops/https_create_nodes_depot_op.go index ed1c7af3d..90aa54092 100644 --- a/local-libs/vcluster/vclusterops/https_create_nodes_depot_op.go +++ b/local-libs/vcluster/vclusterops/https_create_nodes_depot_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_create_tls_authentication_op.go b/local-libs/vcluster/vclusterops/https_create_tls_authentication_op.go index 331d39de1..0aeeb9c38 100644 --- a/local-libs/vcluster/vclusterops/https_create_tls_authentication_op.go +++ b/local-libs/vcluster/vclusterops/https_create_tls_authentication_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_demote_subcluster_op.go b/local-libs/vcluster/vclusterops/https_demote_subcluster_op.go index 327548ab4..945e65def 100644 --- a/local-libs/vcluster/vclusterops/https_demote_subcluster_op.go +++ b/local-libs/vcluster/vclusterops/https_demote_subcluster_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_disallow_multiple_namespaces_op.go b/local-libs/vcluster/vclusterops/https_disallow_multiple_namespaces_op.go index ebc930244..c613a65d8 100644 --- a/local-libs/vcluster/vclusterops/https_disallow_multiple_namespaces_op.go +++ b/local-libs/vcluster/vclusterops/https_disallow_multiple_namespaces_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_drop_node_op.go b/local-libs/vcluster/vclusterops/https_drop_node_op.go index 4990f0206..30dd1d7af 100644 --- a/local-libs/vcluster/vclusterops/https_drop_node_op.go +++ b/local-libs/vcluster/vclusterops/https_drop_node_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_drop_subcluster_op.go b/local-libs/vcluster/vclusterops/https_drop_subcluster_op.go index 057379182..c561fc398 100644 --- a/local-libs/vcluster/vclusterops/https_drop_subcluster_op.go +++ b/local-libs/vcluster/vclusterops/https_drop_subcluster_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_find_subcluster_op.go b/local-libs/vcluster/vclusterops/https_find_subcluster_op.go index 8909edc90..6b90eada8 100644 --- a/local-libs/vcluster/vclusterops/https_find_subcluster_op.go +++ b/local-libs/vcluster/vclusterops/https_find_subcluster_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_get_cluster_info_op.go b/local-libs/vcluster/vclusterops/https_get_cluster_info_op.go index 4baf6638e..b8c2ca002 100644 --- a/local-libs/vcluster/vclusterops/https_get_cluster_info_op.go +++ b/local-libs/vcluster/vclusterops/https_get_cluster_info_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_get_draining_status_op.go b/local-libs/vcluster/vclusterops/https_get_draining_status_op.go index 4e806ca61..c1f367e5e 100644 --- a/local-libs/vcluster/vclusterops/https_get_draining_status_op.go +++ b/local-libs/vcluster/vclusterops/https_get_draining_status_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_get_local_node_state_op.go b/local-libs/vcluster/vclusterops/https_get_local_node_state_op.go index de13a8a62..c685ab674 100644 --- a/local-libs/vcluster/vclusterops/https_get_local_node_state_op.go +++ b/local-libs/vcluster/vclusterops/https_get_local_node_state_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_get_local_storage_locations.go b/local-libs/vcluster/vclusterops/https_get_local_storage_locations.go index 5484580ca..6d587ac64 100644 --- a/local-libs/vcluster/vclusterops/https_get_local_storage_locations.go +++ b/local-libs/vcluster/vclusterops/https_get_local_storage_locations.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_get_nodes_info_op.go b/local-libs/vcluster/vclusterops/https_get_nodes_info_op.go index 29a524af1..f1953693c 100644 --- a/local-libs/vcluster/vclusterops/https_get_nodes_info_op.go +++ b/local-libs/vcluster/vclusterops/https_get_nodes_info_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_get_system_tables_op.go b/local-libs/vcluster/vclusterops/https_get_system_tables_op.go index f0e323858..c095ee45d 100644 --- a/local-libs/vcluster/vclusterops/https_get_system_tables_op.go +++ b/local-libs/vcluster/vclusterops/https_get_system_tables_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_get_up_nodes_op.go b/local-libs/vcluster/vclusterops/https_get_up_nodes_op.go index ded3a6e01..cd330372a 100644 --- a/local-libs/vcluster/vclusterops/https_get_up_nodes_op.go +++ b/local-libs/vcluster/vclusterops/https_get_up_nodes_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_grant_authentication_op.go b/local-libs/vcluster/vclusterops/https_grant_authentication_op.go index 96cb453ff..fdf73d6e9 100644 --- a/local-libs/vcluster/vclusterops/https_grant_authentication_op.go +++ b/local-libs/vcluster/vclusterops/https_grant_authentication_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_install_license_op.go b/local-libs/vcluster/vclusterops/https_install_license_op.go index 83a603a17..ad40bf377 100644 --- a/local-libs/vcluster/vclusterops/https_install_license_op.go +++ b/local-libs/vcluster/vclusterops/https_install_license_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_install_packages_op.go b/local-libs/vcluster/vclusterops/https_install_packages_op.go index 788b89674..1059eb215 100644 --- a/local-libs/vcluster/vclusterops/https_install_packages_op.go +++ b/local-libs/vcluster/vclusterops/https_install_packages_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_mark_design_ksafe_op.go b/local-libs/vcluster/vclusterops/https_mark_design_ksafe_op.go index eaf149f00..864b2e1dc 100644 --- a/local-libs/vcluster/vclusterops/https_mark_design_ksafe_op.go +++ b/local-libs/vcluster/vclusterops/https_mark_design_ksafe_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_mark_nodes_ephemeral_op.go b/local-libs/vcluster/vclusterops/https_mark_nodes_ephemeral_op.go index 0cb7fec3a..ed084d7ed 100644 --- a/local-libs/vcluster/vclusterops/https_mark_nodes_ephemeral_op.go +++ b/local-libs/vcluster/vclusterops/https_mark_nodes_ephemeral_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_poll_node_state_indirect_op.go b/local-libs/vcluster/vclusterops/https_poll_node_state_indirect_op.go index 39203c5a6..393c85e2e 100644 --- a/local-libs/vcluster/vclusterops/https_poll_node_state_indirect_op.go +++ b/local-libs/vcluster/vclusterops/https_poll_node_state_indirect_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_poll_node_state_op.go b/local-libs/vcluster/vclusterops/https_poll_node_state_op.go index cd73ad9f7..415f7d4f8 100644 --- a/local-libs/vcluster/vclusterops/https_poll_node_state_op.go +++ b/local-libs/vcluster/vclusterops/https_poll_node_state_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_poll_node_state_op_test.go b/local-libs/vcluster/vclusterops/https_poll_node_state_op_test.go index fdb112a68..eb4b329c6 100644 --- a/local-libs/vcluster/vclusterops/https_poll_node_state_op_test.go +++ b/local-libs/vcluster/vclusterops/https_poll_node_state_op_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_poll_subcluster_node_state_op.go b/local-libs/vcluster/vclusterops/https_poll_subcluster_node_state_op.go index 5a3d3f6ab..c6ef4a25d 100644 --- a/local-libs/vcluster/vclusterops/https_poll_subcluster_node_state_op.go +++ b/local-libs/vcluster/vclusterops/https_poll_subcluster_node_state_op.go @@ -1,5 +1,5 @@ /* -(c) Copyright [2023-2024] Open Text. +(c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_poll_subscription_state_op.go b/local-libs/vcluster/vclusterops/https_poll_subscription_state_op.go index e818f1ed4..55d6a05ad 100644 --- a/local-libs/vcluster/vclusterops/https_poll_subscription_state_op.go +++ b/local-libs/vcluster/vclusterops/https_poll_subscription_state_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_promote_subcluster_op.go b/local-libs/vcluster/vclusterops/https_promote_subcluster_op.go index 943f592be..544a27235 100644 --- a/local-libs/vcluster/vclusterops/https_promote_subcluster_op.go +++ b/local-libs/vcluster/vclusterops/https_promote_subcluster_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_re_ip_op.go b/local-libs/vcluster/vclusterops/https_re_ip_op.go index 24255c4cb..47d942664 100644 --- a/local-libs/vcluster/vclusterops/https_re_ip_op.go +++ b/local-libs/vcluster/vclusterops/https_re_ip_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_rebalance_cluster_op.go b/local-libs/vcluster/vclusterops/https_rebalance_cluster_op.go index adfb171dc..18dc00df8 100644 --- a/local-libs/vcluster/vclusterops/https_rebalance_cluster_op.go +++ b/local-libs/vcluster/vclusterops/https_rebalance_cluster_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_rebalance_subcluster_shards_op.go b/local-libs/vcluster/vclusterops/https_rebalance_subcluster_shards_op.go index 391b5ff7c..557d46c43 100644 --- a/local-libs/vcluster/vclusterops/https_rebalance_subcluster_shards_op.go +++ b/local-libs/vcluster/vclusterops/https_rebalance_subcluster_shards_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_reload_spread_op.go b/local-libs/vcluster/vclusterops/https_reload_spread_op.go index cca5a464c..0ffdac91b 100644 --- a/local-libs/vcluster/vclusterops/https_reload_spread_op.go +++ b/local-libs/vcluster/vclusterops/https_reload_spread_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_rename_subcluster_op.go b/local-libs/vcluster/vclusterops/https_rename_subcluster_op.go index ba00d5308..23748abb8 100644 --- a/local-libs/vcluster/vclusterops/https_rename_subcluster_op.go +++ b/local-libs/vcluster/vclusterops/https_rename_subcluster_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_sandbox_subcluster_op.go b/local-libs/vcluster/vclusterops/https_sandbox_subcluster_op.go index 3be20081e..845844638 100644 --- a/local-libs/vcluster/vclusterops/https_sandbox_subcluster_op.go +++ b/local-libs/vcluster/vclusterops/https_sandbox_subcluster_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_session_starts_op.go b/local-libs/vcluster/vclusterops/https_session_starts_op.go new file mode 100644 index 000000000..fbe710124 --- /dev/null +++ b/local-libs/vcluster/vclusterops/https_session_starts_op.go @@ -0,0 +1,162 @@ +/* + (c) Copyright [2023-2024] Open Text. + Licensed 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 vclusterops + +import ( + "errors" + "strconv" + "strings" +) + +const ( + startTimeParam = "start-time=" + endTimeParam = "end-time=" + sessionIDParam = "session-id=" + txnIDParam = "txn-id=" + debugParam = "debug=" +) + +type httpsSessionStartsOp struct { + opBase + + // when debug mode is on, this op will return stub data + sessionID string + startTime string + endTime string + debug bool +} + +func makeHTTPSSessionStartsOp(upHosts []string, sessionID, startTime, endTime string, debug bool) httpsSessionStartsOp { + op := httpsSessionStartsOp{} + op.name = "HTTPSSessionStartsOp" + op.description = "Check Session Starts" + op.hosts = upHosts + op.sessionID = sessionID + op.startTime = startTime + op.endTime = endTime + op.debug = debug + return op +} + +const sessionStartsURL = "dc/session-starts" + +// setupClusterHTTPRequest works as the module setup in Admintools +func (op *httpsSessionStartsOp) setupClusterHTTPRequest(hosts []string) error { + // this op may consume resources of the database, + // thus we only need to send https request to one of the up hosts + url := sessionStartsURL + queryParams := []string{} + if op.sessionID != "" { + queryParams = append(queryParams, sessionIDParam+op.sessionID) + } + if op.debug { + queryParams = append(queryParams, debugParam+strconv.FormatBool(op.debug)) + } + if op.startTime != "" { + queryParams = append(queryParams, startTimeParam+op.startTime) + } + if op.endTime != "" { + queryParams = append(queryParams, endTimeParam+op.endTime) + } + for i, param := range queryParams { + // replace " " with "%20" in query params + queryParams[i] = strings.ReplaceAll(param, " ", "%20") + } + + if len(queryParams) > 0 { + url += "?" + strings.Join(queryParams, "&") + } + for _, host := range hosts[:1] { + httpRequest := hostHTTPRequest{} + httpRequest.Method = GetMethod + httpRequest.buildHTTPSEndpoint(url) + op.clusterHTTPRequest.RequestCollection[host] = httpRequest + } + + return nil +} + +func (op *httpsSessionStartsOp) prepare(execContext *opEngineExecContext) error { + execContext.dispatcher.setup(op.hosts) + + return op.setupClusterHTTPRequest(op.hosts) +} + +func (op *httpsSessionStartsOp) execute(execContext *opEngineExecContext) error { + if err := op.runExecute(execContext); err != nil { + return err + } + + return op.processResult(execContext) +} + +func (op *httpsSessionStartsOp) finalize(_ *opEngineExecContext) error { + return nil +} + +type dcSessionStarts struct { + SessionStartsList []dcSessionStart `json:"dc_session_starts_list"` +} + +type dcSessionStart struct { + Time string `json:"timestamp"` + NodeName string `json:"node_name"` + SessionID string `json:"session_id"` + UserID int64 `json:"user_id"` + UserName string `json:"user_name"` + ClientHostname string `json:"client_hostname"` + ClientPID int64 `json:"client_pid"` + ClientLabel string `json:"client_label"` + ClientType string `json:"client_type"` + ClientVersion string `json:"client_version"` + ClientOS string `json:"client_os"` + ClientOSUserName string `json:"client_os_user_name"` + ClientOSHostname string `json:"client_os_hostname"` + SSLState string `json:"ssl_state"` + TLSVersion string `json:"tls_version"` + SSLClientSubject string `json:"ssl_client_subject"` + SSLClientFingerprint string `json:"ssl_client_fingerprint"` + SSLCASubject string `json:"ssl_ca_subject"` + SSLCAFingerPrint string `json:"ssl_ca_fingerprint"` + AuthenticationMethod string `json:"authentication_method"` + ClientAuthenticationName string `json:"client_authentication_name"` + IsInternal bool `json:"is_internal"` + RequestedProtocol string `json:"requested_protocol"` + EffectiveProtocol string `json:"effective_protocol"` + SessionType string `json:"session_type"` + IsBinaryTransfer bool `json:"is_binary_transfer"` +} + +func (op *httpsSessionStartsOp) processResult(execContext *opEngineExecContext) error { + var allErrs error + for host, result := range op.clusterHTTPRequest.ResultCollection { + op.logResponse(host, result) + + if result.isPassing() { + var sessionStarts dcSessionStarts + err := op.parseAndCheckResponse(host, result.content, &sessionStarts) + if err != nil { + return errors.Join(allErrs, err) + } + + // we only need result from one host + execContext.dcSessionStarts = sessionStarts + return allErrs + } + } + + return allErrs +} diff --git a/local-libs/vcluster/vclusterops/https_slow_event_op.go b/local-libs/vcluster/vclusterops/https_slow_event_op.go new file mode 100644 index 000000000..3d4ff3e30 --- /dev/null +++ b/local-libs/vcluster/vclusterops/https_slow_event_op.go @@ -0,0 +1,220 @@ +/* + (c) Copyright [2023-2024] Open Text. + Licensed 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 vclusterops + +import ( + "encoding/json" + "errors" + "fmt" + "io" + "os" + "strings" +) + +type httpsSlowEventsOp struct { + opBase + transactionID string + startTime string + endTime string + threadID string + nodeName string + phaseDuration string + eventDesc string + // when debug mode is on, this op will return stub data + debug bool +} + +func makeHTTPSSlowEventOp(upHosts []string, startTime, endTime, transactionID, nodeName, + threadID, phaseDuration, eventDesc string, debug bool) httpsSlowEventsOp { + op := httpsSlowEventsOp{} + op.name = "HTTPSSlowEventOp" + op.description = "Check slow events" + op.hosts = upHosts + op.startTime = startTime + op.endTime = endTime + op.transactionID = transactionID + op.nodeName = nodeName + op.threadID = threadID + op.phaseDuration = phaseDuration + op.eventDesc = eventDesc + op.debug = debug + return op +} + +const ( + slowEventsURL = "dc/slow-events" +) + +// setupClusterHTTPRequest works as the module setup in Admintools +func (op *httpsSlowEventsOp) setupClusterHTTPRequest(hosts []string) error { + // this op may consume resources of the database, + // thus we only need to send https request to one of the up hosts + + // compose url from options + url := slowEventsURL + queryParams := []string{} + + if op.startTime != "" { + queryParams = append(queryParams, "start-time="+op.startTime) + } + if op.endTime != "" { + queryParams = append(queryParams, "end-time="+op.endTime) + } + if op.debug { + queryParams = append(queryParams, "debug=true") + } + if op.nodeName != "" { + queryParams = append(queryParams, "node-name="+op.nodeName) + } + if op.threadID != "" { + queryParams = append(queryParams, "thread-id="+op.threadID) + } + if op.phaseDuration != "" { + queryParams = append(queryParams, "phases-duration-desc"+op.phaseDuration) + } + if op.eventDesc != "" { + queryParams = append(queryParams, "event-desc="+op.eventDesc) + } + + for i, param := range queryParams { + // replace " " with "%20" in query params + queryParams[i] = strings.ReplaceAll(param, " ", "%20") + } + url += "?" + strings.Join(queryParams, "&") + + for _, host := range hosts[:1] { + httpRequest := hostHTTPRequest{} + httpRequest.Method = GetMethod + httpRequest.buildHTTPSEndpoint(url) + op.clusterHTTPRequest.RequestCollection[host] = httpRequest + } + + return nil +} + +func (op *httpsSlowEventsOp) prepare(execContext *opEngineExecContext) error { + execContext.dispatcher.setup(op.hosts) + + return op.setupClusterHTTPRequest(op.hosts) +} + +func (op *httpsSlowEventsOp) execute(execContext *opEngineExecContext) error { + if op.debug { + return op.executeOnStub(execContext) + } + + if err := op.runExecute(execContext); err != nil { + return err + } + + return op.processResult(execContext) +} + +func (op *httpsSlowEventsOp) finalize(_ *opEngineExecContext) error { + return nil +} + +type dcSlowEvents struct { + SlowEventList []dcSlowEvent `json:"dc_slow_event_list"` +} + +type dcSlowEvent struct { + Time string `json:"timestamp"` + NodeName string `json:"node_name"` + SessionID string `json:"session_id"` + UserID string `json:"user_id"` + UserName string `json:"user_name"` + TxnID string `json:"txn_id"` + StatementID string `json:"statement_id"` + RequestID string `json:"request_id"` + EventDescription string `json:"event_description"` + ThresholdUs int64 `json:"threshold_us"` + DurationUs int64 `json:"duration_us"` + PhasesDurationUs string `json:"phases_duration_us"` + ThreadID string `json:"thread_id"` + Val3 string `json:"val3"` +} + +func (op *httpsSlowEventsOp) processResult(execContext *opEngineExecContext) error { + var allErrs error + for host, result := range op.clusterHTTPRequest.ResultCollection { + op.logResponse(host, result) + + if result.isPassing() { + var slowEvents dcSlowEvents + err := op.parseAndCheckResponse(host, result.content, &slowEvents) + if err != nil { + return errors.Join(allErrs, err) + } + + // we only need result from one host + execContext.slowEvents = &slowEvents + return allErrs + } + } + + return allErrs +} + +func (op *httpsSlowEventsOp) executeOnStub(execContext *opEngineExecContext) error { + // TODO: we take this location from input, but this place would be fine + // because we can any way write files from outside to the test containers + location := "/opt/vertica/tmp/slow_events_sample.json" + jsonFile, err := os.Open(location) + if err != nil { + return fmt.Errorf("failed to open slow events stub file at %s", location) + } + + defer jsonFile.Close() + + var slowEventList []dcSlowEvent + bytes, _ := io.ReadAll(jsonFile) + err = json.Unmarshal(bytes, &slowEventList) + if err != nil { + return err + } + + var filteredEvents []dcSlowEvent + for idx := range slowEventList { + event := slowEventList[idx] + if op.startTime != "" { + if event.Time < op.startTime { + continue + } + } + if op.endTime != "" { + if event.Time > op.endTime { + continue + } + } + if op.threadID != "" { + if event.ThreadID != op.threadID { + continue + } + } + if op.eventDesc != "" { + if !strings.Contains(event.EventDescription, op.eventDesc) { + continue + } + } + filteredEvents = append(filteredEvents, event) + } + + execContext.slowEvents = new(dcSlowEvents) + execContext.slowEvents.SlowEventList = filteredEvents + + return nil +} diff --git a/local-libs/vcluster/vclusterops/https_spread_remove_node_op.go b/local-libs/vcluster/vclusterops/https_spread_remove_node_op.go index 48f421711..26da2f3ce 100644 --- a/local-libs/vcluster/vclusterops/https_spread_remove_node_op.go +++ b/local-libs/vcluster/vclusterops/https_spread_remove_node_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_stage_system_tables_op.go b/local-libs/vcluster/vclusterops/https_stage_system_tables_op.go index 76d956e4e..171ebd080 100644 --- a/local-libs/vcluster/vclusterops/https_stage_system_tables_op.go +++ b/local-libs/vcluster/vclusterops/https_stage_system_tables_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_start_replication_op.go b/local-libs/vcluster/vclusterops/https_start_replication_op.go index 0f0228b87..080158862 100644 --- a/local-libs/vcluster/vclusterops/https_start_replication_op.go +++ b/local-libs/vcluster/vclusterops/https_start_replication_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_startup_command_op.go b/local-libs/vcluster/vclusterops/https_startup_command_op.go index e4cb5d4ef..fd49e39d8 100644 --- a/local-libs/vcluster/vclusterops/https_startup_command_op.go +++ b/local-libs/vcluster/vclusterops/https_startup_command_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_stop_db_op.go b/local-libs/vcluster/vclusterops/https_stop_db_op.go index 3821e7a1b..d10f49e67 100644 --- a/local-libs/vcluster/vclusterops/https_stop_db_op.go +++ b/local-libs/vcluster/vclusterops/https_stop_db_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_stop_node_op.go b/local-libs/vcluster/vclusterops/https_stop_node_op.go index e0fc34d11..17b17ff5a 100644 --- a/local-libs/vcluster/vclusterops/https_stop_node_op.go +++ b/local-libs/vcluster/vclusterops/https_stop_node_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_stop_subcluster_op.go b/local-libs/vcluster/vclusterops/https_stop_subcluster_op.go index 509cae0c8..f690a1f05 100644 --- a/local-libs/vcluster/vclusterops/https_stop_subcluster_op.go +++ b/local-libs/vcluster/vclusterops/https_stop_subcluster_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_sync_catalog_op.go b/local-libs/vcluster/vclusterops/https_sync_catalog_op.go index 548a42416..a7a7c8371 100644 --- a/local-libs/vcluster/vclusterops/https_sync_catalog_op.go +++ b/local-libs/vcluster/vclusterops/https_sync_catalog_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_transaction_starts_op.go b/local-libs/vcluster/vclusterops/https_transaction_starts_op.go new file mode 100644 index 000000000..a72e36171 --- /dev/null +++ b/local-libs/vcluster/vclusterops/https_transaction_starts_op.go @@ -0,0 +1,138 @@ +/* + (c) Copyright [2023-2024] Open Text. + Licensed 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 vclusterops + +import ( + "errors" + "strconv" + "strings" +) + +type httpsTransactionStartsOp struct { + opBase + transactionID string + startTime string + endTime string + + // when debug mode is on, this op will return stub data + debug bool +} + +const ( + transactionStartsURL = "dc/transaction-starts" +) + +func makeHTTPSTransactionStartsOp(upHosts []string, transactionID, startTime, endTime string, debug bool) httpsTransactionStartsOp { + op := httpsTransactionStartsOp{} + op.name = "HTTPSTransactionStartsOp" + op.description = "Check transaction starts" + op.hosts = upHosts + op.transactionID = transactionID + op.startTime = startTime + op.endTime = endTime + op.debug = debug + return op +} + +// setupClusterHTTPRequest works as the module setup in Admintools +func (op *httpsTransactionStartsOp) setupClusterHTTPRequest(hosts []string) error { + // this op may consume resources of the database, + // thus we only need to send https request to one of the up hosts + + url := transactionStartsURL + queryParams := []string{} + if op.startTime != "" { + queryParams = append(queryParams, startTimeParam+op.startTime) + } + if op.endTime != "" { + queryParams = append(queryParams, endTimeParam+op.endTime) + } + if op.transactionID != "" { + queryParams = append(queryParams, txnIDParam+op.transactionID) + } + if op.debug { + queryParams = append(queryParams, debugParam+strconv.FormatBool(op.debug)) + } + for i, param := range queryParams { + // replace " " with "%20" in query params + queryParams[i] = strings.ReplaceAll(param, " ", "%20") + } + + if len(queryParams) > 0 { + url += "?" + strings.Join(queryParams, "&") + } + + for _, host := range hosts[:1] { + httpRequest := hostHTTPRequest{} + httpRequest.Method = GetMethod + httpRequest.buildHTTPSEndpoint(url) + op.clusterHTTPRequest.RequestCollection[host] = httpRequest + } + + return nil +} + +func (op *httpsTransactionStartsOp) prepare(execContext *opEngineExecContext) error { + execContext.dispatcher.setup(op.hosts) + + return op.setupClusterHTTPRequest(op.hosts) +} + +func (op *httpsTransactionStartsOp) execute(execContext *opEngineExecContext) error { + if err := op.runExecute(execContext); err != nil { + return err + } + + return op.processResult(execContext) +} + +func (op *httpsTransactionStartsOp) finalize(_ *opEngineExecContext) error { + return nil +} + +type dcTransactionStarts struct { + TransactionStartsList []dcTransactionStart `json:"dc_transaction_starts_list"` +} + +type dcTransactionStart struct { + Time string `json:"timestamp"` + NodeName string `json:"node_name"` + SessionID string `json:"session_id"` + UserName string `json:"user_name"` + TxnID string `json:"txn_id"` + Description string `json:"description"` +} + +func (op *httpsTransactionStartsOp) processResult(execContext *opEngineExecContext) error { + var allErrs error + for host, result := range op.clusterHTTPRequest.ResultCollection { + op.logResponse(host, result) + + if result.isPassing() { + var TransactionStarts dcTransactionStarts + err := op.parseAndCheckResponse(host, result.content, &TransactionStarts) + if err != nil { + return errors.Join(allErrs, err) + } + + // we only need result from one host + execContext.dcTransactionStarts = TransactionStarts + return allErrs + } + } + + return allErrs +} diff --git a/local-libs/vcluster/vclusterops/https_unsandbox_subcluster_op.go b/local-libs/vcluster/vclusterops/https_unsandbox_subcluster_op.go index 11538bfd8..fcfb922ce 100644 --- a/local-libs/vcluster/vclusterops/https_unsandbox_subcluster_op.go +++ b/local-libs/vcluster/vclusterops/https_unsandbox_subcluster_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/https_update_node_state_op.go b/local-libs/vcluster/vclusterops/https_update_node_state_op.go index e11dd2039..5015825fe 100644 --- a/local-libs/vcluster/vclusterops/https_update_node_state_op.go +++ b/local-libs/vcluster/vclusterops/https_update_node_state_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/install_packages.go b/local-libs/vcluster/vclusterops/install_packages.go index c35c5adfd..8f89a5a08 100644 --- a/local-libs/vcluster/vclusterops/install_packages.go +++ b/local-libs/vcluster/vclusterops/install_packages.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/manage_connection_draining.go b/local-libs/vcluster/vclusterops/manage_connection_draining.go index 94da4f48a..911f8ed4d 100644 --- a/local-libs/vcluster/vclusterops/manage_connection_draining.go +++ b/local-libs/vcluster/vclusterops/manage_connection_draining.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/manage_connection_draining_test.go b/local-libs/vcluster/vclusterops/manage_connection_draining_test.go index f70a253bf..2253525f7 100644 --- a/local-libs/vcluster/vclusterops/manage_connection_draining_test.go +++ b/local-libs/vcluster/vclusterops/manage_connection_draining_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/network_adapter.go b/local-libs/vcluster/vclusterops/network_adapter.go index 9e4e30ba4..2b95de92d 100644 --- a/local-libs/vcluster/vclusterops/network_adapter.go +++ b/local-libs/vcluster/vclusterops/network_adapter.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_bootstrap_catalog_op.go b/local-libs/vcluster/vclusterops/nma_bootstrap_catalog_op.go index c4cf52d28..e385e1fcd 100644 --- a/local-libs/vcluster/vclusterops/nma_bootstrap_catalog_op.go +++ b/local-libs/vcluster/vclusterops/nma_bootstrap_catalog_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_check_cluster_version_op.go b/local-libs/vcluster/vclusterops/nma_check_cluster_version_op.go index aa63e2427..29667b1f7 100644 --- a/local-libs/vcluster/vclusterops/nma_check_cluster_version_op.go +++ b/local-libs/vcluster/vclusterops/nma_check_cluster_version_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_check_vcluster_server_pid_op.go b/local-libs/vcluster/vclusterops/nma_check_vcluster_server_pid_op.go index dad9aff5a..ed9a58527 100644 --- a/local-libs/vcluster/vclusterops/nma_check_vcluster_server_pid_op.go +++ b/local-libs/vcluster/vclusterops/nma_check_vcluster_server_pid_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_clean_communal_storage_op.go b/local-libs/vcluster/vclusterops/nma_clean_communal_storage_op.go index 62413046d..be862f677 100644 --- a/local-libs/vcluster/vclusterops/nma_clean_communal_storage_op.go +++ b/local-libs/vcluster/vclusterops/nma_clean_communal_storage_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_delete_file_op.go b/local-libs/vcluster/vclusterops/nma_delete_file_op.go new file mode 100644 index 000000000..abc1d283f --- /dev/null +++ b/local-libs/vcluster/vclusterops/nma_delete_file_op.go @@ -0,0 +1,114 @@ +package vclusterops + +import ( + "encoding/json" + "errors" + "fmt" +) + +const ( + delFileOpName = "NMADeleteFileOp" + delFileOpDesc = "Delete file" +) + +// this op is for deleting a single file on the specified host +type nmaDeleteFileOp struct { + opBase + filePath string + hostRequestBodyMap map[string]string +} + +type deleteFileData struct { + FilePath string `json:"file_path"` +} + +func makeNMADeleteFileOp(hosts []string, filePath string) nmaDeleteFileOp { + op := nmaDeleteFileOp{} + op.name = delFileOpName + op.description = delFileOpDesc + op.hosts = hosts + op.filePath = filePath + + return op +} + +// make https json data +func (op *nmaDeleteFileOp) setupRequestBody() (map[string]string, error) { + hostRequestBodyMap := make(map[string]string, len(op.hosts)) + for _, host := range op.hosts { + requestData := deleteFileData{} + requestData.FilePath = op.filePath + + dataBytes, err := json.Marshal(requestData) + if err != nil { + return nil, fmt.Errorf("[%s] fail to marshal request data to JSON string, detail %w", op.name, err) + } + hostRequestBodyMap[host] = string(dataBytes) + } + + op.logger.Info("request data", "op name", op.name, "hostRequestBodyMap", op.hostRequestBodyMap) + return hostRequestBodyMap, nil +} + +func (op *nmaDeleteFileOp) setupClusterHTTPRequest(hostRequestBodyMap map[string]string) error { + for host, requestBody := range hostRequestBodyMap { + httpRequest := hostHTTPRequest{} + httpRequest.Method = PostMethod + httpRequest.buildNMAEndpoint("files/delete") + httpRequest.RequestData = requestBody + op.clusterHTTPRequest.RequestCollection[host] = httpRequest + } + + return nil +} + +func (op *nmaDeleteFileOp) prepare(execContext *opEngineExecContext) error { + hostRequestBodyMap, err := op.setupRequestBody() + if err != nil { + return err + } + + execContext.dispatcher.setup(op.hosts) + + return op.setupClusterHTTPRequest(hostRequestBodyMap) +} + +func (op *nmaDeleteFileOp) execute(execContext *opEngineExecContext) error { + if err := op.runExecute(execContext); err != nil { + return err + } + + return op.processResult(execContext) +} + +func (op *nmaDeleteFileOp) finalize(_ *opEngineExecContext) error { + return nil +} + +func (op *nmaDeleteFileOp) processResult(_ *opEngineExecContext) error { + var allErrs error + + for host, result := range op.clusterHTTPRequest.ResultCollection { + op.logResponse(host, result) + + if result.isPassing() { + // the response object will be a map e.g,.: + // {'/tmp/dummy_file.txt': 'deleted'} + responseObj, err := op.parseAndCheckMapResponse(host, result.content) + if err != nil { + allErrs = errors.Join(allErrs, err) + continue + } + + _, ok := responseObj["delete_file_return_code"] + if !ok { + err = fmt.Errorf(`[%s] response does not contain field "delete_file_return_code"`, op.name) + allErrs = errors.Join(allErrs, err) + } + } else { + allErrs = errors.Join(allErrs, result.err) + } + } + + return allErrs +} diff --git a/local-libs/vcluster/vclusterops/nma_download_config.go b/local-libs/vcluster/vclusterops/nma_download_config.go index c4b0181ad..23dfa5f79 100644 --- a/local-libs/vcluster/vclusterops/nma_download_config.go +++ b/local-libs/vcluster/vclusterops/nma_download_config.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 @@ -25,6 +25,7 @@ import ( const ( spreadConf = "config/spread" verticaConf = "config/vertica" + licenseKey = "config/license" ) type nmaDownloadConfigOp struct { @@ -59,6 +60,23 @@ func makeNMADownloadConfigOp( return op } +func makeNMADownloadLicenseOp( + sourceHost, filePath string, + fileContent *string) nmaDownloadConfigOp { + op := nmaDownloadConfigOp{} + op.name = "NMADownloadLicenseKeyOp" + op.hosts = []string{sourceHost} + op.endpoint = licenseKey + op.description = "Get contents of license key" + op.fileContent = fileContent + op.catalogPathMap = make(map[string]string) + op.catalogPathMap[sourceHost] = filePath + op.vdb = nil + // upgrade license key can only be done on main cluster + op.sandbox = nil + return op +} + func (op *nmaDownloadConfigOp) setupClusterHTTPRequest(hosts []string) error { for _, host := range hosts { httpRequest := hostHTTPRequest{} @@ -78,6 +96,21 @@ func (op *nmaDownloadConfigOp) setupClusterHTTPRequest(hosts []string) error { } func (op *nmaDownloadConfigOp) prepare(execContext *opEngineExecContext) error { + // shortcut for license key, as the op has to be done on the passed-in host + if op.endpoint == licenseKey { + return op.prepareForDownloadLicense(execContext) + } + + return op.prepareForDownloadConfigs(execContext) +} + +func (op *nmaDownloadConfigOp) prepareForDownloadLicense(execContext *opEngineExecContext) error { + execContext.dispatcher.setup(op.hosts) + + return op.setupClusterHTTPRequest(op.hosts) +} + +func (op *nmaDownloadConfigOp) prepareForDownloadConfigs(execContext *opEngineExecContext) error { op.catalogPathMap = make(map[string]string) // vdb is built by calling /cluster and /nodes endpoints of a running db. // If nodes' info is not available in vdb, we will get the host from execContext.nmaVDatabase which is build by reading the catalog editor diff --git a/local-libs/vcluster/vclusterops/nma_download_file_op.go b/local-libs/vcluster/vclusterops/nma_download_file_op.go index 284ee68c4..20c7ff00a 100644 --- a/local-libs/vcluster/vclusterops/nma_download_file_op.go +++ b/local-libs/vcluster/vclusterops/nma_download_file_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_download_file_op_test.go b/local-libs/vcluster/vclusterops/nma_download_file_op_test.go index 591f440dd..99dcc6eb2 100644 --- a/local-libs/vcluster/vclusterops/nma_download_file_op_test.go +++ b/local-libs/vcluster/vclusterops/nma_download_file_op_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_get_config_parameter_op.go b/local-libs/vcluster/vclusterops/nma_get_config_parameter_op.go index 4ed831191..b971a45c3 100644 --- a/local-libs/vcluster/vclusterops/nma_get_config_parameter_op.go +++ b/local-libs/vcluster/vclusterops/nma_get_config_parameter_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_get_config_parameter_op_test.go b/local-libs/vcluster/vclusterops/nma_get_config_parameter_op_test.go index 8b414b10a..738e36631 100644 --- a/local-libs/vcluster/vclusterops/nma_get_config_parameter_op_test.go +++ b/local-libs/vcluster/vclusterops/nma_get_config_parameter_op_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_get_healthy_nodes_op.go b/local-libs/vcluster/vclusterops/nma_get_healthy_nodes_op.go index 7f2d063e0..21ae73385 100644 --- a/local-libs/vcluster/vclusterops/nma_get_healthy_nodes_op.go +++ b/local-libs/vcluster/vclusterops/nma_get_healthy_nodes_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_get_nodes_info_op.go b/local-libs/vcluster/vclusterops/nma_get_nodes_info_op.go index 3e954ba6e..18f1ee176 100644 --- a/local-libs/vcluster/vclusterops/nma_get_nodes_info_op.go +++ b/local-libs/vcluster/vclusterops/nma_get_nodes_info_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_get_scrutinize_tar_op.go b/local-libs/vcluster/vclusterops/nma_get_scrutinize_tar_op.go index d2f442a4c..6e58115cc 100644 --- a/local-libs/vcluster/vclusterops/nma_get_scrutinize_tar_op.go +++ b/local-libs/vcluster/vclusterops/nma_get_scrutinize_tar_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_health_op.go b/local-libs/vcluster/vclusterops/nma_health_op.go index c5dadceb0..ecb700637 100644 --- a/local-libs/vcluster/vclusterops/nma_health_op.go +++ b/local-libs/vcluster/vclusterops/nma_health_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_load_remote_catalog_op.go b/local-libs/vcluster/vclusterops/nma_load_remote_catalog_op.go index da7152780..c151dec5f 100644 --- a/local-libs/vcluster/vclusterops/nma_load_remote_catalog_op.go +++ b/local-libs/vcluster/vclusterops/nma_load_remote_catalog_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_manage_connections_op.go b/local-libs/vcluster/vclusterops/nma_manage_connections_op.go index 0a7f4b7e8..ed6f298f2 100644 --- a/local-libs/vcluster/vclusterops/nma_manage_connections_op.go +++ b/local-libs/vcluster/vclusterops/nma_manage_connections_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_manage_connections_op_test.go b/local-libs/vcluster/vclusterops/nma_manage_connections_op_test.go index 045fa70e5..14455130c 100644 --- a/local-libs/vcluster/vclusterops/nma_manage_connections_op_test.go +++ b/local-libs/vcluster/vclusterops/nma_manage_connections_op_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_network_profile_op.go b/local-libs/vcluster/vclusterops/nma_network_profile_op.go index d72bb0839..8fd8934c3 100644 --- a/local-libs/vcluster/vclusterops/nma_network_profile_op.go +++ b/local-libs/vcluster/vclusterops/nma_network_profile_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_poll_replication_status.go b/local-libs/vcluster/vclusterops/nma_poll_replication_status.go index 45e485fa8..2b34056cd 100644 --- a/local-libs/vcluster/vclusterops/nma_poll_replication_status.go +++ b/local-libs/vcluster/vclusterops/nma_poll_replication_status.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_prepare_directories_op.go b/local-libs/vcluster/vclusterops/nma_prepare_directories_op.go index d4e0a4ab8..74b3a9edc 100644 --- a/local-libs/vcluster/vclusterops/nma_prepare_directories_op.go +++ b/local-libs/vcluster/vclusterops/nma_prepare_directories_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_prepare_scrutinizer_directories_op.go b/local-libs/vcluster/vclusterops/nma_prepare_scrutinizer_directories_op.go index 0bf15f18e..7506bf52d 100644 --- a/local-libs/vcluster/vclusterops/nma_prepare_scrutinizer_directories_op.go +++ b/local-libs/vcluster/vclusterops/nma_prepare_scrutinizer_directories_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_re_ip_op.go b/local-libs/vcluster/vclusterops/nma_re_ip_op.go index 992bb661b..1838fbc2a 100644 --- a/local-libs/vcluster/vclusterops/nma_re_ip_op.go +++ b/local-libs/vcluster/vclusterops/nma_re_ip_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_read_catalog_editor_op.go b/local-libs/vcluster/vclusterops/nma_read_catalog_editor_op.go index ada99d53f..6e4a18706 100644 --- a/local-libs/vcluster/vclusterops/nma_read_catalog_editor_op.go +++ b/local-libs/vcluster/vclusterops/nma_read_catalog_editor_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_replication_start.go b/local-libs/vcluster/vclusterops/nma_replication_start.go index a050794f6..3511fbf4d 100644 --- a/local-libs/vcluster/vclusterops/nma_replication_start.go +++ b/local-libs/vcluster/vclusterops/nma_replication_start.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_replication_status.go b/local-libs/vcluster/vclusterops/nma_replication_status.go index 7a21b62f8..a10a47e32 100644 --- a/local-libs/vcluster/vclusterops/nma_replication_status.go +++ b/local-libs/vcluster/vclusterops/nma_replication_status.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_save_restore_points_op.go b/local-libs/vcluster/vclusterops/nma_save_restore_points_op.go index e64b9b0ef..4d3cfcb45 100644 --- a/local-libs/vcluster/vclusterops/nma_save_restore_points_op.go +++ b/local-libs/vcluster/vclusterops/nma_save_restore_points_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_set_config_parameter_op.go b/local-libs/vcluster/vclusterops/nma_set_config_parameter_op.go index c15c8e9cd..7c1d1df0d 100644 --- a/local-libs/vcluster/vclusterops/nma_set_config_parameter_op.go +++ b/local-libs/vcluster/vclusterops/nma_set_config_parameter_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_set_config_parameter_op_test.go b/local-libs/vcluster/vclusterops/nma_set_config_parameter_op_test.go index 8866e3a6b..a1f83f3e1 100644 --- a/local-libs/vcluster/vclusterops/nma_set_config_parameter_op_test.go +++ b/local-libs/vcluster/vclusterops/nma_set_config_parameter_op_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_show_restore_points_op.go b/local-libs/vcluster/vclusterops/nma_show_restore_points_op.go index 74c8e27e2..959f35e25 100644 --- a/local-libs/vcluster/vclusterops/nma_show_restore_points_op.go +++ b/local-libs/vcluster/vclusterops/nma_show_restore_points_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_show_restore_points_op_test.go b/local-libs/vcluster/vclusterops/nma_show_restore_points_op_test.go index deaa665cc..d97cebcd9 100644 --- a/local-libs/vcluster/vclusterops/nma_show_restore_points_op_test.go +++ b/local-libs/vcluster/vclusterops/nma_show_restore_points_op_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_spread_security_op.go b/local-libs/vcluster/vclusterops/nma_spread_security_op.go index 22ef70cd4..7e8cbd6fa 100644 --- a/local-libs/vcluster/vclusterops/nma_spread_security_op.go +++ b/local-libs/vcluster/vclusterops/nma_spread_security_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_spread_security_op_test.go b/local-libs/vcluster/vclusterops/nma_spread_security_op_test.go index 5df3ce1db..e8dc4297b 100644 --- a/local-libs/vcluster/vclusterops/nma_spread_security_op_test.go +++ b/local-libs/vcluster/vclusterops/nma_spread_security_op_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_stage_dc_tables_op.go b/local-libs/vcluster/vclusterops/nma_stage_dc_tables_op.go index 59245daff..275037d28 100644 --- a/local-libs/vcluster/vclusterops/nma_stage_dc_tables_op.go +++ b/local-libs/vcluster/vclusterops/nma_stage_dc_tables_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_stage_vertica_logs_op.go b/local-libs/vcluster/vclusterops/nma_stage_vertica_logs_op.go index fde54769d..8518471c4 100644 --- a/local-libs/vcluster/vclusterops/nma_stage_vertica_logs_op.go +++ b/local-libs/vcluster/vclusterops/nma_stage_vertica_logs_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_start_node_op.go b/local-libs/vcluster/vclusterops/nma_start_node_op.go index be65a4db9..2142df63c 100644 --- a/local-libs/vcluster/vclusterops/nma_start_node_op.go +++ b/local-libs/vcluster/vclusterops/nma_start_node_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_upload_config.go b/local-libs/vcluster/vclusterops/nma_upload_config.go index b5c918c98..4cf0c9ee9 100644 --- a/local-libs/vcluster/vclusterops/nma_upload_config.go +++ b/local-libs/vcluster/vclusterops/nma_upload_config.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 @@ -64,6 +64,7 @@ func makeNMAUploadConfigOp( } else if op.endpoint == spreadConf { op.description = "Send contents of spread.conf to nodes" } + op.fileContent = fileContent op.catalogPathMap = make(map[string]string) op.sourceConfigHost = sourceConfigHost @@ -73,6 +74,26 @@ func makeNMAUploadConfigOp( return op } +func makeNMAUploadLicenseOp( + sourceHost, targetHost, tempLicensePath string, + fileContent *string, +) nmaUploadConfigOp { + op := nmaUploadConfigOp{} + op.name = "NMAUploadLicenseOp" + op.endpoint = licenseKey + op.description = "Send contents of license key to the target node" + op.fileContent = fileContent + // re-use the catalog_path as the path for writing the temp license file + op.catalogPathMap = make(map[string]string) + op.catalogPathMap[targetHost] = tempLicensePath + op.sourceConfigHost = []string{sourceHost} + op.destHosts = []string{targetHost} + op.hosts = op.destHosts + op.vdb = nil + + return op +} + func (op *nmaUploadConfigOp) setupRequestBody(hosts []string) error { op.hostRequestBodyMap = make(map[string]string) @@ -104,7 +125,21 @@ func (op *nmaUploadConfigOp) setupClusterHTTPRequest(hosts []string) error { return nil } +func (op *nmaUploadConfigOp) completePrepare(execContext *opEngineExecContext) error { + err := op.setupRequestBody(op.hosts) + if err != nil { + return err + } + execContext.dispatcher.setup(op.hosts) + + return op.setupClusterHTTPRequest(op.hosts) +} + func (op *nmaUploadConfigOp) prepare(execContext *opEngineExecContext) error { + // shortcut for transferring license, it only has to be on the target host + if op.endpoint == licenseKey { + return op.completePrepare(execContext) + } op.catalogPathMap = make(map[string]string) // If any node's info is available, we set catalogPathMap from node's info. // This case is used for starting nodes operation. @@ -156,13 +191,7 @@ func (op *nmaUploadConfigOp) prepare(execContext *opEngineExecContext) error { } } - err := op.setupRequestBody(op.hosts) - if err != nil { - return err - } - execContext.dispatcher.setup(op.hosts) - - return op.setupClusterHTTPRequest(op.hosts) + return op.completePrepare(execContext) } func (op *nmaUploadConfigOp) execute(execContext *opEngineExecContext) error { diff --git a/local-libs/vcluster/vclusterops/nma_vertica_version_op.go b/local-libs/vcluster/vclusterops/nma_vertica_version_op.go index ae91cf525..41af69825 100644 --- a/local-libs/vcluster/vclusterops/nma_vertica_version_op.go +++ b/local-libs/vcluster/vclusterops/nma_vertica_version_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/nma_vertica_version_op_test.go b/local-libs/vcluster/vclusterops/nma_vertica_version_op_test.go index fbb4bfa99..b983bb8be 100644 --- a/local-libs/vcluster/vclusterops/nma_vertica_version_op_test.go +++ b/local-libs/vcluster/vclusterops/nma_vertica_version_op_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/node_info.go b/local-libs/vcluster/vclusterops/node_info.go index 570424e37..05936ffe2 100644 --- a/local-libs/vcluster/vclusterops/node_info.go +++ b/local-libs/vcluster/vclusterops/node_info.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/node_info_test.go b/local-libs/vcluster/vclusterops/node_info_test.go index 97650e296..535231c99 100644 --- a/local-libs/vcluster/vclusterops/node_info_test.go +++ b/local-libs/vcluster/vclusterops/node_info_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/poll_sc_state.go b/local-libs/vcluster/vclusterops/poll_sc_state.go index 77d60c3d6..baf606e09 100644 --- a/local-libs/vcluster/vclusterops/poll_sc_state.go +++ b/local-libs/vcluster/vclusterops/poll_sc_state.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/promote_sandbox_to_main.go b/local-libs/vcluster/vclusterops/promote_sandbox_to_main.go index 36a140d77..586791590 100644 --- a/local-libs/vcluster/vclusterops/promote_sandbox_to_main.go +++ b/local-libs/vcluster/vclusterops/promote_sandbox_to_main.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/promote_sandbox_to_main_test.go b/local-libs/vcluster/vclusterops/promote_sandbox_to_main_test.go index d3a2f19dd..351eae98b 100644 --- a/local-libs/vcluster/vclusterops/promote_sandbox_to_main_test.go +++ b/local-libs/vcluster/vclusterops/promote_sandbox_to_main_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/re_ip.go b/local-libs/vcluster/vclusterops/re_ip.go index 459ee2b5d..fd590828d 100644 --- a/local-libs/vcluster/vclusterops/re_ip.go +++ b/local-libs/vcluster/vclusterops/re_ip.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/re_ip_test.go b/local-libs/vcluster/vclusterops/re_ip_test.go index a669c4836..050c93029 100644 --- a/local-libs/vcluster/vclusterops/re_ip_test.go +++ b/local-libs/vcluster/vclusterops/re_ip_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/remove_node.go b/local-libs/vcluster/vclusterops/remove_node.go index 3e63c273c..c47bf3833 100644 --- a/local-libs/vcluster/vclusterops/remove_node.go +++ b/local-libs/vcluster/vclusterops/remove_node.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/remove_subcluster.go b/local-libs/vcluster/vclusterops/remove_subcluster.go index 6b665b963..c4cfa5eda 100644 --- a/local-libs/vcluster/vclusterops/remove_subcluster.go +++ b/local-libs/vcluster/vclusterops/remove_subcluster.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/remove_subcluster_test.go b/local-libs/vcluster/vclusterops/remove_subcluster_test.go index b2956f0b2..f11d05028 100644 --- a/local-libs/vcluster/vclusterops/remove_subcluster_test.go +++ b/local-libs/vcluster/vclusterops/remove_subcluster_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/rename_subcluster.go b/local-libs/vcluster/vclusterops/rename_subcluster.go index a8abcecb2..7d558e6b5 100644 --- a/local-libs/vcluster/vclusterops/rename_subcluster.go +++ b/local-libs/vcluster/vclusterops/rename_subcluster.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/rename_subcluster_test.go b/local-libs/vcluster/vclusterops/rename_subcluster_test.go index 32f794083..8b38659f6 100644 --- a/local-libs/vcluster/vclusterops/rename_subcluster_test.go +++ b/local-libs/vcluster/vclusterops/rename_subcluster_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/replication.go b/local-libs/vcluster/vclusterops/replication.go index 2cc2d5c6d..3ca81b17d 100644 --- a/local-libs/vcluster/vclusterops/replication.go +++ b/local-libs/vcluster/vclusterops/replication.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/replication_status.go b/local-libs/vcluster/vclusterops/replication_status.go index 518129f6f..7e49c848f 100644 --- a/local-libs/vcluster/vclusterops/replication_status.go +++ b/local-libs/vcluster/vclusterops/replication_status.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 @@ -18,6 +18,7 @@ package vclusterops import ( "fmt" "sort" + "strings" "time" "github.com/vertica/vcluster/vclusterops/util" @@ -48,6 +49,8 @@ type ReplicationStatusResponse struct { // 'started', 'failed', 'completed' Status string `json:"status"` + ErrMsg string + // Node the current replication operation is on NodeName string `json:"node_name"` @@ -237,8 +240,7 @@ func getFinalReplicationStatus(replicationStatus []ReplicationStatusResponse) *R // Get the rest of the status info from the current op (the last op in the sorted list) currentOp := replicationStatus[len(replicationStatus)-1] - - finalReplicationStatus.Status = currentOp.Status + setStatusAndErrMsg(&finalReplicationStatus, ¤tOp) finalReplicationStatus.EndTime = currentOp.EndTime finalReplicationStatus.OpName = currentOp.OpName finalReplicationStatus.SentBytes = currentOp.SentBytes @@ -247,3 +249,12 @@ func getFinalReplicationStatus(replicationStatus []ReplicationStatusResponse) *R return &finalReplicationStatus } + +func setStatusAndErrMsg(finalReplicationStatus, currentOp *ReplicationStatusResponse) { + if strings.HasPrefix(currentOp.Status, "failed:") { + finalReplicationStatus.Status = "failed" + finalReplicationStatus.ErrMsg = strings.TrimSpace(currentOp.Status[7:]) + } else { + finalReplicationStatus.Status = currentOp.Status + } +} diff --git a/local-libs/vcluster/vclusterops/replication_status_test.go b/local-libs/vcluster/vclusterops/replication_status_test.go index 43b70ebfe..6e450df36 100644 --- a/local-libs/vcluster/vclusterops/replication_status_test.go +++ b/local-libs/vcluster/vclusterops/replication_status_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 @@ -67,7 +67,7 @@ var ( } node1LoadSnapshotFailed = ReplicationStatusResponse{ OpName: loadSnapshotOp, - Status: failedStatus, + Status: "failed: Restore: Can replicate/restore public schema only to the default namespace", NodeName: node1, StartTime: "Mon Sep 23 16:08:11 EDT 2024", EndTime: "Mon Sep 23 16:08:13 EDT 2024", @@ -158,6 +158,7 @@ func TestGetFinalReplicationStatus(t *testing.T) { expectedStatus = ReplicationStatusResponse{ OpName: loadSnapshotOp, Status: failedStatus, + ErrMsg: "Restore: Can replicate/restore public schema only to the default namespace", NodeName: node1, StartTime: "Mon Sep 23 16:08:11 EDT 2024", EndTime: "Mon Sep 23 16:08:13 EDT 2024", @@ -214,6 +215,7 @@ func TestGetFinalReplicationStatus(t *testing.T) { expectedStatus = ReplicationStatusResponse{ OpName: loadSnapshotOp, Status: completedStatus, + ErrMsg: "", NodeName: node2, StartTime: "Mon Sep 23 16:08:11 EDT 2024", EndTime: "Mon Sep 23 16:08:14 EDT 2024", diff --git a/local-libs/vcluster/vclusterops/revive_db.go b/local-libs/vcluster/vclusterops/revive_db.go index b354bdbaf..d1085fdce 100644 --- a/local-libs/vcluster/vclusterops/revive_db.go +++ b/local-libs/vcluster/vclusterops/revive_db.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/sandbox.go b/local-libs/vcluster/vclusterops/sandbox.go index abf552ce9..eaea7c690 100644 --- a/local-libs/vcluster/vclusterops/sandbox.go +++ b/local-libs/vcluster/vclusterops/sandbox.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/save_restore_points.go b/local-libs/vcluster/vclusterops/save_restore_points.go index b7582c4ed..5c6540118 100644 --- a/local-libs/vcluster/vclusterops/save_restore_points.go +++ b/local-libs/vcluster/vclusterops/save_restore_points.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/scrutinize.go b/local-libs/vcluster/vclusterops/scrutinize.go index 20f636ce2..3fa8b1a45 100644 --- a/local-libs/vcluster/vclusterops/scrutinize.go +++ b/local-libs/vcluster/vclusterops/scrutinize.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 @@ -27,7 +27,7 @@ import ( ) // files and folders used by scrutinize -const ScrutinizeOutputBasePath = "/tmp/scrutinize" +const ScrutinizeOutputBasePath = util.TmpDir + "/scrutinize" const scrutinizeRemoteOutputPath = ScrutinizeOutputBasePath + "/remote" const scrutinizeLogFileName = "vcluster.log" diff --git a/local-libs/vcluster/vclusterops/scrutinize_op.go b/local-libs/vcluster/vclusterops/scrutinize_op.go index 8c5c2a133..be3f36d89 100644 --- a/local-libs/vcluster/vclusterops/scrutinize_op.go +++ b/local-libs/vcluster/vclusterops/scrutinize_op.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/set_config_parameter.go b/local-libs/vcluster/vclusterops/set_config_parameter.go index fa32026cd..7f7a43468 100644 --- a/local-libs/vcluster/vclusterops/set_config_parameter.go +++ b/local-libs/vcluster/vclusterops/set_config_parameter.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/set_config_parameter_test.go b/local-libs/vcluster/vclusterops/set_config_parameter_test.go index 0c78b2a7c..5cece21ae 100644 --- a/local-libs/vcluster/vclusterops/set_config_parameter_test.go +++ b/local-libs/vcluster/vclusterops/set_config_parameter_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/show_restore_points.go b/local-libs/vcluster/vclusterops/show_restore_points.go index 89ff1ff18..609e6d17c 100644 --- a/local-libs/vcluster/vclusterops/show_restore_points.go +++ b/local-libs/vcluster/vclusterops/show_restore_points.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/sql_endpoint_common.go b/local-libs/vcluster/vclusterops/sql_endpoint_common.go index 43860b15f..bd1fe451f 100644 --- a/local-libs/vcluster/vclusterops/sql_endpoint_common.go +++ b/local-libs/vcluster/vclusterops/sql_endpoint_common.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/start_db.go b/local-libs/vcluster/vclusterops/start_db.go index 622a50c64..6e586b244 100644 --- a/local-libs/vcluster/vclusterops/start_db.go +++ b/local-libs/vcluster/vclusterops/start_db.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/start_node.go b/local-libs/vcluster/vclusterops/start_node.go index 79e27f499..b2055781b 100644 --- a/local-libs/vcluster/vclusterops/start_node.go +++ b/local-libs/vcluster/vclusterops/start_node.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/start_subcluster.go b/local-libs/vcluster/vclusterops/start_subcluster.go index 2cba327f3..d7af707fc 100644 --- a/local-libs/vcluster/vclusterops/start_subcluster.go +++ b/local-libs/vcluster/vclusterops/start_subcluster.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/state_poller.go b/local-libs/vcluster/vclusterops/state_poller.go index 15b7404d0..9b099458f 100644 --- a/local-libs/vcluster/vclusterops/state_poller.go +++ b/local-libs/vcluster/vclusterops/state_poller.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/stop_db.go b/local-libs/vcluster/vclusterops/stop_db.go index cffb21786..69061cd93 100644 --- a/local-libs/vcluster/vclusterops/stop_db.go +++ b/local-libs/vcluster/vclusterops/stop_db.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/stop_node.go b/local-libs/vcluster/vclusterops/stop_node.go index 572449b5d..737beebad 100644 --- a/local-libs/vcluster/vclusterops/stop_node.go +++ b/local-libs/vcluster/vclusterops/stop_node.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/stop_subcluster.go b/local-libs/vcluster/vclusterops/stop_subcluster.go index 128db6518..de956f4e9 100644 --- a/local-libs/vcluster/vclusterops/stop_subcluster.go +++ b/local-libs/vcluster/vclusterops/stop_subcluster.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/unsandbox.go b/local-libs/vcluster/vclusterops/unsandbox.go index 5a095eb0e..2ed5cb002 100644 --- a/local-libs/vcluster/vclusterops/unsandbox.go +++ b/local-libs/vcluster/vclusterops/unsandbox.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/upgrade_license.go b/local-libs/vcluster/vclusterops/upgrade_license.go index 8bd245d8b..8397abb21 100644 --- a/local-libs/vcluster/vclusterops/upgrade_license.go +++ b/local-libs/vcluster/vclusterops/upgrade_license.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 @@ -17,17 +17,26 @@ package vclusterops import ( "fmt" + "path/filepath" "github.com/vertica/vcluster/vclusterops/util" "github.com/vertica/vcluster/vclusterops/vlog" ) +const tempLicensePath = util.TmpDir + "/temp_vertica_license" + type VUpgradeLicenseOptions struct { DatabaseOptions - // Required arguments + // Required argument LicenseFilePath string - LicenseHost string + + // Optional argument, if not provided, then assume license file on localhost + LicenseHost string + // Calculated hidden argument, any value passed from callers will be ignored + LocalHostAddr string + // hidden argument for early check on file type, any value passed from callers will be ignored + StageLicensePath string } func VUpgradeLicenseFactory() VUpgradeLicenseOptions { @@ -51,7 +60,7 @@ func (options *VUpgradeLicenseOptions) validateRequiredOptions(logger vlog.Print return fmt.Errorf("must specify a license file") } if options.LicenseHost == "" { - return fmt.Errorf("must specify a host the license file located on") + logger.Info("no license host provided, considering license file on local host") } // license file must be specified as an absolute path err = util.ValidateAbsPath(options.LicenseFilePath, "license file path") @@ -78,13 +87,32 @@ func (options *VUpgradeLicenseOptions) validateParseOptions(log vlog.Printer) er // analyzeOptions will modify some options based on what is chosen func (options *VUpgradeLicenseOptions) analyzeOptions() (err error) { - // resolve license host to be IP addresses - licenseHostAddr, err := util.ResolveToOneIP(options.LicenseHost, options.IPv6) - if err != nil { - return err + // make sure the specified file path has a file extension + licenseExt := filepath.Ext(options.LicenseFilePath) + // no extension, it's not a file + if licenseExt == "" { + return fmt.Errorf("must specify a valid file path") + } + + if options.LicenseHost != "" { + // resolve license host to be IP addresses + licenseHostAddr, err := util.ResolveToOneIP(options.LicenseHost, options.IPv6) + if err != nil { + return err + } + + options.LicenseHost = licenseHostAddr + } else { + // using localhost as source host for transferring the license file, should resolve localhost to one IP + // resolve license host to be IP addresses + localHostAddr, err := util.ResolveToOneIP(util.LocalHost, options.IPv6) + if err != nil { + return err + } + options.LocalHostAddr = localHostAddr + // also set the temporary license file path for staging the file on a remote host + options.StageLicensePath = tempLicensePath + licenseExt } - // install license call has to be done on the host that has the license file - options.LicenseHost = licenseHostAddr if len(options.RawHosts) > 0 { // resolve RawHosts to be IP addresses hostAddresses, err := util.ResolveRawHostsToAddresses(options.RawHosts, options.IPv6) @@ -125,7 +153,7 @@ func (vcc VClusterCommands) VUpgradeLicense(options *VUpgradeLicenseOptions) err // produce create acchive instructions instructions, err := vcc.produceUpgradeLicenseInstructions(options) if err != nil { - return fmt.Errorf("fail to produce instructions, %w", err) + return fmt.Errorf("fail to produce INSTRUCTIONS, %w", err) } // create a VClusterOpEngine, and add certs to the engine @@ -140,8 +168,13 @@ func (vcc VClusterCommands) VUpgradeLicense(options *VUpgradeLicenseOptions) err } // The generated instructions will later perform the following operations necessary -// for a successful create_archive: +// if users specify a remote license host: // - Run install license API +// +// otherwise: +// - Transfer the specified license file on localhost to an UP node +// - Run install license API on the UP primary node +// - Delete the temporary license file on the UP primary node func (vcc *VClusterCommands) produceUpgradeLicenseInstructions(options *VUpgradeLicenseOptions) ([]clusterOp, error) { var instructions []clusterOp vdb := makeVCoordinationDatabase() @@ -155,21 +188,53 @@ func (vcc *VClusterCommands) produceUpgradeLicenseInstructions(options *VUpgrade hosts := options.Hosts // Trim host list hosts = vdb.filterUpHostlist(hosts, util.MainClusterSandbox) - // if license host isn't an UP host, error out - // this license upgrade has to be done in main cluster - if !util.StringInArray(options.LicenseHost, hosts) { - return instructions, fmt.Errorf("license file must be on an UP host, the specified host %s is not UP", options.LicenseHost) + + // should not happen, but adding a guardrail + if len(hosts) == 0 { + return instructions, fmt.Errorf("found no UP nodes for upgrading license") } - initiatorHost := []string{options.LicenseHost} + // shortcut if users specified a remote host + if options.LicenseHost != "" { + // if specified license host isn't an UP host, error out + // this license upgrade has to be done in main cluster + if !util.StringInArray(options.LicenseHost, hosts) { + return instructions, fmt.Errorf("license file must be on an UP host, the specified host %s is not UP", options.LicenseHost) + } - httpsInstallLicenseOp, err := makeHTTPSInstallLicenseOp(initiatorHost, options.usePassword, - options.UserName, options.Password, options.LicenseFilePath) - if err != nil { - return instructions, err + initiatorHost := []string{options.LicenseHost} + + httpsInstallLicenseOp, err := makeHTTPSInstallLicenseOp(initiatorHost, options.usePassword, + options.UserName, options.Password, options.LicenseFilePath) + if err != nil { + return instructions, err + } + + instructions = append(instructions, &httpsInstallLicenseOp) + return instructions, nil + } + // if users do not specify a remote license host, transfer local license file to a primary UP node and perform upgrade + // initiator is the host on which HTTPS install license endpoint will run + initiator, setInitiatorErr := getInitiatorHost(vdb.PrimaryUpNodes, []string{} /* skip hosts */) + if setInitiatorErr != nil { + return instructions, setInitiatorErr + } + + // step 1: transfer the local license file to the initiator host + produceTransferLicenseOps(&instructions, options.LocalHostAddr, initiator, + options.LicenseFilePath, options.StageLicensePath) + + initiatorHost := []string{initiator} + // step 2: upgrade license + httpsInstallLicenseOp, makeOpErr := makeHTTPSInstallLicenseOp(initiatorHost, options.usePassword, + options.UserName, options.Password, options.StageLicensePath) + if makeOpErr != nil { + return instructions, makeOpErr } + instructions = append(instructions, &httpsInstallLicenseOp) - instructions = append(instructions, - &httpsInstallLicenseOp) + // step 3: clean up the stage license file + nmaDeleteFileOp := makeNMADeleteFileOp(initiatorHost, options.StageLicensePath) + instructions = append(instructions, &nmaDeleteFileOp) return instructions, nil } diff --git a/local-libs/vcluster/vclusterops/util/defaults.go b/local-libs/vcluster/vclusterops/util/defaults.go index 047fc8cec..f9bf9720c 100644 --- a/local-libs/vcluster/vclusterops/util/defaults.go +++ b/local-libs/vcluster/vclusterops/util/defaults.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/util/util.go b/local-libs/vcluster/vclusterops/util/util.go index fbd5ddaf9..e91285353 100644 --- a/local-libs/vcluster/vclusterops/util/util.go +++ b/local-libs/vcluster/vclusterops/util/util.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 @@ -48,6 +48,7 @@ type FetchAllEnvVars interface { const ( RootDir = "/" + TmpDir = "/tmp" NodeInfoCountMismatch = "[%s] expect one node's information, but got %d nodes' information from HTTPS /v1/nodes/ endpoint on host %s" DepotSizeHint = "integer%, which expresses the depot size as a percentage of the total disk size." DepotSizeKMGTMsg = "integer{K|M|G|T}, where K is kilobytes, M is megabytes, G is gigabytes, and T is terabytes.\n" @@ -75,6 +76,7 @@ const ( keyValueArrayLen = 2 ipv4Str = "IPv4" ipv6Str = "IPv6" + LocalHost = "localhost" AWSAuthKey = "awsauth" kubernetesPort = "KUBERNETES_PORT" diff --git a/local-libs/vcluster/vclusterops/util/util_test.go b/local-libs/vcluster/vclusterops/util/util_test.go index 6790c3270..facb407f6 100644 --- a/local-libs/vcluster/vclusterops/util/util_test.go +++ b/local-libs/vcluster/vclusterops/util/util_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/vcluster_database_options.go b/local-libs/vcluster/vclusterops/vcluster_database_options.go index 58d0f26c9..31e90c868 100644 --- a/local-libs/vcluster/vclusterops/vcluster_database_options.go +++ b/local-libs/vcluster/vclusterops/vcluster_database_options.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/vcluster_database_options_test.go b/local-libs/vcluster/vclusterops/vcluster_database_options_test.go index 7998d3fbb..38d5d7d88 100644 --- a/local-libs/vcluster/vclusterops/vcluster_database_options_test.go +++ b/local-libs/vcluster/vclusterops/vcluster_database_options_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/vcluster_version.go b/local-libs/vcluster/vclusterops/vcluster_version.go index 523cc0b95..cfd730b31 100644 --- a/local-libs/vcluster/vclusterops/vcluster_version.go +++ b/local-libs/vcluster/vclusterops/vcluster_version.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 @@ -11,6 +11,8 @@ 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. + + This is a test12! */ package vclusterops diff --git a/local-libs/vcluster/vclusterops/vcluster_version_test.go b/local-libs/vcluster/vclusterops/vcluster_version_test.go index 374bd3fff..2c8c2c609 100644 --- a/local-libs/vcluster/vclusterops/vcluster_version_test.go +++ b/local-libs/vcluster/vclusterops/vcluster_version_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/vlog/printer.go b/local-libs/vcluster/vclusterops/vlog/printer.go index 8fbbd92a8..842ac7516 100644 --- a/local-libs/vcluster/vclusterops/vlog/printer.go +++ b/local-libs/vcluster/vclusterops/vlog/printer.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/vlog/printer_test.go b/local-libs/vcluster/vclusterops/vlog/printer_test.go index 1152daf81..7e4a8f736 100644 --- a/local-libs/vcluster/vclusterops/vlog/printer_test.go +++ b/local-libs/vcluster/vclusterops/vlog/printer_test.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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 diff --git a/local-libs/vcluster/vclusterops/vstruct/vstruct.go b/local-libs/vcluster/vclusterops/vstruct/vstruct.go index e4f5e031c..517fb7ac0 100644 --- a/local-libs/vcluster/vclusterops/vstruct/vstruct.go +++ b/local-libs/vcluster/vclusterops/vstruct/vstruct.go @@ -1,5 +1,5 @@ /* - (c) Copyright [2023-2024] Open Text. + (c) Copyright [2023-2025] Open Text. Licensed 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