list dns records
This commit is contained in:
parent
8498f6f0a7
commit
04ebd05a8f
5 changed files with 244 additions and 3 deletions
|
|
@ -7,6 +7,8 @@ import (
|
|||
"git.juancwu.dev/juancwu/porkbacon/internal/ui/messages"
|
||||
"github.com/charmbracelet/bubbles/list"
|
||||
"github.com/charmbracelet/bubbles/paginator"
|
||||
"github.com/charmbracelet/bubbles/spinner"
|
||||
"github.com/charmbracelet/bubbles/textinput"
|
||||
tea "github.com/charmbracelet/bubbletea"
|
||||
"github.com/charmbracelet/lipgloss"
|
||||
)
|
||||
|
|
@ -20,6 +22,11 @@ type domainListMsg struct {
|
|||
Domains []string
|
||||
}
|
||||
|
||||
type dnsRecordListMsg struct {
|
||||
Status string
|
||||
Records []string
|
||||
}
|
||||
|
||||
type menuItem struct {
|
||||
id uint8
|
||||
title, desc string
|
||||
|
|
@ -39,10 +46,20 @@ const (
|
|||
utilPing
|
||||
)
|
||||
|
||||
const (
|
||||
stateNoOp uint8 = iota
|
||||
stateDNSRetrieveGetDomain
|
||||
)
|
||||
|
||||
type Model struct {
|
||||
list list.Model
|
||||
paginator paginator.Model
|
||||
spinner spinner.Model
|
||||
textInput textinput.Model
|
||||
loading bool
|
||||
state uint8
|
||||
domains []string
|
||||
records []string
|
||||
client *porkbun.Client
|
||||
err error
|
||||
output string
|
||||
|
|
@ -67,15 +84,27 @@ func New(client *porkbun.Client) *Model {
|
|||
p.ActiveDot = lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "235", Dark: "252"}).Render("•")
|
||||
p.InactiveDot = lipgloss.NewStyle().Foreground(lipgloss.AdaptiveColor{Light: "250", Dark: "238"}).Render("•")
|
||||
|
||||
s := spinner.New()
|
||||
s.Spinner = spinner.Dot
|
||||
s.Style = lipgloss.NewStyle().Foreground(lipgloss.Color("205"))
|
||||
|
||||
ti := textinput.New()
|
||||
ti.Placeholder = "example.com"
|
||||
ti.CharLimit = 156
|
||||
ti.Width = 20
|
||||
|
||||
return &Model{
|
||||
list: l,
|
||||
paginator: p,
|
||||
spinner: s,
|
||||
textInput: ti,
|
||||
client: client,
|
||||
state: 0,
|
||||
}
|
||||
}
|
||||
|
||||
func (m *Model) Init() tea.Cmd {
|
||||
return nil
|
||||
return tea.Sequence(m.spinner.Tick)
|
||||
}
|
||||
|
||||
func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
||||
|
|
@ -86,6 +115,42 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
return m, nil
|
||||
|
||||
case tea.KeyMsg:
|
||||
if m.loading && msg.String() == "ctrl+c" {
|
||||
return m, tea.Quit
|
||||
}
|
||||
|
||||
if m.state == stateDNSRetrieveGetDomain {
|
||||
switch msg.String() {
|
||||
case "enter":
|
||||
domain := m.textInput.Value()
|
||||
m.textInput.SetValue("")
|
||||
m.state = stateNoOp
|
||||
m.loading = true
|
||||
cmd := func() tea.Msg {
|
||||
resp, err := m.client.RetrieveDNSRecords(domain)
|
||||
if err != nil {
|
||||
return messages.ErrorMsg(err)
|
||||
}
|
||||
var records []string
|
||||
for _, record := range resp.Records {
|
||||
records = append(records, renderRecordItem(&record))
|
||||
}
|
||||
return dnsRecordListMsg{
|
||||
Status: resp.Status,
|
||||
Records: records,
|
||||
}
|
||||
}
|
||||
return m, tea.Batch(cmd, m.spinner.Tick)
|
||||
case "esc":
|
||||
m.state = stateNoOp
|
||||
m.textInput.SetValue("")
|
||||
return m, nil
|
||||
}
|
||||
var cmd tea.Cmd
|
||||
m.textInput, cmd = m.textInput.Update(msg)
|
||||
return m, cmd
|
||||
}
|
||||
|
||||
if m.output != "" {
|
||||
if msg.String() == "esc" {
|
||||
m.output = ""
|
||||
|
|
@ -104,6 +169,16 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
return m, cmd
|
||||
}
|
||||
|
||||
if len(m.records) > 0 {
|
||||
var cmd tea.Cmd
|
||||
m.paginator, cmd = m.paginator.Update(msg)
|
||||
if msg.String() == "esc" {
|
||||
m.records = nil
|
||||
return m, nil
|
||||
}
|
||||
return m, cmd
|
||||
}
|
||||
|
||||
if msg.String() == "enter" {
|
||||
i, ok := m.list.SelectedItem().(menuItem)
|
||||
if ok {
|
||||
|
|
@ -111,13 +186,24 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
}
|
||||
}
|
||||
|
||||
case dnsRecordListMsg:
|
||||
m.loading = false
|
||||
m.paginator.PerPage = 1
|
||||
m.paginator.SetTotalPages(len(msg.Records))
|
||||
m.paginator.Page = 0
|
||||
m.domains = msg.Records
|
||||
return m, nil
|
||||
|
||||
case domainListMsg:
|
||||
m.loading = false
|
||||
m.paginator.PerPage = 1
|
||||
m.paginator.SetTotalPages(len(msg.Domains))
|
||||
m.paginator.Page = 0
|
||||
m.domains = msg.Domains
|
||||
return m, nil
|
||||
|
||||
case pingResultMsg:
|
||||
m.loading = false
|
||||
m.output = fmt.Sprintf("Ping successful!\nYour IP: %s", msg.IP)
|
||||
return m, nil
|
||||
|
||||
|
|
@ -127,26 +213,51 @@ func (m *Model) Update(msg tea.Msg) (tea.Model, tea.Cmd) {
|
|||
}
|
||||
|
||||
var cmd tea.Cmd
|
||||
if m.loading {
|
||||
m.spinner, cmd = m.spinner.Update(msg)
|
||||
return m, cmd
|
||||
}
|
||||
|
||||
m.list, cmd = m.list.Update(msg)
|
||||
return m, cmd
|
||||
}
|
||||
|
||||
func (m *Model) View() string {
|
||||
if m.loading {
|
||||
return fmt.Sprintf("\n\n %s Loading... press ctl+c to quit\n\n", m.spinner.View())
|
||||
}
|
||||
|
||||
if m.output != "" {
|
||||
return fmt.Sprintf("%s\n\n(Press Esc to go back)", m.output)
|
||||
}
|
||||
|
||||
if m.state == stateDNSRetrieveGetDomain {
|
||||
return fmt.Sprintf(
|
||||
"Enter domain to retrieve records for:\n\n%s\n\n(esc to quit)",
|
||||
m.textInput.View(),
|
||||
)
|
||||
}
|
||||
|
||||
if len(m.domains) > 0 {
|
||||
return fmt.Sprintf("%s\n\n%s\n\n(Press Esc to go back, arrows to navigate)", m.domains[m.paginator.Page], m.paginator.View())
|
||||
}
|
||||
|
||||
if len(m.records) > 0 {
|
||||
return fmt.Sprintf("%s\n\n%s\n\n(Press Esc to go back, arrows to navigate)", m.records[m.paginator.Page], m.paginator.View())
|
||||
}
|
||||
|
||||
return m.list.View()
|
||||
}
|
||||
|
||||
func (m *Model) handleSelection(i menuItem) (tea.Model, tea.Cmd) {
|
||||
switch i.id {
|
||||
case dnsRetrieveRecords:
|
||||
m.state = stateDNSRetrieveGetDomain
|
||||
m.textInput.Focus()
|
||||
return m, textinput.Blink
|
||||
case domainListAll:
|
||||
return m, func() tea.Msg {
|
||||
m.loading = true
|
||||
cmd := func() tea.Msg {
|
||||
resp, err := m.client.DomainListAll(0, true)
|
||||
if err != nil {
|
||||
return messages.ErrorMsg(err)
|
||||
|
|
@ -161,14 +272,17 @@ func (m *Model) handleSelection(i menuItem) (tea.Model, tea.Cmd) {
|
|||
Domains: domains,
|
||||
}
|
||||
}
|
||||
return m, tea.Batch(cmd, m.spinner.Tick)
|
||||
case utilPing:
|
||||
return m, func() tea.Msg {
|
||||
m.loading = true
|
||||
cmd := func() tea.Msg {
|
||||
resp, err := m.client.Ping()
|
||||
if err != nil {
|
||||
return messages.ErrorMsg(err)
|
||||
}
|
||||
return pingResultMsg{IP: resp.YourIP}
|
||||
}
|
||||
return m, tea.Batch(cmd, m.spinner.Tick)
|
||||
}
|
||||
return m, nil
|
||||
}
|
||||
|
|
|
|||
23
internal/ui/pages/menu/recorditem.go
Normal file
23
internal/ui/pages/menu/recorditem.go
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
package menu
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"git.juancwu.dev/juancwu/porkbacon/internal/porkbun"
|
||||
"git.juancwu.dev/juancwu/porkbacon/internal/ui/utils"
|
||||
)
|
||||
|
||||
func renderRecordItem(item *porkbun.DNSRecord) string {
|
||||
var b strings.Builder
|
||||
b.WriteString("ID: " + item.ID + "\n")
|
||||
b.WriteString("Name: " + item.Name + "\n")
|
||||
b.WriteString("Type: " + item.Type + "\n")
|
||||
b.WriteString(fmt.Sprintln("TTL:", item.TTL))
|
||||
b.WriteString(fmt.Sprintln("Priority:", item.Priority))
|
||||
b.WriteString("Content: ")
|
||||
b.WriteString(utils.WrapText(item.Content, 80))
|
||||
b.WriteString("\n")
|
||||
b.WriteString("Notes: " + item.Notes + "\n")
|
||||
return b.String()
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue