Skip to content

Commit 9de3bf3

Browse files
committed
feat: --password flag on droplet create and campaign deploy
1 parent 612439f commit 9de3bf3

2 files changed

Lines changed: 34 additions & 0 deletions

File tree

cmd/campaign.go

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,7 @@ var (
115115
campOperatorIP string
116116
campVPCAuto bool
117117
campTemplateVar []string
118+
campPassword string
118119
)
119120

120121
func init() {
@@ -136,6 +137,7 @@ func init() {
136137
campaignDeployCmd.Flags().StringVar(&campOperatorIP, "operator-ip", "", "Operator IP used by firewall presets to restrict SSH (required when using --role with a preset)")
137138
campaignDeployCmd.Flags().BoolVar(&campVPCAuto, "vpc-auto", false, "Automatically create a VPC in the campaign region and attach all Droplets")
138139
campaignDeployCmd.Flags().StringArrayVar(&campTemplateVar, "template-var", nil, "Template variable: KEY=VALUE (repeatable, applies to all --template or role template=)")
140+
campaignDeployCmd.Flags().StringVar(&campPassword, "password", "", "Set root password via cloud-init on all Droplets (injected into any template or user-data)")
139141
campaignDeployCmd.MarkFlagRequired("name") //nolint:errcheck
140142

141143
// status & destroy
@@ -269,6 +271,9 @@ func runCampaignDeploySimple() error {
269271
if err != nil {
270272
return err
271273
}
274+
if campPassword != "" {
275+
ud = injectPassword(ud, campPassword)
276+
}
272277

273278
dropSvc, fwSvc, ripSvc, err := newCampaignClients()
274279
if err != nil {
@@ -499,6 +504,9 @@ func runCampaignDeployRoles() error {
499504
return err
500505
}
501506
}
507+
if campPassword != "" {
508+
ud = injectPassword(ud, campPassword)
509+
}
502510

503511
step(fmt.Sprintf("[%s] Creating %d Droplet(s) image=%s size=%s",
504512
color.CyanString(role.Name), role.Count, image, size))

cmd/droplet.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ var (
190190
sshPort int
191191
createTemplate string
192192
createTemplateVar []string
193+
createPassword string
193194
)
194195

195196
func init() {
@@ -209,6 +210,7 @@ func init() {
209210
dropletCreateCmd.Flags().BoolVar(&createBackups, "backups", false, "Enable automatic backups")
210211
dropletCreateCmd.Flags().BoolVarP(&createWait, "wait", "w", false, "Wait until the Droplet is active and print its IP")
211212
dropletCreateCmd.Flags().IntVarP(&createCount, "count", "c", 1, "Number of Droplets to provision in parallel (names become name-01, name-02, ...)")
213+
dropletCreateCmd.Flags().StringVar(&createPassword, "password", "", "Set root password via cloud-init (injected into any --template or --user-data-file)")
212214
dropletCreateCmd.MarkFlagRequired("name") //nolint:errcheck
213215

214216
// delete flags
@@ -457,6 +459,27 @@ func runDropletGet(cmd *cobra.Command, args []string) error {
457459
return nil
458460
}
459461

462+
// injectPassword inserts root password setup lines into a cloud-init script
463+
// right after the shebang, composing cleanly with any existing script content.
464+
func injectPassword(script, password string) string {
465+
block := fmt.Sprintf(
466+
"echo %q | chpasswd\n"+
467+
"sed -i 's/^#*PermitRootLogin.*/PermitRootLogin yes/' /etc/ssh/sshd_config\n"+
468+
"sed -i 's/^#*PasswordAuthentication.*/PasswordAuthentication yes/' /etc/ssh/sshd_config\n"+
469+
"systemctl restart ssh\n",
470+
"root:"+password,
471+
)
472+
if script == "" {
473+
return "#!/bin/bash\n" + block
474+
}
475+
if strings.HasPrefix(script, "#!") {
476+
if idx := strings.Index(script, "\n"); idx >= 0 {
477+
return script[:idx+1] + block + script[idx+1:]
478+
}
479+
}
480+
return block + script
481+
}
482+
460483
func runDropletCreate(cmd *cobra.Command, args []string) error {
461484
if createCount < 1 {
462485
return fmt.Errorf("--count must be >= 1")
@@ -466,6 +489,9 @@ func runDropletCreate(cmd *cobra.Command, args []string) error {
466489
if err != nil {
467490
return err
468491
}
492+
if createPassword != "" {
493+
ud = injectPassword(ud, createPassword)
494+
}
469495

470496
svc, err := newDropletService()
471497
if err != nil {

0 commit comments

Comments
 (0)