Documentation
¶
Index ¶
Constants ¶
View Source
const ChangeDeprecatedServerTypeMessage = (`Existing servers of that plan will ` +
`continue to work as before and no action is required on your part. ` +
`It is possible to migrate this Server to another Server Type by using ` +
`the "hcloud server change-type" command.`)
Variables ¶
View Source
var AddToPlacementGroupCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { cmd := &cobra.Command{ Use: "add-to-placement-group --placement-group <placement-group> <server>", Short: "Add a Server to a Placement Group", ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), } cmd.Flags().StringP("placement-group", "g", "", "Placement Group (ID or name) (required)") _ = cmd.RegisterFlagCompletionFunc("placement-group", cmpl.SuggestCandidatesF(client.PlacementGroup().Names)) _ = cmd.MarkFlagRequired(("placement-group")) return cmd }, Run: func(s state.State, cmd *cobra.Command, args []string) error { idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found %s", idOrName) } placementGroupIDOrName, _ := cmd.Flags().GetString("placement-group") placementGroup, _, err := s.Client().PlacementGroup().Get(s, placementGroupIDOrName) if err != nil { return err } if placementGroup == nil { return fmt.Errorf("Placement Group not found: %s", placementGroupIDOrName) } action, _, err := s.Client().Server().AddToPlacementGroup(s, server, placementGroup) if err != nil { return err } if err := s.WaitForActions(s, cmd, action); err != nil { return err } cmd.Printf("Server %d added to Placement Group %s\n", server.ID, placementGroupIDOrName) return nil }, }
View Source
var AttachISOCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { return &cobra.Command{ Use: "attach-iso <server> <iso>", Short: "Attach an ISO to a server", TraverseChildren: true, ValidArgsFunction: cmpl.SuggestArgs( cmpl.SuggestCandidatesF(client.Server().Names), cmpl.SuggestCandidatesF(client.ISO().Names), ), DisableFlagsInUseLine: true, } }, Run: func(s state.State, cmd *cobra.Command, args []string) error { idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } isoIDOrName := args[1] iso, _, err := s.Client().ISO().Get(s, isoIDOrName) if err != nil { return err } if iso == nil { return fmt.Errorf("ISO not found: %s", isoIDOrName) } if iso.Architecture != nil && *iso.Architecture != server.ServerType.Architecture { return errors.New("failed to attach ISO: ISO has a different architecture than the server") } action, _, err := s.Client().Server().AttachISO(s, server, iso) if err != nil { return err } if err := s.WaitForActions(s, cmd, action); err != nil { return err } cmd.Printf("ISO %s attached to Server %d\n", iso.Name, server.ID) return nil }, }
View Source
var AttachToNetworkCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { cmd := &cobra.Command{ Use: "attach-to-network [options] --network <network> <server>", Short: "Attach a Server to a Network", ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), TraverseChildren: true, DisableFlagsInUseLine: true, } cmd.Flags().StringP("network", "n", "", "Network (ID or name) (required)") _ = cmd.RegisterFlagCompletionFunc("network", cmpl.SuggestCandidatesF(client.Network().Names)) _ = cmd.MarkFlagRequired("network") cmd.Flags().IP("ip", nil, "IP address to assign to the Server (auto-assigned if omitted)") cmd.Flags().IPNet("ip-range", net.IPNet{}, "IP range in CIDR block notation of the subnet to attach to (auto-assigned if omitted)") cmd.Flags().IPSlice("alias-ips", []net.IP{}, "Additional IP addresses to be assigned to the Server") return cmd }, Run: func(s state.State, cmd *cobra.Command, args []string) error { idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } networkIDOrName, _ := cmd.Flags().GetString("network") network, _, err := s.Client().Network().Get(s, networkIDOrName) if err != nil { return err } if network == nil { return fmt.Errorf("Network not found: %s", networkIDOrName) } ip, _ := cmd.Flags().GetIP("ip") ipRange, _ := cmd.Flags().GetIPNet("ip-range") aliasIPs, _ := cmd.Flags().GetIPSlice("alias-ips") opts := hcloud.ServerAttachToNetworkOpts{ Network: network, IP: ip, } opts.AliasIPs = append(opts.AliasIPs, aliasIPs...) if cmd.Flags().Changed("ip-range") { opts.IPRange = &ipRange } action, _, err := s.Client().Server().AttachToNetwork(s, server, opts) if err != nil { return err } if err := s.WaitForActions(s, cmd, action); err != nil { return err } cmd.Printf("Server %d attached to Network %d\n", server.ID, network.ID) return nil }, }
View Source
var ChangeAliasIPsCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { cmd := &cobra.Command{ Use: "change-alias-ips [options] --network <network> <server>", Short: "Change a server's alias IPs in a Network", ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), TraverseChildren: true, DisableFlagsInUseLine: true, } cmd.Flags().StringP("network", "n", "", "Network (ID or name) (required)") _ = cmd.RegisterFlagCompletionFunc("network", cmpl.SuggestCandidatesF(client.Network().Names)) _ = cmd.MarkFlagRequired("network") cmd.Flags().StringSlice("alias-ips", nil, "New alias IPs") cmd.Flags().Bool("clear", false, "Remove all alias IPs") return cmd }, Run: func(s state.State, cmd *cobra.Command, args []string) error { clearAll, _ := cmd.Flags().GetBool("clear") idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } networkIDOrName, _ := cmd.Flags().GetString("network") network, _, err := s.Client().Network().Get(s, networkIDOrName) if err != nil { return err } if network == nil { return fmt.Errorf("Network not found: %s", networkIDOrName) } aliasIPs, _ := cmd.Flags().GetStringSlice("alias-ips") opts := hcloud.ServerChangeAliasIPsOpts{ Network: network, } if clearAll { opts.AliasIPs = []net.IP{} } else { for _, aliasIP := range aliasIPs { opts.AliasIPs = append(opts.AliasIPs, net.ParseIP(aliasIP)) } } action, _, err := s.Client().Server().ChangeAliasIPs(s, server, opts) if err != nil { return err } if err := s.WaitForActions(s, cmd, action); err != nil { return err } cmd.Printf("Alias IPs changed for Server %d in Network %d\n", server.ID, network.ID) return nil }, }
View Source
var ChangeProtectionCmds = base.ChangeProtectionCmds[*hcloud.Server, hcloud.ServerChangeProtectionOpts]{ ResourceNameSingular: "Server", NameSuggestions: func(client hcapi2.Client) func() []string { return client.Server().Names }, ProtectionLevels: map[string]func(opts *hcloud.ServerChangeProtectionOpts, value bool){ "delete": func(opts *hcloud.ServerChangeProtectionOpts, value bool) { opts.Delete = &value }, "rebuild": func(opts *hcloud.ServerChangeProtectionOpts, value bool) { opts.Rebuild = &value }, }, Fetch: func(s state.State, _ *cobra.Command, idOrName string) (*hcloud.Server, *hcloud.Response, error) { return s.Client().Server().Get(s, idOrName) }, ChangeProtectionFunction: func(s state.State, server *hcloud.Server, opts hcloud.ServerChangeProtectionOpts) (*hcloud.Action, *hcloud.Response, error) { return s.Client().Server().ChangeProtection(s, server, opts) }, IDOrName: func(server *hcloud.Server) string { return fmt.Sprint(server.ID) }, }
View Source
var ChangeTypeCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { cmd := &cobra.Command{ Use: "change-type [--keep-disk] <server> <server-type>", Short: "Change type of a server", ValidArgsFunction: cmpl.SuggestArgs( cmpl.SuggestCandidatesF(client.Server().Names), cmpl.SuggestCandidatesF(client.ServerType().Names), ), TraverseChildren: true, DisableFlagsInUseLine: true, } cmd.Flags().Bool("keep-disk", false, "Keep disk size of current Server Type. This enables downgrading the server. (true, false)") return cmd }, Run: func(s state.State, cmd *cobra.Command, args []string) error { idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } serverTypeIDOrName := args[1] serverType, _, err := s.Client().ServerType().Get(s, serverTypeIDOrName) if err != nil { return err } if serverType == nil { return fmt.Errorf("Server Type not found: %s", serverTypeIDOrName) } cmd.Print(deprecatedServerTypeWarning(serverType, server.Location.Name)) keepDisk, _ := cmd.Flags().GetBool("keep-disk") opts := hcloud.ServerChangeTypeOpts{ ServerType: serverType, UpgradeDisk: !keepDisk, } action, _, err := s.Client().Server().ChangeType(s, server, opts) if err != nil { return err } if err := s.WaitForActions(s, cmd, action); err != nil { return err } if opts.UpgradeDisk { cmd.Printf("Server %d changed to type %s\n", server.ID, serverType.Name) } else { cmd.Printf("Server %d changed to type %s (disk size was unchanged)\n", server.ID, serverType.Name) } return nil }, }
View Source
var CreateCmd = base.CreateCmd[*createResult]{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { cmd := &cobra.Command{ Use: "create [options] --name <name> --type <server-type> --image <image>", Short: "Create a Server", Long: `Create a Server. The --datacenter flag is deprecated. Use --location instead. See https://docs.hetzner.cloud/changelog#2025-12-16-phasing-out-datacenters.`, } cmd.Flags().String("name", "", "Server name (required)") _ = cmd.MarkFlagRequired("name") cmd.Flags().String("type", "", "Server Type (ID or name) (required)") _ = cmd.RegisterFlagCompletionFunc("type", cmpl.SuggestCandidatesF(client.ServerType().Names)) _ = cmd.MarkFlagRequired("type") cmd.Flags().String("image", "", "Image (ID or name) (required)") _ = cmd.RegisterFlagCompletionFunc("image", cmpl.SuggestCandidatesF(client.Image().Names)) _ = cmd.MarkFlagRequired("image") cmd.Flags().String("location", "", "Location (ID or name)") _ = cmd.RegisterFlagCompletionFunc("location", cmpl.SuggestCandidatesF(client.Location().Names)) cmd.Flags().String("datacenter", "", "Datacenter (ID or name) (deprecated)") _ = cmd.RegisterFlagCompletionFunc("datacenter", cmpl.SuggestCandidatesF(client.Datacenter().Names)) cmd.Flags().StringSlice("ssh-key", nil, "ID or name of SSH Key to inject (can be specified multiple times)") _ = cmd.RegisterFlagCompletionFunc("ssh-key", cmpl.SuggestCandidatesF(client.SSHKey().Names)) cmd.Flags().StringToString("label", nil, "User-defined labels ('key=value') (can be specified multiple times)") cmd.Flags().StringArray("user-data-from-file", []string{}, "Read user data from specified file (use - to read from stdin)") cmd.Flags().Bool("start-after-create", true, "Start Server right after creation (true, false)") cmd.Flags().StringSlice("volume", nil, "ID or name of Volume to attach (can be specified multiple times)") _ = cmd.RegisterFlagCompletionFunc("volume", cmpl.SuggestCandidatesF(client.Volume().Names)) cmd.Flags().StringSlice("network", nil, "ID or name of Network to attach the Server to (can be specified multiple times)") _ = cmd.RegisterFlagCompletionFunc("network", cmpl.SuggestCandidatesF(client.Network().Names)) cmd.Flags().StringSlice("firewall", nil, "ID or name of Firewall to attach the Server to (can be specified multiple times)") _ = cmd.RegisterFlagCompletionFunc("firewall", cmpl.SuggestCandidatesF(client.Firewall().Names)) cmd.Flags().Bool("automount", false, "Automount Volumes after attach (default: false) (true, false)") cmd.Flags().Bool("allow-deprecated-image", false, "Enable the use of deprecated Images (default: false) (true, false)") cmd.Flags().String("placement-group", "", "Placement Group (ID of name)") _ = cmd.RegisterFlagCompletionFunc("placement-group", cmpl.SuggestCandidatesF(client.PlacementGroup().Names)) cmd.Flags().String("primary-ipv4", "", "Primary IPv4 (ID of name)") _ = cmd.RegisterFlagCompletionFunc("primary-ipv4", cmpl.SuggestCandidatesF(client.PrimaryIP().Names(true, false, hcloud.Ptr(hcloud.PrimaryIPTypeIPv4)))) cmd.Flags().String("primary-ipv6", "", "Primary IPv6 (ID of name)") _ = cmd.RegisterFlagCompletionFunc("primary-ipv6", cmpl.SuggestCandidatesF(client.PrimaryIP().Names(true, false, hcloud.Ptr(hcloud.PrimaryIPTypeIPv6)))) cmd.Flags().Bool("without-ipv4", false, "Creates the Server without an IPv4 (default: false) (true, false)") cmd.Flags().Bool("without-ipv6", false, "Creates the Server without an IPv6 (default: false) (true, false)") cmd.Flags().StringSlice("enable-protection", []string{}, "Enable protection (delete, rebuild) (default: none)") _ = cmd.RegisterFlagCompletionFunc("enable-protection", cmpl.SuggestCandidates("delete", "rebuild")) cmd.Flags().Bool("enable-backup", false, "Enable automatic backups (true, false)") return cmd }, Run: func(s state.State, cmd *cobra.Command, _ []string) (*createResult, any, error) { createOpts, protectionOpts, err := createOptsFromFlags(s, cmd) if err != nil { return nil, nil, err } // Check if intended server type is deprecated in the requested location var locName string if createOpts.Location != nil { locName = createOpts.Location.Name } else if createOpts.Datacenter != nil { locName = createOpts.Datacenter.Location.Name } cmd.Print(deprecatedServerTypeWarning(createOpts.ServerType, locName)) result, _, err := s.Client().Server().Create(s, createOpts) if err != nil { return nil, nil, err } if err := s.WaitForActions(s, cmd, actionutil.AppendNext(result.Action, result.NextActions)...); err != nil { return nil, nil, err } cmd.Printf("Server %d created\n", result.Server.ID) if protectionOpts.Delete != nil || protectionOpts.Rebuild != nil { if err := ChangeProtectionCmds.ChangeProtection(s, cmd, result.Server, true, protectionOpts); err != nil { return nil, nil, err } } enableBackup, _ := cmd.Flags().GetBool("enable-backup") if enableBackup { action, _, err := s.Client().Server().EnableBackup(s, result.Server, "") if err != nil { return nil, nil, err } if err := s.WaitForActions(s, cmd, action); err != nil { return nil, nil, err } cmd.Printf("Backups enabled for Server %d\n", result.Server.ID) } server, _, err := s.Client().Server().GetByID(s, result.Server.ID) if err != nil { return nil, nil, err } if server == nil { return nil, nil, fmt.Errorf("Server not found: %d", result.Server.ID) } return &createResult{Server: server, RootPassword: result.RootPassword}, createResultSchema{Server: hcloud.SchemaFromServer(server), RootPassword: result.RootPassword}, nil }, PrintResource: func(s state.State, cmd *cobra.Command, result *createResult) { server := result.Server if !server.PublicNet.IPv4.IsUnspecified() { cmd.Printf("IPv4: %s\n", server.PublicNet.IPv4.IP.String()) } if !server.PublicNet.IPv6.IsUnspecified() { cmd.Printf("IPv6: %s1\n", server.PublicNet.IPv6.Network.IP.String()) cmd.Printf("IPv6 Network: %s\n", server.PublicNet.IPv6.Network.String()) } if len(server.PrivateNet) > 0 { cmd.Printf("Private Networks:\n") for _, network := range server.PrivateNet { cmd.Printf("\t- %s (%s)\n", network.IP.String(), s.Client().Network().Name(network.Network.ID)) } } if result.RootPassword != "" { cmd.Printf("Root password: %s\n", result.RootPassword) } }, }
CreateCmd defines a command for creating a server.
View Source
var CreateImageCmd = base.Cmd{ BaseCobraCommand: func(hcapi2.Client) *cobra.Command { cmd := &cobra.Command{ Use: "create-image [options] --type <snapshot|backup> <server>", Short: "Create an Image from a Server", } cmd.Flags().String("type", "", "Image type (backup, snapshot) (required)") _ = cmd.RegisterFlagCompletionFunc("type", cmpl.SuggestCandidates("backup", "snapshot")) _ = cmd.MarkFlagRequired("type") cmd.Flags().String("description", "", "Image description") cmd.Flags().StringToString("label", nil, "User-defined labels ('key=value') (can be specified multiple times)") return cmd }, Run: func(s state.State, cmd *cobra.Command, args []string) error { idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } imageType, _ := cmd.Flags().GetString("type") description, _ := cmd.Flags().GetString("description") labels, _ := cmd.Flags().GetStringToString("label") switch hcloud.ImageType(imageType) { case hcloud.ImageTypeBackup, hcloud.ImageTypeSnapshot: break default: return fmt.Errorf("invalid Image type: %v", imageType) } opts := &hcloud.ServerCreateImageOpts{ Type: hcloud.ImageType(imageType), Description: hcloud.Ptr(description), Labels: labels, } result, _, err := s.Client().Server().CreateImage(s, server, opts) if err != nil { return err } if err := s.WaitForActions(s, cmd, result.Action); err != nil { return err } cmd.Printf("Image %d created from Server %d\n", result.Image.ID, server.ID) return nil }, }
View Source
var DeleteCmd = base.DeleteCmd[*hcloud.Server]{ ResourceNameSingular: "Server", ResourceNamePlural: "Servers", ShortDescription: "Delete a server", NameSuggestions: func(c hcapi2.Client) func() []string { return c.Server().Names }, Fetch: func(s state.State, _ *cobra.Command, idOrName string) (*hcloud.Server, *hcloud.Response, error) { return s.Client().Server().Get(s, idOrName) }, Delete: func(s state.State, _ *cobra.Command, server *hcloud.Server) (*hcloud.Action, error) { result, _, err := s.Client().Server().DeleteWithResult(s, server) if err != nil { return nil, err } return result.Action, nil }, }
View Source
var DescribeCmd = base.DescribeCmd[*hcloud.Server]{ ResourceNameSingular: "Server", ShortDescription: "Describe a Server", NameSuggestions: func(c hcapi2.Client) func() []string { return c.Server().Names }, Fetch: func(s state.State, _ *cobra.Command, idOrName string) (*hcloud.Server, any, error) { srv, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return nil, nil, err } return srv, hcloud.SchemaFromServer(srv), nil }, PrintText: func(s state.State, _ *cobra.Command, out io.Writer, server *hcloud.Server) error { fmt.Fprintf(out, "ID:\t%d\n", server.ID) fmt.Fprintf(out, "Name:\t%s\n", server.Name) fmt.Fprintf(out, "Status:\t%s\n", server.Status) fmt.Fprintf(out, "Created:\t%s (%s)\n", util.Datetime(server.Created), humanize.Time(server.Created)) serverTypeDescription, _ := servertype.DescribeServerType(s, server.ServerType, true) fmt.Fprintln(out) fmt.Fprintf(out, "Server Type:\n") fmt.Fprintf(out, "%s", util.PrefixLines(serverTypeDescription, " ")) locationInfoIndex := slices.IndexFunc(server.ServerType.Locations, func(locInfo hcloud.ServerTypeLocation) bool { return locInfo.Location.Name == server.Location.Name }) if locationInfoIndex >= 0 { if text := util.DescribeDeprecation(server.ServerType.Locations[locationInfoIndex]); text != "" { fmt.Fprintln(out) fmt.Fprint(out, util.PrefixLines(text, " ")) } } fmt.Fprintln(out) fmt.Fprintf(out, "Public Net:\n") fmt.Fprintf(out, " IPv4:\n") if server.PublicNet.IPv4.IsUnspecified() { fmt.Fprintf(out, " No Primary IPv4\n") } else { fmt.Fprintf(out, " ID:\t%d\n", server.PublicNet.IPv4.ID) fmt.Fprintf(out, " IP:\t%s\n", server.PublicNet.IPv4.IP) fmt.Fprintf(out, " Blocked:\t%s\n", util.YesNo(server.PublicNet.IPv4.Blocked)) fmt.Fprintf(out, " DNS:\t%s\n", server.PublicNet.IPv4.DNSPtr) } fmt.Fprintln(out) fmt.Fprintf(out, " IPv6:\n") if server.PublicNet.IPv6.IsUnspecified() { fmt.Fprintf(out, " No Primary IPv6\n") } else { fmt.Fprintf(out, " ID:\t%d\n", server.PublicNet.IPv6.ID) fmt.Fprintf(out, " IP:\t%s\n", server.PublicNet.IPv6.Network.String()) fmt.Fprintf(out, " Blocked:\t%s\n", util.YesNo(server.PublicNet.IPv6.Blocked)) } fmt.Fprintln(out) fmt.Fprintf(out, " Floating IPs:\n") if len(server.PublicNet.FloatingIPs) > 0 { for _, f := range server.PublicNet.FloatingIPs { floatingIP, _, err := s.Client().FloatingIP().GetByID(s, f.ID) if err != nil { return fmt.Errorf("error fetching Floating IP: %w", err) } fmt.Fprintf(out, " - ID:\t%d\n", floatingIP.ID) fmt.Fprintf(out, " Description:\t%s\n", util.NA(floatingIP.Description)) fmt.Fprintf(out, " IP:\t%s\n", floatingIP.IP) } } else { fmt.Fprintf(out, " No Floating IPs\n") } fmt.Fprintln(out) fmt.Fprintf(out, "Private Net:\n") if len(server.PrivateNet) > 0 { for i, n := range server.PrivateNet { if i > 0 { fmt.Fprintln(out) } network, _, err := s.Client().Network().GetByID(s, n.Network.ID) if err != nil { return fmt.Errorf("error fetching Network: %w", err) } fmt.Fprintf(out, " - ID:\t%d\n", network.ID) fmt.Fprintf(out, " Name:\t%s\n", network.Name) fmt.Fprintf(out, " IP:\t%s\n", n.IP.String()) fmt.Fprintf(out, " MAC Address:\t%s\n", n.MACAddress) if len(n.Aliases) > 0 { fmt.Fprintf(out, " Alias IPs:\t\n") for _, a := range n.Aliases { fmt.Fprintf(out, " -\t%s\n", a) } } else { fmt.Fprintf(out, " Alias IPs:\t%s\n", util.NA("")) } } } else { fmt.Fprintf(out, " No Private Networks\n") } fmt.Fprintln(out) fmt.Fprintf(out, "Volumes:\n") if len(server.Volumes) > 0 { for _, v := range server.Volumes { volume, _, err := s.Client().Volume().GetByID(s, v.ID) if err != nil { return fmt.Errorf("error fetching Volume: %w", err) } fmt.Fprintf(out, " - ID:\t%d\n", volume.ID) fmt.Fprintf(out, " Name:\t%s\n", volume.Name) fmt.Fprintf(out, " Size:\t%s\n", humanize.Bytes(uint64(volume.Size)*humanize.GByte)) } } else { fmt.Fprintf(out, " No Volumes\n") } fmt.Fprintln(out) fmt.Fprintf(out, "Image:\n") if server.Image != nil { fmt.Fprint(out, util.PrefixLines(image.DescribeImage(server.Image), " ")) } else { fmt.Fprintf(out, " No Image\n") } fmt.Fprintln(out) fmt.Fprintf(out, "Location:\n") fmt.Fprint(out, util.PrefixLines(location.DescribeLocation(server.Location), " ")) if server.Datacenter != nil { fmt.Fprintln(out) fmt.Fprintf(out, "Datacenter:\n") fmt.Fprintf(out, "%s", util.PrefixLines(datacenter.DescribeDatacenter(s.Client(), server.Datacenter, true), " ")) } fmt.Fprintln(out) if server.BackupWindow != "" { fmt.Fprintf(out, "Backup Window:\t%s\n", server.BackupWindow) } else { fmt.Fprintf(out, "Backup Window:\tBackups disabled\n") } fmt.Fprintln(out) if server.RescueEnabled { fmt.Fprintf(out, "Rescue System:\tenabled\n") } else { fmt.Fprintf(out, "Rescue System:\tdisabled\n") } fmt.Fprintln(out) fmt.Fprintf(out, "Traffic:\n") fmt.Fprintf(out, " Outgoing:\t%v\n", humanize.IBytes(server.OutgoingTraffic)) fmt.Fprintf(out, " Ingoing:\t%v\n", humanize.IBytes(server.IngoingTraffic)) fmt.Fprintf(out, " Included:\t%v\n", humanize.IBytes(server.IncludedTraffic)) fmt.Fprintln(out) fmt.Fprintf(out, "ISO:\n") if server.ISO != nil { fmt.Fprint(out, util.PrefixLines(iso.DescribeISO(server.ISO), " ")) } else { fmt.Fprintf(out, " No ISO attached\n") } fmt.Fprintln(out) fmt.Fprintf(out, "Protection:\n") fmt.Fprintf(out, " Delete:\t%s\n", util.YesNo(server.Protection.Delete)) fmt.Fprintf(out, " Rebuild:\t%s\n", util.YesNo(server.Protection.Rebuild)) fmt.Fprintln(out) util.DescribeLabels(out, server.Labels, "") fmt.Fprintln(out) fmt.Fprintf(out, "Placement Group:\n") if server.PlacementGroup != nil { fmt.Fprint(out, util.PrefixLines(placementgroup.DescribePlacementGroup(s.Client(), server.PlacementGroup), " ")) } else { fmt.Fprintf(out, " No Placement Group set\n") } return nil }, }
View Source
var DetachFromNetworkCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { cmd := &cobra.Command{ Use: "detach-from-network --network <network> <server>", Short: "Detach a Server from a Network", ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), TraverseChildren: true, DisableFlagsInUseLine: true, } cmd.Flags().StringP("network", "n", "", "Network (ID or name) (required)") _ = cmd.RegisterFlagCompletionFunc("network", cmpl.SuggestCandidatesF(client.Network().Names)) _ = cmd.MarkFlagRequired("network") return cmd }, Run: func(s state.State, cmd *cobra.Command, args []string) error { idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } networkIDOrName, _ := cmd.Flags().GetString("network") network, _, err := s.Client().Network().Get(s, networkIDOrName) if err != nil { return err } if network == nil { return fmt.Errorf("Network not found: %s", networkIDOrName) } opts := hcloud.ServerDetachFromNetworkOpts{ Network: network, } action, _, err := s.Client().Server().DetachFromNetwork(s, server, opts) if err != nil { return err } if err := s.WaitForActions(s, cmd, action); err != nil { return err } cmd.Printf("Server %d detached from Network %d\n", server.ID, network.ID) return nil }, }
View Source
var DetachISOCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { return &cobra.Command{ Use: "detach-iso <server>", Short: "Detach an ISO from a Server", ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), TraverseChildren: true, DisableFlagsInUseLine: true, } }, Run: func(s state.State, cmd *cobra.Command, args []string) error { idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } action, _, err := s.Client().Server().DetachISO(s, server) if err != nil { return err } if err := s.WaitForActions(s, cmd, action); err != nil { return err } cmd.Printf("ISO detached from Server %d\n", server.ID) return nil }, }
View Source
var DisableBackupCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { return &cobra.Command{ Use: "disable-backup <server>", Short: "Disable backup for a server", ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), TraverseChildren: true, DisableFlagsInUseLine: true, } }, Run: func(s state.State, cmd *cobra.Command, args []string) error { idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } action, _, err := s.Client().Server().DisableBackup(s, server) if err != nil { return err } if err := s.WaitForActions(s, cmd, action); err != nil { return err } cmd.Printf("Backup disabled for Server %d\n", server.ID) return nil }, }
View Source
var DisableRescueCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { return &cobra.Command{ Use: "disable-rescue <server>", Short: "Disable rescue for a server", ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), TraverseChildren: true, DisableFlagsInUseLine: true, } }, Run: func(s state.State, cmd *cobra.Command, args []string) error { idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } action, _, err := s.Client().Server().DisableRescue(s, server) if err != nil { return err } if err := s.WaitForActions(s, cmd, action); err != nil { return err } cmd.Printf("Rescue disabled for Server %d\n", server.ID) return nil }, }
View Source
var EnableBackupCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { cmd := &cobra.Command{ Use: "enable-backup <server>", Short: "Enable backup for a server", ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), TraverseChildren: true, DisableFlagsInUseLine: true, } cmd.Flags().String( "window", "", "(deprecated) The time window for the daily backup to run. All times are in UTC. 22-02 means that the backup will be started between 10 PM and 2 AM.") return cmd }, Run: func(s state.State, cmd *cobra.Command, args []string) error { idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } window, _ := cmd.Flags().GetString("window") if window != "" { cmd.Print("[WARN] The ability to specify a backup window when enabling backups has been removed. Ignoring flag.\n") } action, _, err := s.Client().Server().EnableBackup(s, server, "") if err != nil { return err } if err := s.WaitForActions(s, cmd, action); err != nil { return err } cmd.Printf("Backup enabled for Server %d\n", server.ID) return nil }, }
View Source
var EnableRescueCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { cmd := &cobra.Command{ Use: "enable-rescue [options] <server>", Short: "Enable rescue for a server", ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), TraverseChildren: true, DisableFlagsInUseLine: true, } cmd.Flags().String("type", "linux64", "Rescue type") _ = cmd.RegisterFlagCompletionFunc("type", cmpl.SuggestCandidates("linux64")) cmd.Flags().StringSlice("ssh-key", nil, "ID or name of SSH Key to inject (can be specified multiple times)") _ = cmd.RegisterFlagCompletionFunc("ssh-key", cmpl.SuggestCandidatesF(client.SSHKey().Names)) return cmd }, Run: func(s state.State, cmd *cobra.Command, args []string) error { idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } var ( opts hcloud.ServerEnableRescueOpts ) rescueType, _ := cmd.Flags().GetString("type") opts.Type = hcloud.ServerRescueType(rescueType) switch opts.Type { case hcloud.ServerRescueTypeLinux64: break case hcloud.ServerRescueTypeLinux32: return fmt.Errorf("rescue type not supported anymore: %s", opts.Type) default: return fmt.Errorf("invalid rescue type: %s", opts.Type) } sshKeys, _ := cmd.Flags().GetStringSlice("ssh-key") for _, sshKeyIDOrName := range sshKeys { sshKey, _, err := s.Client().SSHKey().Get(s, sshKeyIDOrName) if err != nil { return err } if sshKey == nil { return fmt.Errorf("SSH Key not found: %s", sshKeyIDOrName) } opts.SSHKeys = append(opts.SSHKeys, sshKey) } result, _, err := s.Client().Server().EnableRescue(s, server, opts) if err != nil { return err } if err := s.WaitForActions(s, cmd, result.Action); err != nil { return err } cmd.Printf("Rescue enabled for Server %d with root password: %s\n", server.ID, result.RootPassword) return nil }, }
View Source
var IPCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { cmd := &cobra.Command{ Use: "ip [--ipv6] <server>", Short: "Print a server's IP address", ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), TraverseChildren: true, DisableFlagsInUseLine: true, } cmd.Flags().BoolP("ipv6", "6", false, "Print the first address of the Server's Primary IPv6 network") return cmd }, Run: func(s state.State, cmd *cobra.Command, args []string) error { ipv6, _ := cmd.Flags().GetBool("ipv6") idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } if ipv6 { if server.PublicNet.IPv6.IsUnspecified() { return fmt.Errorf("Server %s has no Primary IPv6", idOrName) } cmd.Println(server.PublicNet.IPv6.IP.String() + "1") } else { if server.PublicNet.IPv4.IsUnspecified() { return fmt.Errorf("Server %s has no Primary IPv4", idOrName) } cmd.Println(server.PublicNet.IPv4.IP.String()) } return nil }, }
View Source
var LabelCmds = base.LabelCmds[*hcloud.Server]{ ResourceNameSingular: "Server", ShortDescriptionAdd: "Add a label to a Server", ShortDescriptionRemove: "Remove a label from a Server", NameSuggestions: func(c hcapi2.Client) func() []string { return c.Server().Names }, LabelKeySuggestions: func(c hcapi2.Client) func(idOrName string) []string { return c.Server().LabelKeys }, Fetch: func(s state.State, idOrName string) (*hcloud.Server, error) { server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return nil, err } if server == nil { return nil, fmt.Errorf("Server not found: %s", idOrName) } return server, nil }, SetLabels: func(s state.State, server *hcloud.Server, labels map[string]string) error { opts := hcloud.ServerUpdateOpts{ Labels: labels, } _, _, err := s.Client().Server().Update(s, server, opts) return err }, GetLabels: func(server *hcloud.Server) map[string]string { return server.Labels }, GetIDOrName: func(server *hcloud.Server) string { return strconv.FormatInt(server.ID, 10) }, }
View Source
var ListCmd = &base.ListCmd[*hcloud.Server, schema.Server]{ ResourceNamePlural: "Servers", JSONKeyGetByName: "servers", DefaultColumns: []string{"id", "name", "status", "ipv4", "ipv6", "private_net", "location", "age"}, SortOption: config.OptionSortServer, AdditionalFlags: func(cmd *cobra.Command) { cmd.Flags().StringSlice("status", nil, "Only Servers with one of these statuses are displayed") _ = cmd.RegisterFlagCompletionFunc("status", cmpl.SuggestCandidates(serverStatusStrings...)) }, Fetch: func(s state.State, flags *pflag.FlagSet, listOpts hcloud.ListOpts, sorts []string) ([]*hcloud.Server, error) { statuses, _ := flags.GetStringSlice("status") opts := hcloud.ServerListOpts{ListOpts: listOpts} if len(sorts) > 0 { opts.Sort = sorts } if len(statuses) > 0 { for _, status := range statuses { if slices.Contains(serverStatusStrings, status) { opts.Status = append(opts.Status, hcloud.ServerStatus(status)) } else { return nil, fmt.Errorf("invalid status: %s", status) } } } return s.Client().Server().AllWithOpts(s, opts) }, OutputTable: func(t *output.Table[*hcloud.Server], client hcapi2.Client) { t. AddAllowedFields(&hcloud.Server{}). AddFieldFn("ipv4", func(server *hcloud.Server) string { if server.PublicNet.IPv4.IsUnspecified() { return "-" } return server.PublicNet.IPv4.IP.String() }). AddFieldFn("ipv6", func(server *hcloud.Server) string { if server.PublicNet.IPv6.IsUnspecified() { return "-" } return server.PublicNet.IPv6.Network.String() }). AddFieldFn("included_traffic", func(server *hcloud.Server) string { return humanize.IBytes(server.IncludedTraffic) }). AddFieldFn("ingoing_traffic", func(server *hcloud.Server) string { return humanize.IBytes(server.IngoingTraffic) }). AddFieldFn("outgoing_traffic", func(server *hcloud.Server) string { return humanize.IBytes(server.OutgoingTraffic) }). AddFieldFn("datacenter", func(server *hcloud.Server) string { if server.Datacenter != nil { return server.Datacenter.Name } return "-" }). AddFieldFn("location", func(server *hcloud.Server) string { return server.Location.Name }). AddFieldFn("labels", func(server *hcloud.Server) string { return util.LabelsToString(server.Labels) }). AddFieldFn("type", func(server *hcloud.Server) string { return server.ServerType.Name }). AddFieldFn("volumes", func(server *hcloud.Server) string { var volumes []string for _, volume := range server.Volumes { volumeID := strconv.FormatInt(volume.ID, 10) volumes = append(volumes, volumeID) } return strings.Join(volumes, ", ") }). AddFieldFn("private_net", func(server *hcloud.Server) string { var networks []string for _, network := range server.PrivateNet { networks = append(networks, fmt.Sprintf("%s (%s)", network.IP.String(), client.Network().Name(network.Network.ID))) } return util.NA(strings.Join(networks, ", ")) }). AddFieldFn("protection", func(server *hcloud.Server) string { var protection []string if server.Protection.Delete { protection = append(protection, "delete") } if server.Protection.Rebuild { protection = append(protection, "rebuild") } return strings.Join(protection, ", ") }). AddFieldFn("created", func(server *hcloud.Server) string { return util.Datetime(server.Created) }). AddFieldFn("age", func(server *hcloud.Server) string { return util.Age(server.Created, time.Now()) }). AddFieldFn("placement_group", func(server *hcloud.Server) string { if server.PlacementGroup == nil { return "-" } return server.PlacementGroup.Name }) }, Schema: hcloud.SchemaFromServer, }
View Source
var MetricsCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { cmd := &cobra.Command{ Use: fmt.Sprintf("metrics [options] (--type <%s>)... <server>", strings.Join(metricTypeStrings, "|")), Short: "[ALPHA] Metrics from a Server", ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), TraverseChildren: true, DisableFlagsInUseLine: true, } cmd.Flags().StringSlice("type", nil, "Types of metrics you want to show") _ = cmd.MarkFlagRequired("type") _ = cmd.RegisterFlagCompletionFunc("type", cmpl.SuggestCandidates(metricTypeStrings...)) cmd.Flags().String("start", "", "ISO 8601 timestamp") cmd.Flags().String("end", "", "ISO 8601 timestamp") output.AddFlag(cmd, output.OptionJSON(), output.OptionYAML()) return cmd }, Run: func(s state.State, cmd *cobra.Command, args []string) error { outputFlags := output.FlagsForCommand(cmd) idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } metricTypesStr, _ := cmd.Flags().GetStringSlice("type") var metricTypes []hcloud.ServerMetricType for _, t := range metricTypesStr { if slices.Contains(metricTypeStrings, t) { metricTypes = append(metricTypes, hcloud.ServerMetricType(t)) } else { return fmt.Errorf("invalid metric type: %s", t) } } start, _ := cmd.Flags().GetString("start") startTime := time.Now().Add(-30 * time.Minute) if start != "" { startTime, err = time.Parse(time.RFC3339, start) if err != nil { return fmt.Errorf("start date has an invalid format. It should be ISO 8601, like: %s", time.Now().Format(time.RFC3339)) } } end, _ := cmd.Flags().GetString("end") endTime := time.Now() if end != "" { endTime, err = time.Parse(time.RFC3339, end) if err != nil { return fmt.Errorf("end date has an invalid format. It should be ISO 8601, like: %s", time.Now().Format(time.RFC3339)) } } m, resp, err := s.Client().Server().GetMetrics(s, server, hcloud.ServerGetMetricsOpts{ Types: metricTypes, Start: startTime, End: endTime, }) if err != nil { return err } switch { case outputFlags.IsSet("json") || outputFlags.IsSet("yaml"): var schema map[string]interface{} if err := json.NewDecoder(resp.Body).Decode(&schema); err != nil { return err } if outputFlags.IsSet("json") { return util.DescribeJSON(cmd.OutOrStdout(), schema) } return util.DescribeYAML(cmd.OutOrStdout(), schema) default: var keys []string for k := range m.TimeSeries { keys = append(keys, k) } sort.Strings(keys) for _, k := range keys { if len(m.TimeSeries[k]) == 0 { cmd.Printf("Currently there are no metrics available. Please try it again later.") return nil } cmd.Printf("Server: %s \t Metric: %s \t Start: %s \t End: %s\n", server.Name, k, m.Start.String(), m.End.String()) var data []float64 for _, m := range m.TimeSeries[k] { d, _ := strconv.ParseFloat(m.Value, 64) data = append(data, d) } graph := asciigraph.Plot(data, asciigraph.Height(20), asciigraph.Width(100)) cmd.Println(graph) cmd.Printf("\n\n") } } return nil }, }
View Source
var PoweroffCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { return &cobra.Command{ Use: "poweroff <server>", Short: "Poweroff a Server", ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), TraverseChildren: true, DisableFlagsInUseLine: true, } }, Run: func(s state.State, cmd *cobra.Command, args []string) error { idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } action, _, err := s.Client().Server().Poweroff(s, server) if err != nil { return err } if err := s.WaitForActions(s, cmd, action); err != nil { return err } cmd.Printf("Server %d stopped\n", server.ID) return nil }, }
View Source
var PoweronCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { return &cobra.Command{ Use: "poweron <server>", Short: "Poweron a server", ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), TraverseChildren: true, DisableFlagsInUseLine: true, } }, Run: func(s state.State, cmd *cobra.Command, args []string) error { idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } action, _, err := s.Client().Server().Poweron(s, server) if err != nil { return err } if err := s.WaitForActions(s, cmd, action); err != nil { return err } cmd.Printf("Server %d started\n", server.ID) return nil }, }
View Source
var RebootCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { return &cobra.Command{ Use: "reboot <server>", Short: "Reboot a server", ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), TraverseChildren: true, DisableFlagsInUseLine: true, } }, Run: func(s state.State, cmd *cobra.Command, args []string) error { idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } action, _, err := s.Client().Server().Reboot(s, server) if err != nil { return err } if err := s.WaitForActions(s, cmd, action); err != nil { return err } cmd.Printf("Server %d rebooted\n", server.ID) return nil }, }
View Source
var RebuildCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { cmd := &cobra.Command{ Use: "rebuild [--allow-deprecated-image] --image <image> <server>", Short: "Rebuild a server", ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), TraverseChildren: true, DisableFlagsInUseLine: true, } cmd.Flags().String("image", "", "ID or name of Image to rebuild from (required)") _ = cmd.RegisterFlagCompletionFunc("image", cmpl.SuggestCandidatesF(client.Image().Names)) _ = cmd.MarkFlagRequired("image") cmd.Flags().Bool("allow-deprecated-image", false, "Enable the use of deprecated images (default: false) (true, false)") return cmd }, Run: func(s state.State, cmd *cobra.Command, args []string) error { serverIDOrName := args[0] server, _, err := s.Client().Server().Get(s, serverIDOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", serverIDOrName) } imageIDOrName, _ := cmd.Flags().GetString("image") image, _, err := s.Client().Image().GetForArchitecture(s, imageIDOrName, server.ServerType.Architecture) if err != nil { return err } if image == nil { return fmt.Errorf("image %s for architecture %s not found", imageIDOrName, server.ServerType.Architecture) } allowDeprecatedImage, _ := cmd.Flags().GetBool("allow-deprecated-image") if !image.Deprecated.IsZero() { if allowDeprecatedImage { cmd.Printf("Attention: Image %s is deprecated. It will continue to be available until %s.\n", image.Name, image.Deprecated.AddDate(0, 3, 0).Format(time.DateOnly)) } else { return fmt.Errorf("image %s is deprecated, please use --allow-deprecated-image to create a Server with this image. It will continue to be available until %s", image.Name, image.Deprecated.AddDate(0, 3, 0).Format(time.DateOnly)) } } opts := hcloud.ServerRebuildOpts{ Image: image, } result, _, err := s.Client().Server().RebuildWithResult(s, server, opts) if err != nil { return err } if err := s.WaitForActions(s, cmd, result.Action); err != nil { return err } cmd.Printf("Server %d rebuilt with Image %s\n", server.ID, image.Name) if result.RootPassword != "" { cmd.Printf("Root password: %s\n", result.RootPassword) } return nil }, }
View Source
var RemoveFromPlacementGroupCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { cmd := &cobra.Command{ Use: "remove-from-placement-group <server>", Short: "Removes a Server from a Placement Group", ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), } return cmd }, Run: func(s state.State, cmd *cobra.Command, args []string) error { idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } action, _, err := s.Client().Server().RemoveFromPlacementGroup(s, server) if err != nil { return err } if err := s.WaitForActions(s, cmd, action); err != nil { return err } cmd.Printf("Server %d removed from Placement Group\n", server.ID) return nil }, }
View Source
var RequestConsoleCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { cmd := &cobra.Command{ Use: "request-console [options] <server>", Short: "Request a WebSocket VNC console for a Server", ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), TraverseChildren: true, DisableFlagsInUseLine: true, } output.AddFlag(cmd, output.OptionJSON(), output.OptionYAML()) return cmd }, Run: func(s state.State, cmd *cobra.Command, args []string) error { outOpts := output.FlagsForCommand(cmd) idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } result, _, err := s.Client().Server().RequestConsole(s, server) if err != nil { return err } if err := s.WaitForActions(s, cmd, result.Action); err != nil { return err } if outOpts.IsSet("json") || outOpts.IsSet("yaml") { schema := struct { WSSURL string `json:"wss_url"` Password string `json:"password"` }{ WSSURL: result.WSSURL, Password: result.Password, } if outOpts.IsSet("json") { return util.DescribeJSON(cmd.OutOrStdout(), schema) } return util.DescribeYAML(cmd.OutOrStdout(), schema) } cmd.Printf("Console for Server %d:\n", server.ID) cmd.Printf("WebSocket URL: %s\n", result.WSSURL) cmd.Printf("VNC Password: %s\n", result.Password) return nil }, }
View Source
var ResetCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { return &cobra.Command{ Use: "reset [options] <server>", Short: "Reset a Server", ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), TraverseChildren: true, DisableFlagsInUseLine: true, } }, Run: func(s state.State, cmd *cobra.Command, args []string) error { idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } action, _, err := s.Client().Server().Reset(s, server) if err != nil { return err } if err := s.WaitForActions(s, cmd, action); err != nil { return err } cmd.Printf("Server %d reset\n", server.ID) return nil }, }
View Source
var ResetPasswordCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { cmd := &cobra.Command{ Use: "reset-password [options] <server>", Short: "Reset the root password of a Server", ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), TraverseChildren: true, DisableFlagsInUseLine: true, } output.AddFlag(cmd, output.OptionJSON(), output.OptionYAML()) return cmd }, Run: func(s state.State, cmd *cobra.Command, args []string) error { outputFlags := output.FlagsForCommand(cmd) idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } result, _, err := s.Client().Server().ResetPassword(s, server) if err != nil { return err } if err := s.WaitForActions(s, cmd, result.Action); err != nil { return err } if outputFlags.IsSet("json") || outputFlags.IsSet("yaml") { schema := make(map[string]interface{}) schema["root_password"] = result.RootPassword if outputFlags.IsSet("json") { return util.DescribeJSON(cmd.OutOrStdout(), schema) } return util.DescribeYAML(cmd.OutOrStdout(), schema) } cmd.Printf("Password of Server %d reset to: %s\n", server.ID, result.RootPassword) return nil }, }
View Source
var SSHCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { cmd := &cobra.Command{ Use: "ssh [options] <server> [--] [ssh options] [command [argument...]]", Short: "Spawn an SSH connection for the Server", Args: util.ValidateLenient, ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), TraverseChildren: true, DisableFlagsInUseLine: true, } cmd.Flags().SetInterspersed(false) cmd.Flags().Bool("ipv6", false, "Establish SSH connection to IPv6 address (true, false)") cmd.Flags().StringP("user", "u", "root", "Username for SSH connection") cmd.Flags().IntP("port", "p", 22, "Port for SSH connection") return cmd }, Run: func(s state.State, cmd *cobra.Command, args []string) error { idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } useIPv6, _ := cmd.Flags().GetBool("ipv6") user, _ := cmd.Flags().GetString("user") port, _ := cmd.Flags().GetInt("port") ipAddress := server.PublicNet.IPv4.IP if server.PublicNet.IPv4.IsUnspecified() || useIPv6 { if server.PublicNet.IPv6.IsUnspecified() { return fmt.Errorf("Server %s does not have a assigned Primary IPv4 or IPv6", idOrName) } ipAddress = server.PublicNet.IPv6.Network.IP ipAddress[15]++ } sshArgs := []string{"-l", user, "-p", strconv.Itoa(port), ipAddress.String()} sshCommand := exec.Command(SSHPath, append(sshArgs, args[1:]...)...) sshCommand.Stdin = os.Stdin sshCommand.Stdout = os.Stdout sshCommand.Stderr = os.Stderr if err := sshCommand.Run(); err != nil { var exitError *exec.ExitError if errors.As(err, &exitError) { waitStatus := exitError.Sys().(syscall.WaitStatus) os.Exit(waitStatus.ExitStatus()) } return err } return nil }, }
View Source
var SSHPath = "ssh"
View Source
var SetRDNSCmd = base.SetRdnsCmd[*hcloud.Server]{ ResourceNameSingular: "Server", ShortDescription: "Change reverse DNS of a Server", NameSuggestions: func(c hcapi2.Client) func() []string { return c.Server().Names }, Fetch: func(s state.State, _ *cobra.Command, idOrName string) (*hcloud.Server, *hcloud.Response, error) { return s.Client().Server().Get(s, idOrName) }, GetDefaultIP: func(server *hcloud.Server) net.IP { return server.PublicNet.IPv4.IP }, }
View Source
var ShutdownCmd = base.Cmd{ BaseCobraCommand: func(client hcapi2.Client) *cobra.Command { const description = "Shuts down a Server gracefully by sending an ACPI shutdown request. " + "The Server operating system must support ACPI and react to the request, " + "otherwise the Server will not shut down. Use the --wait flag to wait for the " + "Server to shut down before returning." cmd := &cobra.Command{ Use: "shutdown [options] <server>", Short: "Shutdown a server", Long: description, ValidArgsFunction: cmpl.SuggestArgs(cmpl.SuggestCandidatesF(client.Server().Names)), TraverseChildren: true, DisableFlagsInUseLine: true, } cmd.Flags().Bool("wait", false, "Wait for the Server to shut down before exiting (true, false)") cmd.Flags().Duration("wait-timeout", 30*time.Second, "Timeout for waiting for off state after shutdown") return cmd }, Run: func(s state.State, cmd *cobra.Command, args []string) error { wait, _ := cmd.Flags().GetBool("wait") timeout, _ := cmd.Flags().GetDuration("wait-timeout") idOrName := args[0] server, _, err := s.Client().Server().Get(s, idOrName) if err != nil { return err } if server == nil { return fmt.Errorf("Server not found: %s", idOrName) } action, _, err := s.Client().Server().Shutdown(s, server) if err != nil { return err } if err := s.WaitForActions(s, cmd, action); err != nil { return err } cmd.Printf("Sent shutdown signal to Server %d\n", server.ID) if wait { start := time.Now() interval, _ := cmd.Flags().GetDuration("poll-interval") if interval < time.Second { interval = time.Second } ticker := time.NewTicker(interval) defer ticker.Stop() progress := ui.NewProgress( os.Stderr, ui.FakeActionMessage("Waiting for Server to shut down"), ui.ActionResourcesMessage(&hcloud.ActionResource{ID: server.ID, Type: hcloud.ActionResourceTypeServer}), ) progress.Start() for server.Status != hcloud.ServerStatusOff { if now := <-ticker.C; now.Sub(start) >= timeout { progress.SetError() return errors.New("failed to shut down server") } server, _, err = s.Client().Server().GetByID(s, server.ID) if err != nil { progress.SetError() return err } } progress.SetSuccess() cmd.Printf("Server %d shut down\n", server.ID) } return nil }, }
View Source
var UpdateCmd = base.UpdateCmd[*hcloud.Server]{ ResourceNameSingular: "Server", ShortDescription: "Update a Server", NameSuggestions: func(c hcapi2.Client) func() []string { return c.Server().Names }, Fetch: func(s state.State, _ *cobra.Command, idOrName string) (*hcloud.Server, *hcloud.Response, error) { return s.Client().Server().Get(s, idOrName) }, DefineFlags: func(cmd *cobra.Command) { cmd.Flags().String("name", "", "Server name") }, Update: func(s state.State, _ *cobra.Command, server *hcloud.Server, flags map[string]pflag.Value) error { updOpts := hcloud.ServerUpdateOpts{ Name: flags["name"].String(), } _, _, err := s.Client().Server().Update(s, server, updOpts) if err != nil { return err } return nil }, }
Functions ¶
Types ¶
This section is empty.
Source Files
¶
- add_to_placement_group.go
- attach_iso.go
- attach_to_network.go
- change_alias_ips.go
- change_protection.go
- change_type.go
- create.go
- create_image.go
- delete.go
- describe.go
- detach_from_network.go
- detach_iso.go
- disable_backup.go
- disable_rescue.go
- enable_backup.go
- enable_rescue.go
- ip.go
- labels.go
- list.go
- metrics.go
- poweroff.go
- poweron.go
- reboot.go
- rebuild.go
- remove_from_placement_group.go
- request_console.go
- reset.go
- reset_password.go
- server.go
- set_rdns.go
- shutdown.go
- ssh.go
- texts.go
- update.go
Click to show internal directories.
Click to hide internal directories.