1 /* 2 Copyright (c) DataStax, Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 #ifndef __CCM_BRIDGE_HPP__ 18 #define __CCM_BRIDGE_HPP__ 19 20 #include "authentication_type.hpp" 21 #include "bridge_exception.hpp" 22 #include "cass_version.hpp" 23 #include "deployment_type.hpp" 24 #include "dse_credentials_type.hpp" 25 #include "process.hpp" 26 #include "server_type.hpp" 27 #include "tsocket.hpp" 28 29 #include <map> 30 #include <string> 31 #include <vector> 32 33 #ifdef CASS_USE_LIBSSH2 34 // Forward declarations for libssh2 35 typedef struct _LIBSSH2_SESSION LIBSSH2_SESSION; 36 typedef struct _LIBSSH2_CHANNEL LIBSSH2_CHANNEL; 37 #endif 38 39 // Default values 40 #define DEFAULT_CASSANDRA_VERSION CassVersion("3.11.6") 41 #define DEFAULT_DSE_VERSION DseVersion("6.7.7") 42 #define DEFAULT_USE_GIT false 43 #define DEFAULT_USE_INSTALL_DIR false 44 #define DEFAULT_SERVER_TYPE ServerType(ServerType::CASSANDRA) 45 #define DEFAULT_USE_DSE false 46 #define DEFAULT_USE_DDAC false 47 #define DEFAULT_CLUSTER_PREFIX "cpp-driver" 48 #define DEFAULT_DSE_CREDENTIALS DseCredentialsType::USERNAME_PASSWORD 49 #define DEFAULT_DEPLOYMENT DeploymentType::LOCAL 50 #define DEFAULT_AUTHENTICATION AuthenticationType::USERNAME_PASSWORD 51 #define DEFAULT_HOST "127.0.0.1" 52 #define DEFAULT_REMOTE_DEPLOYMENT_PORT 22 53 #define DEFAULT_REMOTE_DEPLOYMENT_USERNAME "vagrant" 54 #define DEFAULT_REMOTE_DEPLOYMENT_PASSWORD "vagrant" 55 #define DEFAULT_IS_VERBOSE false 56 #define DEFAULT_JVM_ARGUMENTS std::vector<std::string>() 57 58 // Define the node limit for a cluster 59 #define CLUSTER_NODE_LIMIT 6 60 61 /** 62 * Node status information for a cluster 63 */ 64 struct ClusterStatus { 65 /** 66 * List of IPv4 addresses for `DECOMMISSIONED` nodes 67 */ 68 std::vector<std::string> nodes_decommissioned; 69 /** 70 * List of IPv4 addresses for `DOWN` or unavailable nodes 71 */ 72 std::vector<std::string> nodes_down; 73 /** 74 * List of IPv4 addresses for `uninitialized` nodes 75 */ 76 std::vector<std::string> nodes_uninitialized; 77 /** 78 * List of IPv4 addresses for `UP` or ready nodes 79 */ 80 std::vector<std::string> nodes_up; 81 /** 82 * Total number of nodes in the cluster 83 */ 84 unsigned int node_count; 85 86 /** 87 * Constructor 88 */ ClusterStatusClusterStatus89 ClusterStatus() 90 : node_count(0) {} 91 }; 92 93 namespace CCM { 94 /** 95 * Enumeration for a DSE workload 96 */ 97 enum DseWorkload { 98 /** 99 * Cassandra 100 */ 101 DSE_WORKLOAD_CASSANDRA = 0, 102 /** 103 * CFS - Cassandra file system (Hadoop Distributed File System (HDFS) 104 * replacement 105 */ 106 DSE_WORKLOAD_CFS, 107 /** 108 * DSEFS - DataStax Enterprise file system (Spark streaming and Write Ahead 109 * Logging (WAL)) 110 */ 111 DSE_WORKLOAD_DSEFS, 112 /** 113 * Graph 114 */ 115 DSE_WORKLOAD_GRAPH, 116 /** 117 * Hadoop 118 */ 119 DSE_WORKLOAD_HADOOP, 120 /** 121 * Solr 122 */ 123 DSE_WORKLOAD_SOLR, 124 /** 125 * Spark 126 */ 127 DSE_WORKLOAD_SPARK 128 }; 129 130 class Bridge { 131 public: 132 /** 133 * Default DSE workload to apply (Cassandra) 134 */ 135 static const std::vector<DseWorkload> DEFAULT_DSE_WORKLOAD; 136 137 /** 138 * Constructor 139 * 140 * @param cassandra_version Cassandra version to use 141 * (default: DEFAULT_CASSANDRA_VERSION) 142 * @param use_git True if version should be obtained from ASF/GitHub; false 143 * otherwise (default: DEFAULT_USE_GIT). Prepends 144 * `cassandra-` to version when creating cluster through CCM 145 * if using Cassandra; otherwise passes version information 146 * to CCM for git download of DSE. Set branch_tag to 147 * override default action. 148 * @param branch_tag Branch/Tag to use when use_git is enabled 149 * (default: Empty). This value is independent of the 150 * version specified. 151 * @param use_install_dir True if CCM should use a particular installation 152 * directory; false otherwise 153 * (default: DEAFAULT_USE_INSTALL_DIR) 154 * @param install_dir Installation directory to use when use_install_dir is 155 * enabled (default: Empty) 156 * @param server_type Server type CCM should create (default: CASSANDRA) 157 * @param dse_workload DSE workload to utilize 158 * (default: DEFAULT_DSE_WORKLOAD) 159 * @param cluster_prefix Prefix to use when creating a cluster name 160 * (default: DEFAULT_CLUSTER_PREFIX) 161 * @param dse_credentials_type Username|Password/INI file credentials 162 * (default: DEFAULT_DSE_CREDENTIALS) 163 * @param dse_username Username for DSE download authentication; empty if 164 * using INI file credentials (default: Empty) 165 * @param dse_password Password for DSE download authentication; empty if 166 * using INI file credentials (default: Empty) 167 * @param deployment_type Local|Remote deployment (execute command locally 168 * or remote (default: DEFAULT_DEPLOYMENT) 169 * @param authentication_type Username|Password/Public key authentication 170 * (default: DEFAULT_AUTHENTICATION) 171 * @param host Host/IP address for CCM cluster and/or SSH connection 172 * (default: DEFAULT_HOST) 173 * @param port TCP/IP port for SSH connection 174 * (default: DEFAULT_REMOTE_DEPLOYMENT_PORT) 175 * @param username Username for SSH authentication 176 * (default: DEFAULT_REMOTE_DEPLOYMENT_USERNAME) 177 * @param password Password for SSH authentication; Empty if using public 178 * key (default: DEFAULT_REMOTE_DEPLOYMENT_PASSWORD) 179 * @param public_key Public key for authentication; Empty if using username 180 * and password authentication (default: Empty) 181 * @param private_key Private key for authentication; Empty if using 182 * username and password authentication (default: Empty) 183 * @param is_verbose True if verbose output should be enabled; false 184 * otherwise (default: false) 185 * @throws BridgeException 186 */ 187 Bridge(CassVersion cassandra_version = DEFAULT_CASSANDRA_VERSION, bool use_git = DEFAULT_USE_GIT, 188 const std::string& branch_tag = "", bool use_install_dir = DEFAULT_USE_INSTALL_DIR, 189 const std::string& install_dir = "", ServerType server_type = DEFAULT_SERVER_TYPE, 190 std::vector<DseWorkload> dse_workload = DEFAULT_DSE_WORKLOAD, 191 const std::string& cluster_prefix = DEFAULT_CLUSTER_PREFIX, 192 DseCredentialsType dse_credentials_type = DEFAULT_DSE_CREDENTIALS, 193 const std::string& dse_username = "", const std::string& dse_password = "", 194 DeploymentType deployment_type = DEFAULT_DEPLOYMENT, 195 AuthenticationType authentication_type = DEFAULT_AUTHENTICATION, 196 const std::string& host = DEFAULT_HOST, short port = DEFAULT_REMOTE_DEPLOYMENT_PORT, 197 const std::string& username = DEFAULT_REMOTE_DEPLOYMENT_USERNAME, 198 const std::string& password = DEFAULT_REMOTE_DEPLOYMENT_PASSWORD, 199 const std::string& public_key = "", const std::string& private_key = "", 200 bool is_verbose = DEFAULT_IS_VERBOSE); 201 202 /** 203 * Destructor 204 */ 205 ~Bridge(); 206 207 /** 208 * Clear the data on the active cluster; as a side effect the cluster is 209 * also stopped 210 */ 211 void clear_cluster_data(); 212 213 /** 214 * Get a comma separated list of IPv4 addresses for nodes in the active 215 * Cassandra cluster 216 * 217 * @param is_all True if all node IPv4 addresses should be returned; false 218 * if only the `UP` nodes (default: true) 219 * @return Comma separated list of IPv4 addresses 220 */ 221 std::string cluster_contact_points(bool is_all = true); 222 223 /** 224 * Get the list of IPv4 addresses for node in the active Cassandra cluster 225 * 226 * @param is_all True if all node IPv4 addresses should be returned; false 227 * if only the `UP` nodes (default: true) 228 * @return Array/Vector of IPv4 addresses 229 */ 230 std::vector<std::string> cluster_ip_addresses(bool is_all = true); 231 232 /** 233 * Get the status for the active cluster 234 * 235 * @return Status of the nodes in the active cluster 236 */ 237 ClusterStatus cluster_status(); 238 239 /** 240 * Create a Cassandra cluster with nodes in multiple data centers 241 * 242 * @param data_center_nodes Vector of data center nodes 243 * @param with_vnodes True if vnodes tokens should be used; false otherwise 244 * (default: false) 245 * @param is_password_authenticator True if password authenticator is 246 * enabled; false otherwise 247 * (default: false) 248 * @param is_ssl True if SSL should be enabled; false otherwise 249 * (default: false) 250 * @param is_client_authentication True if client authentication should be 251 * enabled; false otherwise (default: false) 252 * @return True if cluster was created or switched; false otherwise 253 * @throws BridgeException 254 */ 255 bool create_cluster(std::vector<unsigned short> data_center_nodes, bool with_vnodes = false, 256 bool is_password_authenticator = false, bool is_ssl = false, 257 bool is_client_authentication = false); 258 259 /** 260 * Check to see if the active cluster is no longer accepting connections 261 * 262 * NOTE: This method may check the status of the nodes in the cluster 263 * multiple times 264 * 265 * @return True if cluster is no longer accepting connections; false 266 * otherwise 267 */ 268 bool is_cluster_down(); 269 270 /** 271 * Check to see if the active cluster is ready to accept connections 272 * 273 * NOTE: This method may check the status of the nodes in the cluster 274 * multiple times 275 * 276 * @return True if cluster is ready to accept connections; false otherwise 277 */ 278 bool is_cluster_up(); 279 280 /** 281 * "Hang up" the active Cassandra cluster (SIGHUP) 282 * 283 * @return True if cluster is down; false otherwise 284 */ 285 bool hang_up_cluster(); 286 287 /** 288 * Kill the active Cassandra cluster (SIGKILL) 289 * 290 * @return True if cluster is down; false otherwise 291 */ 292 bool kill_cluster(); 293 294 /** 295 * Remove active cluster 296 */ 297 void remove_cluster(); 298 299 /** 300 * Remove a cluster 301 * 302 * @param cluster_name Cluster name to remove 303 */ 304 void remove_cluster(const std::string& cluster_name); 305 306 /** 307 * Remove all the available clusters 308 * (default deletes generated bridge clusters) 309 * 310 * @param is_all If true all CCM clusters are removed; otherwise false to 311 * delete bridge generated clusters (default: false) 312 */ 313 void remove_all_clusters(bool is_all = false); 314 315 /** 316 * Start the active Cassandra cluster 317 * 318 * @param jvm_arguments Array/Vector of JVM arguments to apply during 319 * cluster start 320 * @return True if cluster is up; false otherwise 321 */ 322 bool start_cluster(std::vector<std::string> jvm_arguments); 323 324 /** 325 * Start the active Cassandra cluster 326 * 327 * @param jvm_argument JVM argument to apply during cluster start (optional) 328 * @return True if cluster is down; false otherwise 329 */ 330 bool start_cluster(std::string jvm_argument = ""); 331 332 /** 333 * Stop the active Cassandra cluster 334 * 335 * @param is_kill True if forced termination requested; false otherwise 336 * (default: false) 337 * @return True if cluster is down; false otherwise 338 */ 339 bool stop_cluster(bool is_kill = false); 340 341 /** 342 * Switch to another available cluster 343 * 344 * @param cluster_name Cluster name to switch to 345 * @return True if switched or is currently active cluster; false otherwise 346 */ 347 bool switch_cluster(const std::string& cluster_name); 348 349 /** 350 * Update the cluster configuration 351 * 352 * @param key_value_pairs Key:Value to update 353 * @param is_dse True if key/value pair should update the dse.yaml file; 354 * otherwise false (default: false; update cassandra.yaml) 355 * @param is_yaml True if key_value_pairs is a YAML string; otherwise false 356 * (default: false) 357 * NOTE: key_value_pairs in this instance must be a vector 358 * of strings for use with CCM literal YAML updates. 359 * These strings are single or multi-line YAML 360 * configurations; multi-line YAML must contain EOL 361 * marker at the end of each line (e.g. \n) 362 */ 363 void update_cluster_configuration(std::vector<std::string> key_value_pairs, bool is_dse = false, 364 bool is_yaml = false); 365 366 /** 367 * Update the cluster configuration 368 * 369 * @param key Key to update 370 * @param value Value to apply to key configuration 371 * @param is_dse True if key/value pair should update the dse.yaml file; 372 * otherwise false (default: false; update cassandra.yaml) 373 */ 374 void update_cluster_configuration(const std::string& key, const std::string& value, 375 bool is_dse = false); 376 377 /** 378 * Update the cluster configuration using a YAML configuration 379 * 380 * @param yaml YAML configuration to apply to the cluster 381 * NOTE: These strings are single or multi-line YAML 382 * configurations; multi-line YAML must contain EOL 383 * marker at the end of each line (e.g. \n) 384 * @param is_dse True if yaml configuration should update the dse.yaml file; 385 * otherwise false (default: false; update cassandra.yaml) 386 */ 387 void update_cluster_configuration_yaml(const std::string& yaml, bool is_dse = false); 388 389 /** 390 * Update the node configuration 391 * 392 * @param node Node to update configuration on 393 * @param key_value_pairs Key:Value to update 394 */ 395 void update_node_configuration(unsigned int node, std::vector<std::string> key_value_pairs); 396 397 /** 398 * Update the node configuration 399 * 400 * @param node Node to update configuration on 401 * @param key Key to update 402 * @param value Value to apply to key configuration 403 */ 404 void update_node_configuration(unsigned int node, const std::string& key, 405 const std::string& value); 406 407 /** 408 * Add a node on the active Cassandra cluster 409 * 410 * @param data_center If provided add the node to the data center; otherwise 411 * add node normally (default: no data center) 412 * @return Node added to cluster 413 * @throws BridgeException 414 */ 415 unsigned int add_node(const std::string& data_center = ""); 416 417 /** 418 * Bootstrap (add and start) a node on the active cluster 419 * 420 * @param jvm_arguments JVM arguments to apply during node start 421 * @param data_center If provided add the node to the data center; otherwise 422 * add node normally (default: no data center) 423 * @return Node added to cluster 424 * @throws BridgeException 425 */ 426 unsigned int bootstrap_node(const std::vector<std::string>& jvm_arguments, 427 const std::string& data_center = ""); 428 429 /** 430 * Bootstrap (add and start) a node on the active cluster 431 * 432 * @param jvm_argument JVM argument to apply during node start 433 * (default: no JVM argument) 434 * @param data_center If provided add the node to the data center; otherwise 435 * add node normally (default: no data center) 436 * @return Node added to cluster 437 * @throws BridgeException 438 */ 439 unsigned int bootstrap_node(const std::string& jvm_argument = "", 440 const std::string& data_center = ""); 441 442 /** 443 * Decommission a node on the active Cassandra cluster 444 * 445 * @param node Node to decommission 446 * @oaram is_force True if decommission should be forced; false otherwise 447 * (default: false) 448 * @return True if node was decommissioned; false otherwise 449 */ 450 bool decommission_node(unsigned int node, bool is_force = false); 451 452 /** 453 * Disable binary protocol for a node on the active Cassandra cluster 454 * 455 * @param node Node to disable binary protocol 456 */ 457 void disable_node_binary_protocol(unsigned int node); 458 459 /** 460 * Disable gossip for a node on the active Cassandra cluster 461 * 462 * @param node Node to disable gossip 463 */ 464 void disable_node_gossip(unsigned int node); 465 466 /** 467 * Disable trace for a node on the active Cassandra cluster 468 * 469 * @param node Node to disable tracing 470 */ 471 void disable_node_trace(unsigned int node); 472 473 /** 474 * Enable binary protocol for a node on the active Cassandra cluster 475 * 476 * @param node Node to enable binary protocol 477 */ 478 void enable_node_binary_protocol(unsigned int node); 479 480 /** 481 * Enable gossip for a node on the active Cassandra cluster 482 * 483 * @param node Node to enable gossip 484 */ 485 void enable_node_gossip(unsigned int node); 486 487 /** 488 * Enable trace for a node on the active Cassandra cluster 489 * 490 * @param node Node to enable tracing 491 */ 492 void enable_node_trace(unsigned int node); 493 494 /** 495 * Execute a CQL statement on a particular node 496 * 497 * @param node Node to execute CQL statement on 498 * @param cql CQL statement to execute 499 */ 500 void execute_cql_on_node(unsigned int node, const std::string& cql); 501 502 /** 503 * Determine if server type is Apache Cassandra 504 * 505 * @return True if Cassandra; false otherwise 506 */ is_cassandra()507 bool is_cassandra() { return server_type_ == ServerType::CASSANDRA; } 508 509 /** 510 * Determine if server type is DataStax Enterprise 511 * 512 * @return True if DSE; false otherwise 513 */ is_dse()514 bool is_dse() { return server_type_ == ServerType::DSE; } 515 516 /** 517 * Determine if server type is DataStax Distribution of Apache Cassandra 518 * 519 * @return True if DDAC; false otherwise 520 */ is_ddac()521 bool is_ddac() { return server_type_ == ServerType::DDAC; } 522 523 /** 524 * Force decommission of a node on the active Cassandra cluster 525 * 526 * NOTE: Alias for decommission_node(node, true) 527 * 528 * @param node Node to decommission 529 * @return True if node was decommissioned; false otherwise 530 */ 531 bool force_decommission_node(unsigned int node); 532 533 /** 534 * "Hang up" a node on the active Cassandra cluster (SIGHUP) 535 * 536 * @param node Node send SIGHUP signal to 537 * @return True if node is down; false otherwise 538 */ 539 bool hang_up_node(unsigned int node); 540 541 /** 542 * Kill a node on the active Cassandra cluster (SIGKILL) 543 * 544 * @param node Node to kill 545 * @return True if node is down; false otherwise 546 */ 547 bool kill_node(unsigned int node); 548 549 /** 550 * Pause a node on the active Cassandra cluster 551 * 552 * @param node Node to pause 553 */ 554 void pause_node(unsigned int node); 555 556 /** 557 * Resume a node on the active Cassandra cluster 558 * 559 * @param node Node to resume 560 */ 561 void resume_node(unsigned int node); 562 563 /** 564 * Start a node on the active Cassandra cluster 565 * 566 * @param node Node to start 567 * @param jvm_arguments Array/Vector of JVM arguments to apply during node 568 * start (default: DEFAULT_JVM_ARGUMENTS) 569 * @return True if node is up; false otherwise 570 */ 571 bool start_node(unsigned int node, 572 const std::vector<std::string>& jvm_arguments = DEFAULT_JVM_ARGUMENTS); 573 574 /** 575 * Start a node on the active Cassandra cluster with an additional JVM 576 * argument 577 * 578 * @param node Node to start 579 * @param jvm_argument JVM argument to apply during node start 580 * @return True if node is up; false otherwise 581 */ 582 bool start_node(unsigned int node, const std::string& jvm_argument); 583 584 /** 585 * Stop a node on the active Cassandra cluster 586 * 587 * @param node Node to stop 588 * @param is_kill True if forced termination requested; false otherwise 589 * (default: false) 590 * @return True if node is down; false otherwise 591 */ 592 bool stop_node(unsigned int node, bool is_kill = false); 593 594 /** 595 * Get the IP address prefix from the host IP address 596 * 597 * @return IP address prefix 598 */ 599 std::string get_ip_prefix(); 600 601 /** 602 * Get the Cassandra version from the active cluster 603 * 604 * @return Cassandra version 605 * @throws BridgeException 606 */ 607 CassVersion get_cassandra_version(); 608 609 /** 610 * Get the DSE version from the active cluster 611 * 612 * @return DSE version 613 * @throws BridgeException 614 */ 615 DseVersion get_dse_version(); 616 617 /** 618 * Set the DSE workload on a node 619 * 620 * NOTE: This operation should be performed before starting the node; 621 * otherwise the node will be stopped and restarted 622 * 623 * @param node Node to set DSE workload on 624 * @param workload Workload to be set 625 * @param is_kill True if forced termination requested; false otherwise 626 * (default: false) 627 * @return True if node was restarted; false otherwise 628 */ 629 bool set_dse_workload(unsigned int node, DseWorkload workload, bool is_kill = false); 630 631 /** 632 * Set the DSE workloads on a node 633 * 634 * NOTE: This operation should be performed before starting the node; 635 * otherwise the node will be stopped and restarted 636 * 637 * @param node Node to set DSE workload on 638 * @param workloads Workloads to be set 639 * @param is_kill True if forced termination requested; false otherwise 640 * (default: false) 641 * @return True if node was restarted; false otherwise 642 */ 643 bool set_dse_workloads(unsigned int node, std::vector<DseWorkload> workloads, 644 bool is_kill = false); 645 646 /** 647 * Set the DSE workload on the cluster 648 * 649 * NOTE: This operation should be performed before starting the cluster; 650 * otherwise the cluster will be stopped and restarted 651 * 652 * @param workload Workload to be set 653 * @param is_kill True if forced termination requested; false otherwise 654 * (default: false) 655 * @return True if cluster was restarted; false otherwise 656 */ 657 bool set_dse_workload(DseWorkload workload, bool is_kill = false); 658 659 /** 660 * Set the DSE workloads on the cluster 661 * 662 * NOTE: This operation should be performed before starting the cluster; 663 * otherwise the cluster will be stopped and restarted 664 * 665 * @param workloads Workloads to be set 666 * @param is_kill True if forced termination requested; false otherwise 667 * (default: false) 668 * @return True if cluster was restarted; false otherwise 669 */ 670 bool set_dse_workloads(std::vector<DseWorkload> workloads, bool is_kill = false); 671 672 /** 673 * Check to see if a node has been decommissioned 674 * 675 * @param node Node to check `DECOMMISSION` status 676 * @return True if node is decommissioned; false otherwise 677 */ 678 bool is_node_decommissioned(unsigned int node); 679 680 /** 681 * Check to see if a node will no longer accept connections 682 * 683 * NOTE: This method may check the status of the node multiple times 684 * 685 * @param node Node to check `DOWN` status 686 * @param is_quick_check True if `DOWN` status is checked once; false 687 * otherwise (default: false) 688 * @return True if node is no longer accepting connections; false otherwise 689 */ 690 bool is_node_down(unsigned int node, bool is_quick_check = false); 691 692 /** 693 * Check to see if a node is ready to accept connections 694 * 695 * NOTE: This method may check the status of the node multiple times 696 * 697 * @param node Node to check `UP` status 698 * @param is_quick_check True if `UP` status is checked once; false 699 * otherwise (default: false) 700 * @return True if node is ready to accept connections; false otherwise 701 */ 702 bool is_node_up(unsigned int node, bool is_quick_check = false); 703 704 private: 705 /** 706 * Cassandra version to use 707 */ 708 CassVersion cassandra_version_; 709 /** 710 * DSE version to use 711 */ 712 DseVersion dse_version_; 713 /** 714 * Flag to determine if Cassandra/DSE should be built from ASF/GitHub 715 */ 716 bool use_git_; 717 /** 718 * Branch/Tag to retrieve from ASF/GitHub 719 */ 720 std::string branch_tag_; 721 /** 722 * Flag to determine if installation directory should be used (passed to 723 * CCM) 724 */ 725 bool use_install_dir_; 726 /** 727 * Installation directory to pass to CCM 728 */ 729 std::string install_dir_; 730 /** 731 * Server type to use with CCM 732 */ 733 ServerType server_type_; 734 /** 735 * Workload to apply to the DSE cluster 736 * 737 * NOTE: Multiple workloads will be applied simultaneously via CCM 738 */ 739 std::vector<DseWorkload> dse_workload_; 740 /** 741 * Cluster prefix to apply to cluster name during create command 742 */ 743 std::string cluster_prefix_; 744 /** 745 * Authentication type (username|password/public key) 746 * 747 * Flag to indicate how SSH authentication should be established 748 */ 749 AuthenticationType authentication_type_; 750 /** 751 * DSE credentials type (username|password/INI file) 752 * 753 * Flag to indicate how DSE credentials should be obtained 754 */ 755 DseCredentialsType dse_credentials_type_; 756 /** 757 * Username to use when authenticating download access for DSE 758 */ 759 std::string dse_username_; 760 /** 761 * Password to use when authenticating download access for DSE 762 */ 763 std::string dse_password_; 764 /** 765 * Deployment type (local|ssh) 766 * 767 * Flag to indicate how CCM commands should be executed 768 */ 769 DeploymentType deployment_type_; 770 /** 771 * IP address to use when establishing SSH connection for remote CCM 772 * command execution and/or IP address to use for server connection IP 773 * generation 774 */ 775 std::string host_; 776 #ifdef CASS_USE_LIBSSH2 777 /** 778 * SSH session handle for establishing connection 779 */ 780 LIBSSH2_SESSION* session_; 781 /** 782 * SSH channel handle for interacting with the session 783 */ 784 LIBSSH2_CHANNEL* channel_; 785 /** 786 * Socket instance 787 */ 788 Socket* socket_; 789 #endif 790 /** 791 * Workload values to use when setting the workload via CCM 792 */ 793 static const std::vector<std::string> dse_workloads_; 794 /** 795 * Flag to determine if verbose output is enabled 796 */ 797 bool is_verbose_; 798 799 #ifdef CASS_USE_LIBSSH2 800 /** 801 * Initialize the socket 802 * 803 * @param host Host/IP address for SSH connection 804 * @param port TCP/IP port for SSH connection 805 * @throws SocketException 806 */ 807 void initialize_socket(const std::string& host, short port); 808 809 /** 810 * Synchronize the socket based on the direction of the libssh2 session 811 * 812 * @throws BridgeException 813 * @throws SocketException 814 */ 815 void synchronize_socket(); 816 817 /** 818 * Initialize the libssh2 connection 819 * 820 * @throws BridgeException 821 */ 822 void initialize_libssh2(); 823 824 /** 825 * Establish connection via libssh2 826 * 827 * @param authentication_type Username|Password/Public key authentication 828 * @param username Username for SSH authentication 829 * @param password Password for SSH authentication; NULL if using public 830 * key 831 * @param public_key Public key for authentication; Empty if using username 832 * and password authentication 833 * @param private_key Private key for authentication; Empty if using 834 * username and password authentication 835 * @throws BridgeException 836 */ 837 void establish_libssh2_connection(AuthenticationType authentication_type, 838 const std::string& username, const std::string& password, 839 const std::string& public_key, const std::string& private_key); 840 841 /** 842 * Create/Open the libssh2 terminal 843 * 844 * @throws BridgeException 845 */ 846 void open_libssh2_terminal(); 847 848 /** 849 * Terminate/Close the libssh2 terminal 850 * 851 * @throws BridgeException 852 */ 853 void close_libssh2_terminal(); 854 855 /** 856 * Execute a remote command on the libssh2 connection 857 * 858 * @param command Command array to execute ([0] = command, [1-n] arguments) 859 * @return Output from executed command 860 */ 861 std::string execute_libssh2_command(const std::vector<std::string>& command); 862 #endif 863 864 #ifdef CASS_USE_LIBSSH2 865 /** 866 * Read the output (stdout and stderr) from the libssh2 terminal 867 * 868 * @return Output from the terminal (may not be in order) 869 */ 870 std::string read_libssh2_terminal(); 871 872 /** 873 * Finalize the libssh2 library usage and socket used by libssh2 874 */ 875 void finalize_libssh2(); 876 #endif 877 878 /** 879 * Execute the CCM command 880 * 881 * @param command Command array to execute ([0] = CCM command, 882 * [1-n] arguments) 883 * @return Output from executing CCM command 884 */ 885 std::string execute_ccm_command(const std::vector<std::string>& command); 886 887 /** 888 * Get the active Cassandra cluster 889 * 890 * @return Currently active Cassandra cluster 891 */ 892 std::string get_active_cluster(); 893 894 /** 895 * Get the list of available Cassandra clusters 896 * 897 * @return Array/Vector of available Cassandra clusters 898 */ 899 std::vector<std::string> get_available_clusters(); 900 901 /** 902 * Get the list of available Cassandra clusters 903 * 904 * @param [out] active_cluster Current active cluster in the list 905 * @return Array/Vector of available Cassandra clusters 906 */ 907 std::vector<std::string> get_available_clusters(std::string& active_cluster); 908 909 /** 910 * Generate the name of the Cassandra cluster based on the number of nodes 911 * in each data center 912 * 913 * @param cassandra_version Cassandra version being used 914 * @param data_center_nodes Vector of nodes for each data center 915 * @param with_vnodes True if vnodes are enabled; false otherwise 916 * @param is_password_authenticator True if password authenticator is 917 * enabled; false otherwise 918 * @param is_ssl True if SSL is enabled; false otherwise 919 * @param is_client_authentication True if client authentication is enabled; 920 * false otherwise 921 * @return Cluster name 922 */ 923 std::string generate_cluster_name(CassVersion cassandra_version, 924 std::vector<unsigned short> data_center_nodes, bool with_vnodes, 925 bool is_password_authenticator, bool is_ssl, 926 bool is_client_authentication); 927 928 /** 929 * Generate the nodes parameter for theCassandra cluster based on the number 930 * of nodes in each data center 931 * 932 * @param data_center_nodes Vector of nodes for each data center 933 * @param separator Separator to use between cluster nodes 934 * @return String of nodes separated by separator 935 */ 936 std::string generate_cluster_nodes(std::vector<unsigned short> data_center_nodes, 937 char separator = ':'); 938 939 /** 940 * Generate the CCM update configuration command based on the Cassandra 941 * version requested 942 * 943 * @param cassandra_version Cassandra version to use 944 * @return Array/Vector containing the updateconf command 945 */ 946 std::vector<std::string> generate_create_updateconf_command(CassVersion cassandra_version); 947 948 /** 949 * Generate the command separated list for have a single or multiple 950 * workloads for the CCM setworkload command 951 * 952 * @param workloads Workloads to be set 953 * @return String representing the workloads for the setworkload command 954 */ 955 std::string generate_dse_workloads(std::vector<DseWorkload> workloads); 956 957 /** 958 * Get the next available node 959 * 960 * @return Next available node 961 * @throws BridgeException 962 * @see CLUSTER_NODE_LIMIT 963 */ 964 unsigned int get_next_available_node(); 965 966 /** 967 * Generate the node name based on the node requested 968 * 969 * @param node Node to use 970 * @return Name of the node for CCM node commands 971 */ 972 std::string generate_node_name(unsigned int node); 973 974 /** 975 * Determine if a node is available 976 * 977 * @param node Cassandra node to check 978 * @return True if node is available; false otherwise 979 */ 980 bool is_node_availabe(unsigned int node); 981 982 /** 983 * Determine if a node is available 984 * 985 * @param ip_address IPv4 address of the Cassandra node 986 * @return True if node is available; false otherwise 987 */ 988 bool is_node_availabe(const std::string& ip_address); 989 990 /** 991 * Convert a string to lowercase 992 * 993 * @param input String to convert to lowercase 994 * 995 * TODO: Remove static declaration after deprecations are removed 996 */ 997 static std::string to_lower(const std::string& input); 998 999 /** 1000 * Remove the leading and trailing whitespace from a string 1001 * 1002 * @param input String to trim 1003 * @return Trimmed string 1004 * 1005 * TODO: Remove static declaration after deprecations are removed 1006 */ 1007 static std::string trim(const std::string& input); 1008 1009 /** 1010 * Concatenate an array/vector into a string 1011 * 1012 * @param elements Array/Vector elements to concatenate 1013 * @param delimiter Character to use between elements (default: <space>) 1014 * @return A string representation of all the array/vector elements 1015 */ 1016 std::string implode(const std::vector<std::string>& elements, const char delimiter = ' '); 1017 1018 /** 1019 * Split a string into an array/vector 1020 * 1021 * @param input String to convert to array/vector 1022 * @param delimiter Character to use split into elements (default: <space>) 1023 * @return An array/vector representation of the string 1024 * 1025 * TODO: Remove static declaration after deprecations are removed 1026 */ 1027 static std::vector<std::string> explode(const std::string& input, const char delimiter = ' '); 1028 1029 /** 1030 * Cross platform millisecond granularity sleep 1031 * 1032 * @param milliseconds Time in milliseconds to sleep 1033 */ 1034 void msleep(unsigned int milliseconds); 1035 }; 1036 } // namespace CCM 1037 1038 #endif // __CCM_BRIDGE_HPP__ 1039