@@ -601,6 +601,23 @@ private function getFieldsFromInput(array $vars, $package)
601601 'template ' => $ osid ,
602602 'title ' => isset ($ vars ['upcloudvps_hostname ' ]) ? strtolower ($ vars ['upcloudvps_hostname ' ]) : null
603603 ];
604+
605+ // Add SSH keys if provided
606+ if (!empty ($ vars ['upcloudvps_ssh_keys ' ])) {
607+ $ ssh_keys = [];
608+ // Handle both single key and multiple keys (comma-separated or array)
609+ if (is_array ($ vars ['upcloudvps_ssh_keys ' ])) {
610+ $ ssh_keys = array_filter (array_map ('trim ' , $ vars ['upcloudvps_ssh_keys ' ]));
611+ } else {
612+ // Split and clean up
613+ $ keys = preg_split ('/[,\r\n]+/ ' , $ vars ['upcloudvps_ssh_keys ' ], -1 , PREG_SPLIT_NO_EMPTY );
614+ $ ssh_keys = array_filter (array_map ('trim ' , $ keys ));
615+ }
616+ if (!empty ($ ssh_keys )) {
617+ $ fields ['ssh_keys ' ] = $ ssh_keys ;
618+ }
619+ }
620+
604621 return $ fields ;
605622 }
606623
@@ -652,6 +669,22 @@ private function getServiceRules(array $vars = null, $package = null, $edit = fa
652669 'rule ' => [[$ this , 'validateTemplate ' ]],
653670 'message ' => Language::_ ('Upcloudvps.!error.upcloudvps_template.valid ' , true )
654671 ]
672+ ],
673+ 'upcloudvps_ssh_keys ' => [
674+ 'required ' => [
675+ 'if_set ' => $ edit ,
676+ 'rule ' => [
677+ [$ this , 'validateSshKeysRequired ' ],
678+ $ package ,
679+ $ vars ['upcloudvps_template ' ] ?? null ,
680+ ],
681+ 'message ' => Language::_ ('Upcloudvps.!error.upcloudvps_ssh_keys.required ' , true )
682+ ],
683+ 'valid ' => [
684+ 'if_set ' => $ edit ,
685+ 'rule ' => [[$ this , 'validateSshKeys ' ]],
686+ 'message ' => Language::_ ('Upcloudvps.!error.upcloudvps_ssh_keys.valid ' , true )
687+ ]
655688 ]
656689 ];
657690
@@ -706,6 +739,54 @@ public function validateTemplate($template)
706739 return array_key_exists (trim ($ template ), $ valid_templates );
707740 }
708741
742+ /**
743+ * Validates SSH keys' requiredness with the given package and template.
744+ *
745+ * @param string $ssh_keys The SSH keys set
746+ * @param stdClass $package The package to validate with
747+ * @param string $template_uuid The template UUID to validate with (ignored if admin-set)
748+ */
749+ public function validateSshKeysRequired ($ ssh_keys , $ package , $ template_uuid )
750+ {
751+ if (!empty ($ ssh_keys )) {
752+ return true ;
753+ }
754+
755+ $ module_row = null ;
756+ $ rows = $ this ->getModuleRows ();
757+ if (isset ($ rows [0 ])) {
758+ $ module_row = $ rows [0 ];
759+ }
760+ unset($ rows );
761+
762+ $ api = $ this ->getApi ($ module_row ->meta ->api_token , $ module_row ->meta ->api_base_url );
763+ if ($ package ->meta ->set_template !== 'client ' ) {
764+ $ template_uuid = $ package ->meta ->template ;
765+ }
766+ $ template = $ api ->getStorage ($ template_uuid )['response ' ]['storage ' ];
767+
768+ if ($ template ['type ' ] == 'template ' && $ template ['template_type ' ] == 'cloud-init ' ) {
769+ return false ;
770+ }
771+ return true ;
772+ }
773+
774+ /**
775+ * Validates SSH public keys.
776+ *
777+ * @param string $ssh_keys The SSH public keys to validate
778+ * @return bool True if the SSH key is valid, false otherwise
779+ */
780+ public function validateSshKeys ($ ssh_keys )
781+ {
782+ foreach (preg_split ('/[,\r\n]+/ ' , $ ssh_keys , -1 , PREG_SPLIT_NO_EMPTY ) as $ ssh_key ) {
783+ if (!preg_match ('/^(ssh-(rsa|dss|ed25519)|ecdsa-sha2-nistp(256|384|521)|sk-(ssh-ed25519|ecdsa-sha2-nistp256)@openssh\.com) AAAA[0-9A-Za-z+\/]+={0,3}( .*)?$/ ' , $ ssh_key )) {
784+ return false ;
785+ }
786+ }
787+ return true ;
788+ }
789+
709790
710791 /**
711792 * Adds a new service. Creates the server via the API if 'use_module' is true.
@@ -780,6 +861,11 @@ public function addService($package, array $vars = null, $parent_package = null,
780861 'value ' => $ vars ['upcloudvps_location ' ] ?? null ,
781862 'encrypted ' => 0
782863 ],
864+ [
865+ 'key ' => 'upcloudvps_ssh_keys ' ,
866+ 'value ' => $ vars ['upcloudvps_ssh_keys ' ] ?? null ,
867+ 'encrypted ' => 0
868+ ],
783869 [
784870 'key ' => 'upcloudvps_password ' ,
785871 'value ' => $ server ['response ' ]['server ' ]['password ' ] ?? ($ server ['response ' ]['server ' ]['password ' ] ?? null ),
@@ -865,6 +951,7 @@ public function editService($package, $service, array $vars = null, $parent_pack
865951 $ fields = [
866952 'upcloudvps_vmid ' ,
867953 'upcloudvps_template ' ,
954+ 'upcloudvps_ssh_keys ' ,
868955 ];
869956 foreach ($ fields as $ field ) {
870957 if (property_exists ($ service_fields , $ field ) && isset ($ vars [$ field ])) {
@@ -944,6 +1031,19 @@ public function getAdminAddFields($package, $vars = null)
9441031 $ fields ->setField ($ template );
9451032 }
9461033
1034+ // Add SSH keys field
1035+ $ ssh_keys = $ fields ->label (Language::_ ('Upcloudvps.service_field.ssh_keys ' , true ), 'upcloudvps_ssh_keys ' );
1036+ $ ssh_keys ->attach (
1037+ $ fields ->fieldTextarea (
1038+ 'upcloudvps_ssh_keys ' ,
1039+ $ vars ->upcloudvps_ssh_keys ?? null ,
1040+ ['id ' => 'upcloudvps_ssh_keys ' , 'rows ' => 4 , 'placeholder ' => 'ssh-rsa AAAAB3NzaC1yc2E... ' ]
1041+ )
1042+ );
1043+ $ ssh_keys_tooltip = $ fields ->tooltip (Language::_ ('Upcloudvps.service_field.tooltip.ssh_keys ' , true ));
1044+ $ ssh_keys ->attach ($ ssh_keys_tooltip );
1045+ $ fields ->setField ($ ssh_keys );
1046+
9471047 return $ fields ;
9481048 }
9491049
@@ -988,6 +1088,19 @@ public function getAdminEditFields($package, $vars = null)
9881088 $ fields ->setField ($ template );
9891089 }
9901090
1091+ // Add SSH keys field
1092+ $ ssh_keys = $ fields ->label (Language::_ ('Upcloudvps.service_field.ssh_keys ' , true ), 'upcloudvps_ssh_keys ' );
1093+ $ ssh_keys ->attach (
1094+ $ fields ->fieldTextarea (
1095+ 'upcloudvps_ssh_keys ' ,
1096+ $ vars ->upcloudvps_ssh_keys ?? null ,
1097+ ['id ' => 'upcloudvps_ssh_keys ' , 'rows ' => 4 , 'placeholder ' => 'ssh-rsa AAAAB3NzaC1yc2E... ' ]
1098+ )
1099+ );
1100+ $ ssh_keys_tooltip = $ fields ->tooltip (Language::_ ('Upcloudvps.service_field.tooltip.ssh_keys ' , true ));
1101+ $ ssh_keys ->attach ($ ssh_keys_tooltip );
1102+ $ fields ->setField ($ ssh_keys );
1103+
9911104 return $ fields ;
9921105 }
9931106
@@ -1043,6 +1156,19 @@ public function getClientAddFields($package, $vars = null)
10431156 $ fields ->setField ($ template );
10441157 }
10451158
1159+ // Add SSH keys field
1160+ $ ssh_keys = $ fields ->label (Language::_ ('Upcloudvps.service_field.ssh_keys ' , true ), 'upcloudvps_ssh_keys ' );
1161+ $ ssh_keys ->attach (
1162+ $ fields ->fieldTextarea (
1163+ 'upcloudvps_ssh_keys ' ,
1164+ $ vars ->upcloudvps_ssh_keys ?? null ,
1165+ ['id ' => 'upcloudvps_ssh_keys ' , 'rows ' => 4 , 'placeholder ' => 'ssh-rsa AAAAB3NzaC1yc2E... ' ]
1166+ )
1167+ );
1168+ $ ssh_keys_tooltip = $ fields ->tooltip (Language::_ ('Upcloudvps.service_field.tooltip.ssh_keys ' , true ));
1169+ $ ssh_keys ->attach ($ ssh_keys_tooltip );
1170+ $ fields ->setField ($ ssh_keys );
1171+
10461172 return $ fields ;
10471173 }
10481174
0 commit comments