Documentation
¶
Index ¶
- Variables
- func Max(a int, b int) int
- func PreRun() error
- func PreRunDefaultProfile(_ *cobra.Command, _ []string) error
- func PrintVersion(version, commit string) error
- type Alert
- type AlertConfig
- type DatasetListItem
- type DatasetRetentionData
- type DatasetStatsData
- type Item
- type ProfileListItem
- type Repeat
- type RoleData
- type RoleResource
- type Rule
- type RuleConfig
- type Target
- type UserData
- type UserRoleAction
- type UserRolesResponse
- type UserServerRole
Constants ¶
This section is empty.
Variables ¶
var ( // FocusPrimary / FocusSecondary used to be yellow (ANSI 226/220). Now // brand indigo — same role (selected / active item highlight) but // matches the rest of the design system. FocusPrimary = ui.Adaptive(func(p ui.Palette) lipgloss.Color { return p.Accent }) FocusSecondary = ui.Adaptive(func(p ui.Palette) lipgloss.Color { return p.Accent2 }) StandardPrimary = ui.Adaptive(func(p ui.Palette) lipgloss.Color { return p.Body }) StandardSecondary = ui.Adaptive(func(p ui.Palette) lipgloss.Color { return p.Mute }) StandardStyle = lipgloss.NewStyle().Foreground(StandardPrimary) StandardStyleBold = lipgloss.NewStyle().Foreground(StandardPrimary).Bold(true) StandardStyleAlt = lipgloss.NewStyle().Foreground(StandardSecondary) StandardStyleRule = lipgloss.NewStyle().Foreground(ui.Adaptive(func(p ui.Palette) lipgloss.Color { return p.Border })) SelectedStyle = lipgloss.NewStyle().Foreground(FocusPrimary).Bold(true) SelectedStyleAlt = lipgloss.NewStyle().Foreground(FocusSecondary) SelectedItemOuter = lipgloss.NewStyle(). BorderStyle(lipgloss.NormalBorder()). BorderLeft(true). PaddingLeft(1). BorderForeground(FocusPrimary) ItemOuter = lipgloss.NewStyle().PaddingLeft(1) StyleBold = lipgloss.NewStyle().Bold(true) )
Styles for the cobra command CLI outputs (prompts, error messages, list items rendered outside the bubbletea TUI). Sourced from the shared ui.Palette so any palette change auto-propagates here.
Names kept stable for backwards compatibility with existing call sites across cmd/ and pkg/model/.
var AddDatasetCmd = &cobra.Command{ Use: "add dataset-name", Example: " pb dataset add backend_logs\n pb dataset add frontend_metrics --type metrics\n pb dataset add checkout_traces --type traces", Short: "Create a new dataset", Args: cobra.ExactArgs(1), SilenceUsage: true, RunE: func(cmd *cobra.Command, args []string) error { startTime := time.Now() cmd.Annotations = make(map[string]string) defer func() { cmd.Annotations["executionTime"] = time.Since(startTime).String() }() name := args[0] datasetType, err := cmd.Flags().GetString(datasetTypeFlag) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error: %s", err.Error()) return err } datasetType, err = resolveDatasetType(datasetType) if err != nil { if errors.Is(err, errDatasetTypeSelectionCanceled) { fmt.Println("Dataset creation canceled") return nil } cmd.Annotations["errors"] = fmt.Sprintf("Error: %s", err.Error()) return err } client := internalHTTP.DefaultClient(&DefaultProfile) req, err := client.NewRequest("PUT", "logstream/"+name, nil) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error: %s", err.Error()) return err } req.Header.Set("X-P-Telemetry-Type", datasetType) if datasetType == datasets.TypeMetrics || datasetType == datasets.TypeTraces { req.Header.Set("X-P-Log-Source", "otel-"+datasetType) } resp, err := client.Client.Do(req) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error: %s", err.Error()) return err } cmd.Annotations["executionTime"] = time.Since(startTime).String() if resp.StatusCode == 200 { fmt.Printf("Created %s dataset %s\n", SelectedStyle.Render(datasetType), StyleBold.Render(name)) } else { bytes, err := io.ReadAll(resp.Body) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error: %s", err.Error()) return err } body := string(bytes) defer resp.Body.Close() fmt.Printf("Request Failed\nStatus Code: %s\nResponse: %s\n", resp.Status, body) } return nil }, }
AddDatasetCmd is the parent command for dataset
var AddProfileCmd = &cobra.Command{ Use: "add profile-name url <username?> <password?>", Example: " pb profile add local_parseable http://0.0.0.0:8000 admin admin", Short: "Add a new profile", Long: "Add a new profile to the config file", Args: func(cmd *cobra.Command, args []string) error { if err := cobra.MinimumNArgs(2)(cmd, args); err != nil { return err } return cobra.MaximumNArgs(4)(cmd, args) }, RunE: func(cmd *cobra.Command, args []string) error { if cmd.Annotations == nil { cmd.Annotations = make(map[string]string) } startTime := time.Now() var commandError error name := args[0] url, err := url.Parse(args[1]) if err != nil { commandError = fmt.Errorf("error parsing URL: %s", err) cmd.Annotations["error"] = commandError.Error() return commandError } var username, password string if len(args) < 4 { _m, err := tea.NewProgram(credential.New()).Run() if err != nil { commandError = fmt.Errorf("error reading credentials: %s", err) cmd.Annotations["error"] = commandError.Error() return commandError } m := _m.(credential.Model) username, password = m.Values() } else { username = args[2] password = args[3] } profile := config.Profile{URL: url.String(), Username: username, Password: password} fileConfig, err := config.ReadConfigFromFile() if err != nil { newConfig := config.Config{ Profiles: map[string]config.Profile{name: profile}, DefaultProfile: name, } err = config.WriteConfigToFile(&newConfig) commandError = err } else { if fileConfig.Profiles == nil { fileConfig.Profiles = make(map[string]config.Profile) } fileConfig.Profiles[name] = profile if fileConfig.DefaultProfile == "" { fileConfig.DefaultProfile = name } commandError = config.WriteConfigToFile(fileConfig) } cmd.Annotations["executionTime"] = time.Since(startTime).String() if commandError != nil { cmd.Annotations["error"] = commandError.Error() return commandError } if outputFormat == "json" { return outputResult(profile) } fmt.Printf("Profile %s added successfully\n", name) return nil }, }
var AddRoleCmd = &cobra.Command{ Use: "add role-name", Example: " pb role add ingestors", Short: "Add a new role", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { startTime := time.Now() cmd.Annotations = make(map[string]string) defer func() { cmd.Annotations["executionTime"] = time.Since(startTime).String() }() name := args[0] var roles []string client := internalHTTP.DefaultClient(&DefaultProfile) if err := fetchRoles(&client, &roles); err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error fetching roles: %s", err.Error()) return err } if strings.Contains(strings.Join(roles, " "), name) { fmt.Println("role already exists, please use a different name") return nil } _m, err := tea.NewProgram(role.New()).Run() if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error initializing program: %s", err.Error()) return err } m := _m.(role.Model) privilege := m.Selection.Value() stream := m.Stream.Value() if !m.Success { fmt.Println("aborted by user") return nil } var putBody io.Reader if privilege != "none" { roleData := RoleData{Privilege: privilege} switch privilege { case "writer", "ingestor": roleData.Resource = &RoleResource{Stream: stream} case "reader": roleData.Resource = &RoleResource{Stream: stream} } roleDataJSON, _ := json.Marshal([]RoleData{roleData}) putBody = bytes.NewBuffer(roleDataJSON) } req, err := client.NewRequest("PUT", "role/"+name, putBody) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error creating request: %s", err.Error()) return err } resp, err := client.Client.Do(req) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error performing request: %s", err.Error()) return err } defer resp.Body.Close() bodyBytes, err := io.ReadAll(resp.Body) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error reading response: %s", err.Error()) return err } body := string(bodyBytes) if resp.StatusCode == 200 { fmt.Printf("Added role %s", name) } else { cmd.Annotations["errors"] = fmt.Sprintf("Request failed - Status: %s, Response: %s", resp.Status, body) fmt.Printf("Request Failed\nStatus Code: %s\nResponse: %s\n", resp.Status, body) } return nil }, }
var AddUserCmd = func() *cobra.Command {
addUser.Flags().StringP(roleFlag, roleFlagShort, "", "specify the role(s) to be assigned to the user. Use comma separated values for multiple roles. Example: --role admin,developer")
return addUser
}()
var AutocompleteCmd = &cobra.Command{ Use: "autocomplete [bash|zsh|powershell]", Short: "Generate autocomplete script", Long: `Generate autocomplete script for bash, zsh, or powershell`, Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { var err error switch args[0] { case "bash": err = cmd.Root().GenBashCompletion(os.Stdout) case "zsh": err = cmd.Root().GenZshCompletion(os.Stdout) case "powershell": err = cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout) default: err = fmt.Errorf("unsupported shell type: %s. Only bash, zsh, and powershell are supported", args[0]) } if err != nil { return fmt.Errorf("error generating autocomplete script: %w", err) } return nil }, }
AutocompleteCmd represents the autocomplete command
var CreateSchemaCmd = &cobra.Command{ Use: "create", Short: "Create Schema for a Parseable dataset", Example: "pb schema create --dataset=my_dataset --file=schema.json", RunE: func(cmd *cobra.Command, _ []string) error { streamName, err := cmd.Flags().GetString("dataset") if err != nil { return fmt.Errorf(common.Red+"failed to read dataset flag: %w"+common.Reset, err) } if streamName == "" { return fmt.Errorf(common.Red + "dataset flag is required" + common.Reset) } filePath, err := cmd.Flags().GetString("file") if err != nil { return fmt.Errorf(common.Red+"failed to read config flag: %w"+common.Reset, err) } if filePath == "" { return fmt.Errorf(common.Red + "file path flag is required" + common.Reset) } schemaContent, err := os.ReadFile(filePath) if err != nil { return fmt.Errorf(common.Red+"failed to read schema file %s: %w"+common.Reset, filePath, err) } client := internalHTTP.DefaultClient(&DefaultProfile) apiPath := fmt.Sprintf("/logstream/%s", streamName) req, err := client.NewRequest(http.MethodPut, apiPath, bytes.NewBuffer(schemaContent)) if err != nil { return fmt.Errorf(common.Red+"failed to create new request: %w"+common.Reset, err) } req.Header.Set("Content-Type", "application/json") req.Header.Set("X-P-Static-Schema-Flag", "true") resp, err := client.Client.Do(req) if err != nil { return fmt.Errorf(common.Red+"request execution failed: %w"+common.Reset, err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) fmt.Printf(common.Red+"Error response: %s\n"+common.Reset, string(body)) return fmt.Errorf(common.Red+"non-200 status code received: %s"+common.Reset, resp.Status) } respBody, err := io.ReadAll(resp.Body) if err != nil { return fmt.Errorf(common.Red+"failed to read response body: %w"+common.Reset, err) } fmt.Println(common.Green + string(respBody) + common.Reset) return nil }, }
var DefaultProfile config.Profile
var DefaultProfileCmd = &cobra.Command{ Use: "default profile-name", Args: cobra.MaximumNArgs(1), Short: "Set default profile to use with all commands", Example: " pb profile default local_parseable", RunE: func(cmd *cobra.Command, args []string) error { if cmd.Annotations == nil { cmd.Annotations = make(map[string]string) } startTime := time.Now() fileConfig, err := config.ReadConfigFromFile() if err != nil { cmd.Annotations["error"] = fmt.Sprintf("error reading config: %s", err) return err } var name string if len(args) > 0 { name = args[0] } else { model := defaultprofile.New(fileConfig.Profiles) _m, err := tea.NewProgram(model).Run() if err != nil { cmd.Annotations["error"] = fmt.Sprintf("error selecting default profile: %s", err) return err } m := _m.(defaultprofile.Model) if !m.Success { return nil } name = m.Choice } _, exists := fileConfig.Profiles[name] if !exists { commandError := fmt.Sprintf("profile %s does not exist", name) cmd.Annotations["error"] = commandError return errors.New(commandError) } fileConfig.DefaultProfile = name commandError := config.WriteConfigToFile(fileConfig) cmd.Annotations["executionTime"] = time.Since(startTime).String() if commandError != nil { cmd.Annotations["error"] = commandError.Error() return commandError } if outputFormat == "json" { return outputResult(fmt.Sprintf("%s is now set as default profile", name)) } fmt.Printf("%s is now set as default profile\n", name) return nil }, }
var GenerateSchemaCmd = &cobra.Command{ Use: "generate", Short: "Generate Schema for JSON", Example: "pb schema generate --file=test.json", RunE: func(cmd *cobra.Command, _ []string) error { filePath, err := cmd.Flags().GetString("file") if err != nil { return fmt.Errorf(common.Red+"failed to read file flag: %w"+common.Reset, err) } if filePath == "" { return fmt.Errorf(common.Red + "file flag is required" + common.Reset) } fileContent, err := os.ReadFile(filePath) if err != nil { return fmt.Errorf(common.Red+"failed to read file %s: %w"+common.Reset, filePath, err) } client := internalHTTP.DefaultClient(&DefaultProfile) req, err := client.NewRequest(http.MethodPost, generateStaticSchemaPath, bytes.NewBuffer(fileContent)) if err != nil { return fmt.Errorf(common.Red+"failed to create new request: %w"+common.Reset, err) } req.Header.Set("Content-Type", "application/json") resp, err := client.Client.Do(req) if err != nil { return fmt.Errorf(common.Red+"request execution failed: %w"+common.Reset, err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { body, _ := io.ReadAll(resp.Body) fmt.Printf(common.Red+"Error response: %s\n"+common.Reset, string(body)) return fmt.Errorf(common.Red+"non-200 status code received: %s"+common.Reset, resp.Status) } respBody, err := io.ReadAll(resp.Body) if err != nil { return fmt.Errorf(common.Red+"failed to read response body: %w"+common.Reset, err) } var prettyJSON bytes.Buffer if err := json.Indent(&prettyJSON, respBody, "", " "); err != nil { return fmt.Errorf(common.Red+"failed to format response as JSON: %w"+common.Reset, err) } fmt.Println(common.Green + prettyJSON.String() + common.Reset) return nil }, }
var InstallOssCmd = &cobra.Command{ Use: "install", Short: "Deploy Parseable", Example: "pb cluster install", Run: func(cmd *cobra.Command, _ []string) { cmd.Flags().BoolVarP(&verbose, "verbose", "v", false, "Enable verbose logging") installer.Installer(verbose) }, }
var ListDatasetCmd = &cobra.Command{ Use: "list", Aliases: []string{"ls"}, Example: " pb dataset list", Short: "List all datasets", SilenceUsage: true, RunE: func(cmd *cobra.Command, _ []string) error { startTime := time.Now() cmd.Annotations = make(map[string]string) defer func() { cmd.Annotations["executionTime"] = time.Since(startTime).String() }() items, err := datasets.FetchHomeDatasets(DefaultProfile) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error: %s", err.Error()) return err } output, _ := cmd.Flags().GetString("output") if output == "json" { jsonData, err := json.MarshalIndent(items, "", " ") if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error: %s", err.Error()) return err } fmt.Println(string(jsonData)) return nil } for _, dataset := range items { fmt.Println((&DatasetListItem{Name: dataset.Title, Type: dataset.DatasetType}).Render()) } return nil }, }
ListDatasetCmd is the list command for datasets
var ListOssCmd = &cobra.Command{ Use: "list", Short: "List available Parseable servers", Example: "pb list", Run: func(_ *cobra.Command, _ []string) { _, err := common.PromptK8sContext() if err != nil { log.Fatalf("Failed to prompt for kubernetes context: %v", err) } entries, err := common.ReadInstallerConfigMap() if err != nil { log.Fatalf("Failed to list servers: %v", err) } if len(entries) == 0 { fmt.Println("No clusters found.") return } table := tablewriter.NewWriter(os.Stdout) table.SetHeader([]string{"Name", "Namespace", "Version", "Status"}) for _, entry := range entries { table.Append([]string{entry.Name, entry.Namespace, entry.Version, entry.Status}) } table.Render() }, }
ListOssCmd lists the Parseable OSS servers
var ListProfileCmd = &cobra.Command{ Use: "list profiles", Aliases: []string{"ls"}, Short: "List all added profiles", Example: " pb profile list", RunE: func(cmd *cobra.Command, _ []string) error { if cmd.Annotations == nil { cmd.Annotations = make(map[string]string) } startTime := time.Now() fileConfig, err := config.ReadConfigFromFile() if err != nil { cmd.Annotations["error"] = fmt.Sprintf("error reading config: %s", err) return err } if outputFormat == "json" { commandError := outputResult(fileConfig.Profiles) cmd.Annotations["executionTime"] = time.Since(startTime).String() if commandError != nil { cmd.Annotations["error"] = commandError.Error() return commandError } return nil } for key, value := range fileConfig.Profiles { item := ProfileListItem{key, value.URL, value.Username} fmt.Println(item.Render(fileConfig.DefaultProfile == key)) fmt.Println() } cmd.Annotations["executionTime"] = time.Since(startTime).String() return nil }, }
var ListRoleCmd = &cobra.Command{ Use: "list", Aliases: []string{"ls"}, Short: "List all roles", Example: " pb role list", SilenceUsage: true, RunE: func(cmd *cobra.Command, _ []string) error { startTime := time.Now() cmd.Annotations = make(map[string]string) defer func() { cmd.Annotations["executionTime"] = time.Since(startTime).String() }() var roles []string client := internalHTTP.DefaultClient(&DefaultProfile) err := fetchRoles(&client, &roles) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error fetching roles: %s", err.Error()) return err } outputFormat, err := cmd.Flags().GetString("output") if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error retrieving output flag: %s", err.Error()) return err } roleResponses := make([]struct { data []RoleData err error }, len(roles)) var wg sync.WaitGroup for idx, role := range roles { wg.Add(1) go func(idx int, role string) { defer wg.Done() roleResponses[idx].data, roleResponses[idx].err = fetchSpecificRole(&client, role) }(idx, role) } wg.Wait() if outputFormat == "json" { allRoles := map[string][]RoleData{} for idx, roleName := range roles { if roleResponses[idx].err == nil { allRoles[roleName] = roleResponses[idx].data } } jsonOutput, err := json.MarshalIndent(allRoles, "", " ") if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error marshaling JSON output: %s", err.Error()) return fmt.Errorf("failed to marshal JSON output: %w", err) } fmt.Println(string(jsonOutput)) return nil } printRoleTable(roles, roleResponses) var fetchErrors []string for idx, roleName := range roles { if roleResponses[idx].err != nil { errMsg := fmt.Sprintf("Error fetching role data for %s: %v", roleName, roleResponses[idx].err) fetchErrors = append(fetchErrors, errMsg) cmd.Annotations["errors"] += errMsg + "\n" } } if len(fetchErrors) > 0 { return fmt.Errorf("failed to fetch details for %d role(s): %s", len(fetchErrors), strings.Join(fetchErrors, "; ")) } return nil }, }
var ListUserCmd = &cobra.Command{ Use: "list", Aliases: []string{"ls"}, Short: "List all users", Example: " pb user list", SilenceUsage: true, RunE: func(cmd *cobra.Command, _ []string) error { startTime := time.Now() cmd.Annotations = make(map[string]string) defer func() { cmd.Annotations["executionTime"] = time.Since(startTime).String() }() client := internalHTTP.DefaultClient(&DefaultProfile) users, err := fetchUsers(&client) if err != nil { cmd.Annotations["error"] = err.Error() return err } roleResponses := make([]struct { data []string err error }, len(users)) wsg := sync.WaitGroup{} for idx, user := range users { wsg.Add(1) out := &roleResponses[idx] userID := user.ID client := &client go func() { var rolesResp UserRolesResponse rolesResp, out.err = fetchUserRoles(client, userID) if out.err == nil { for roleName := range rolesResp.DirectRoles { out.data = append(out.data, roleName) } for _, groupRoles := range rolesResp.GroupRoles { for roleName := range groupRoles { out.data = append(out.data, roleName) } } } wsg.Done() }() } wsg.Wait() outputFormat, err := cmd.Flags().GetString("output") if err != nil { cmd.Annotations["error"] = err.Error() return err } if outputFormat == "json" { usersWithRoles := make([]map[string]interface{}, len(users)) for idx, user := range users { usersWithRoles[idx] = map[string]interface{}{ "id": user.ID, "roles": roleResponses[idx].data, } } jsonOutput, err := json.MarshalIndent(usersWithRoles, "", " ") if err != nil { cmd.Annotations["error"] = err.Error() return fmt.Errorf("failed to marshal JSON output: %w", err) } fmt.Println(string(jsonOutput)) return userRoleFetchError(cmd, users, roleResponses) } if outputFormat == "text" { printUserRoleTable(users, roleResponses) return userRoleFetchError(cmd, users, roleResponses) } printUserRoleTable(users, roleResponses) return userRoleFetchError(cmd, users, roleResponses) }, }
var LoginCmd = &cobra.Command{ Use: "login", Short: "Login to Parseable", Long: `Interactive login wizard for Parseable. Select self-hosted and enter your server URL, credentials, and a profile name. All settings are saved to ~/.config/pb/config.toml.`, RunE: func(_ *cobra.Command, _ []string) error { _m, err := tea.NewProgram(login.New()).Run() if err != nil { return err } m, ok := _m.(login.Model) if !ok || !m.Done { return nil } if err := writeProfile(m.Profile, m.Name); err != nil { return fmt.Errorf("failed to save profile: %w", err) } return nil }, }
var LogoutCmd = &cobra.Command{ Use: "logout", Short: "Logout from the current Parseable profile", Long: "Removes the active profile (URL and credentials) from config.", Example: " pb logout", RunE: func(_ *cobra.Command, _ []string) error { fileConfig, err := config.ReadConfigFromFile() if err != nil { return fmt.Errorf("no config found — nothing to logout from") } profileName := fileConfig.DefaultProfile activeProfile, exists := fileConfig.Profiles[profileName] if !exists || profileName == "" { if len(fileConfig.Profiles) == 0 { return fmt.Errorf("no active profile found") } selectedProfile, err := selectLogoutProfile(fileConfig.Profiles) if err != nil { return err } if selectedProfile == "" { fmt.Println("Logout canceled") return nil } profileName = selectedProfile activeProfile = fileConfig.Profiles[profileName] } if !confirmLogout(profileName, activeProfile.URL) { fmt.Println("Logout canceled") return nil } delete(fileConfig.Profiles, profileName) newDefaultProfile := "" switch len(fileConfig.Profiles) { case 0: fileConfig.DefaultProfile = "" case 1: for name := range fileConfig.Profiles { fileConfig.DefaultProfile = name newDefaultProfile = name } default: fmt.Println("Select a new default profile:") _m, err := tea.NewProgram(defaultprofile.New(fileConfig.Profiles)).Run() if err != nil { return fmt.Errorf("error selecting new default profile: %w", err) } m := _m.(defaultprofile.Model) if m.Success { fileConfig.DefaultProfile = m.Choice newDefaultProfile = m.Choice } else { fileConfig.DefaultProfile = "" } } if err := config.WriteConfigToFile(fileConfig); err != nil { return fmt.Errorf("failed to update config: %w", err) } fmt.Printf("Logged out and removed profile '%s'\n", profileName) if newDefaultProfile != "" { fmt.Printf("'%s' is now set as the default profile\n", newDefaultProfile) } return nil }, }
var PromqlCmd = &cobra.Command{
Use: "promql",
Short: "PromQL queries and metrics exploration",
Long: "\nRun PromQL queries and explore metrics stored in a Parseable metrics stream.",
Example: " pb promql run -i\n pb promql run \"http_requests_total\" --dataset otel_metrics --from=1h -i",
}
PromqlCmd is the parent command for all PromQL operations.
var QueryCmd = query
var RemoveDatasetCmd = &cobra.Command{ Use: "remove dataset-name", Aliases: []string{"rm"}, Example: " pb dataset remove backend_logs\n pb dataset remove backend_logs --type logs", Short: "Delete a dataset", Args: cobra.ExactArgs(1), SilenceUsage: true, RunE: func(cmd *cobra.Command, args []string) error { startTime := time.Now() cmd.Annotations = make(map[string]string) defer func() { cmd.Annotations["executionTime"] = time.Since(startTime).String() }() name := args[0] client := internalHTTP.DefaultClient(&DefaultProfile) expectedType, err := cmd.Flags().GetString(datasetTypeFlag) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error: %s", err.Error()) return err } expectedType = strings.ToLower(strings.TrimSpace(expectedType)) if expectedType != "" { expectedType, err = validateDatasetType(expectedType) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error: %s", err.Error()) return err } actualType, err := fetchInfo(&client, name) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error: %s", err.Error()) return err } if err := ensureDatasetType(name, actualType, expectedType); err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error: %s", err.Error()) return err } } req, err := client.NewRequest("DELETE", "logstream/"+name, nil) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error: %s", err.Error()) return err } resp, err := client.Client.Do(req) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error: %s", err.Error()) return err } cmd.Annotations["executionTime"] = time.Since(startTime).String() if resp.StatusCode == 200 { fmt.Printf("Successfully deleted dataset %s\n", StyleBold.Render(name)) } else { bytes, err := io.ReadAll(resp.Body) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error: %s", err.Error()) return err } body := string(bytes) defer resp.Body.Close() fmt.Printf("Request Failed\nStatus Code: %s\nResponse: %s\n", resp.Status, body) } return nil }, }
var RemoveProfileCmd = &cobra.Command{ Use: "remove profile-name", Aliases: []string{"rm"}, Example: " pb profile remove local_parseable", Args: cobra.ExactArgs(1), Short: "Delete a profile", RunE: func(cmd *cobra.Command, args []string) error { if cmd.Annotations == nil { cmd.Annotations = make(map[string]string) } startTime := time.Now() name := args[0] fileConfig, err := config.ReadConfigFromFile() if err != nil { cmd.Annotations["error"] = fmt.Sprintf("error reading config: %s", err) return err } _, exists := fileConfig.Profiles[name] if !exists { msg := fmt.Sprintf("No profile found with the name: %s", name) cmd.Annotations["error"] = msg fmt.Println(msg) return nil } wasDefault := fileConfig.DefaultProfile == name delete(fileConfig.Profiles, name) if wasDefault { switch len(fileConfig.Profiles) { case 0: fileConfig.DefaultProfile = "" case 1: for k := range fileConfig.Profiles { fileConfig.DefaultProfile = k fmt.Printf("'%s' is now set as the default profile\n", k) } default: fmt.Println("Select a new default profile:") _m, err := tea.NewProgram(defaultprofile.New(fileConfig.Profiles)).Run() if err != nil { return fmt.Errorf("error selecting new default profile: %w", err) } m := _m.(defaultprofile.Model) if m.Success { fileConfig.DefaultProfile = m.Choice fmt.Printf("'%s' is now set as the default profile\n", m.Choice) } else { fileConfig.DefaultProfile = "" } } } commandError := config.WriteConfigToFile(fileConfig) cmd.Annotations["executionTime"] = time.Since(startTime).String() if commandError != nil { cmd.Annotations["error"] = commandError.Error() return commandError } if outputFormat == "json" { return outputResult(fmt.Sprintf("Deleted profile %s", name)) } fmt.Printf("Deleted profile %s\n", name) return nil }, }
var RemoveRoleCmd = &cobra.Command{ Use: "remove role-name", Aliases: []string{"rm"}, Example: " pb role remove ingestor", Short: "Delete a role", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { startTime := time.Now() cmd.Annotations = make(map[string]string) defer func() { cmd.Annotations["executionTime"] = time.Since(startTime).String() }() name := args[0] client := internalHTTP.DefaultClient(&DefaultProfile) req, err := client.NewRequest("DELETE", "role/"+name, nil) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error creating delete request: %s", err.Error()) return err } resp, err := client.Client.Do(req) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error performing delete request: %s", err.Error()) return err } defer resp.Body.Close() if resp.StatusCode == 200 { fmt.Printf("Removed role %s\n", StyleBold.Render(name)) } else { bodyBytes, err := io.ReadAll(resp.Body) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error reading response: %s", err.Error()) return err } body := string(bodyBytes) cmd.Annotations["errors"] = fmt.Sprintf("Request failed - Status: %s, Response: %s", resp.Status, body) fmt.Printf("Request Failed\nStatus Code: %s\nResponse: %s\n", resp.Status, body) } return nil }, }
var RemoveUserCmd = &cobra.Command{ Use: "remove user-name", Aliases: []string{"rm"}, Example: " pb user remove bob", Short: "Delete a user", Args: cobra.ExactArgs(1), RunE: func(cmd *cobra.Command, args []string) error { startTime := time.Now() cmd.Annotations = make(map[string]string) defer func() { cmd.Annotations["executionTime"] = time.Since(startTime).String() }() name := args[0] client := internalHTTP.DefaultClient(&DefaultProfile) req, err := client.NewRequest("DELETE", "user/"+name, nil) if err != nil { cmd.Annotations["error"] = err.Error() return err } resp, err := client.Client.Do(req) if err != nil { cmd.Annotations["error"] = err.Error() return err } if resp.StatusCode == 200 { fmt.Printf("Removed user %s\n", StyleBold.Render(name)) cmd.Annotations["error"] = "none" } else { body, _ := io.ReadAll(resp.Body) fmt.Printf("Request Failed\nStatus Code: %s\nResponse: %s\n", resp.Status, string(body)) cmd.Annotations["error"] = fmt.Sprintf("request failed with status code %s", resp.Status) } return nil }, }
var SaveSQLCmd = &cobra.Command{ Use: "save [query]", Example: " pb sql save 'select * from frontend'\n pb sql save \"select * from frontend\" --name frontend-errors --from=1h --to=now", Short: "Save SQL query", Long: "\nSave a SQL query without running it.", Args: cobra.ExactArgs(1), SilenceUsage: true, PreRunE: PreRunDefaultProfile, RunE: func(command *cobra.Command, args []string) error { startTime := time.Now() command.Annotations = map[string]string{ "startTime": startTime.Format(time.RFC3339), } defer func() { command.Annotations["executionTime"] = time.Since(startTime).String() }() sqlQuery := strings.TrimSpace(args[0]) if sqlQuery == "" { fmt.Println("Please enter your query") fmt.Printf("Example:\n pb sql save \"select * from frontend\"\n") return nil } start, err := command.Flags().GetString(startFlag) if err != nil { command.Annotations["error"] = err.Error() return err } if start == "" { start = defaultStart } end, err := command.Flags().GetString(endFlag) if err != nil { command.Annotations["error"] = err.Error() return err } if end == "" { end = defaultEnd } sqlQuery = quoteStreamNames(sqlQuery) sqlQuery = quoteFieldsWithDots(sqlQuery) sqlQuery = ensureDefaultLimit(sqlQuery) name := strings.TrimSpace(sqlSaveName) if name == "" { name = defaultSavedQueryName(sqlQuery) } client := internalHTTP.DefaultClient(&DefaultProfile) if err := saveFilter(&client, sqlQuery, name, start, end); err != nil { command.Annotations["error"] = err.Error() return err } fmt.Printf("Query saved as '%s'\n", name) command.Annotations["error"] = "none" return nil }, }
var SavedQueryList = &cobra.Command{ Use: "list", Aliases: []string{"ls"}, Example: "pb sql list [-o | --output]", Short: "List of saved queries", Long: "\nShow the list of saved queries for active user", SilenceUsage: true, PreRunE: PreRunDefaultProfile, RunE: func(_ *cobra.Command, _ []string) error { client := internalHTTP.DefaultClient(&DefaultProfile) if outputFlag != "" { userConfig, err := config.ReadConfigFromFile() if err != nil { fmt.Println("Error reading Default Profile") } var userProfile config.Profile if profile, ok := userConfig.Profiles[userConfig.DefaultProfile]; ok { userProfile = profile } client := &http.Client{ Timeout: time.Second * 60, } userSavedQueries := fetchFilters(client, &userProfile) // Collect all filter titles in a slice and join with commas var filterDetails []string if outputFlag == "json" { jsonOutput, err := json.MarshalIndent(userSavedQueries, "", " ") if err != nil { fmt.Println("Error converting saved queries to JSON:", err) return err } if string(jsonOutput) == "null" { fmt.Println("[]") return nil } fmt.Println(string(jsonOutput)) } else { for _, query := range userSavedQueries { // Build the line conditionally var parts []string if query.Title != "" { parts = append(parts, query.Title) } if query.Stream != "" { parts = append(parts, query.Stream) } if query.Desc != "" { parts = append(parts, query.Desc) } if query.From != "" { parts = append(parts, query.From) } if query.To != "" { parts = append(parts, query.To) } fmt.Println(strings.Join(parts, ", ")) } } fmt.Println(strings.Join(filterDetails, " ")) return nil } p := model.SavedQueriesMenu() if _, err := p.Run(); err != nil { return err } a := model.QueryToApply() d := model.QueryToDelete() if a.SavedQueryID() != "" || strings.TrimSpace(a.Stream()) != "" { if err := savedQueryToPbQuery(a.Stream(), a.StartTime(), a.EndTime()); err != nil { return err } } if d.SavedQueryID() != "" { deleteSavedQuery(&client, d.SavedQueryID(), d.Title()) } return nil }, }
var SetUserRoleCmd = &cobra.Command{ Use: "set-role user-name roles", Short: "Set roles for a user", Example: " pb user set-role bob admin,developer", PreRunE: func(_ *cobra.Command, args []string) error { if len(args) < 2 { return fmt.Errorf("requires at least 2 arguments") } return nil }, RunE: func(cmd *cobra.Command, args []string) error { startTime := time.Now() cmd.Annotations = make(map[string]string) defer func() { cmd.Annotations["executionTime"] = time.Since(startTime).String() }() name := args[0] client := internalHTTP.DefaultClient(&DefaultProfile) users, err := fetchUsers(&client) if err != nil { cmd.Annotations["error"] = err.Error() return err } if !slices.ContainsFunc(users, func(user UserData) bool { return user.ID == name }) { fmt.Printf("user doesn't exist. Please create the user with `pb user add %s`\n", name) cmd.Annotations["error"] = "user does not exist" return nil } rolesToSet := args[1] rolesToSetArr := strings.Split(rolesToSet, ",") var rolesOnServer []string if err := fetchRoles(&client, &rolesOnServer); err != nil { cmd.Annotations["error"] = err.Error() return err } rolesOnServerArr := strings.Join(rolesOnServer, " ") for idx, role := range rolesToSetArr { rolesToSetArr[idx] = strings.TrimSpace(role) if !strings.Contains(rolesOnServerArr, rolesToSetArr[idx]) { fmt.Printf("role %s doesn't exist, please create a role using `pb role add %s`\n", rolesToSetArr[idx], rolesToSetArr[idx]) cmd.Annotations["error"] = fmt.Sprintf("role %s doesn't exist", rolesToSetArr[idx]) return nil } } var putBody io.Reader putBodyJSON, _ := json.Marshal(rolesToSetArr) putBody = bytes.NewBuffer([]byte(putBodyJSON)) req, err := client.NewRequest("PUT", "user/"+name+"/role", putBody) if err != nil { cmd.Annotations["error"] = err.Error() return err } resp, err := client.Client.Do(req) if err != nil { cmd.Annotations["error"] = err.Error() return err } bytes, err := io.ReadAll(resp.Body) if err != nil { cmd.Annotations["error"] = err.Error() return err } body := string(bytes) defer resp.Body.Close() if resp.StatusCode == 200 { fmt.Printf("Added role(s) %s to user %s\n", rolesToSet, name) cmd.Annotations["error"] = "none" } else { fmt.Printf("Request Failed\nStatus Code: %s\nResponse: %s\n", resp.Status, body) cmd.Annotations["error"] = fmt.Sprintf("request failed with status code %s", resp.Status) } return nil }, }
var ShowValuesCmd = &cobra.Command{ Use: "show values", Short: "Show values available in Parseable servers", Example: "pb show values", Run: func(_ *cobra.Command, _ []string) { _, err := common.PromptK8sContext() if err != nil { log.Fatalf("Failed to prompt for Kubernetes context: %v", err) } entries, err := common.ReadInstallerConfigMap() if err != nil { log.Fatalf("Failed to list OSS servers: %v", err) } if len(entries) == 0 { fmt.Println("No OSS servers found.") return } selectedCluster, err := common.PromptClusterSelection(entries) if err != nil { log.Fatalf("Failed to select a cluster: %v", err) } values, err := helm.GetReleaseValues(selectedCluster.Name, selectedCluster.Namespace) if err != nil { log.Fatalf("Failed to get values for release: %v", err) } yamlOutput, err := yaml.Marshal(values) if err != nil { log.Fatalf("Failed to marshal values to YAML: %v", err) } fmt.Println(string(yamlOutput)) fmt.Printf("\nTo get secret values of the Parseable cluster, run the following command:\n") fmt.Printf("kubectl get secret -n %s parseable-env-secret -o jsonpath='{.data}' | jq -r 'to_entries[] | \"\\(.key): \\(.value | @base64d)\"'\n", selectedCluster.Namespace) }, }
ShowValuesCmd lists the Parseable OSS servers
var StatDatasetCmd = &cobra.Command{ Use: "info dataset-name", Aliases: []string{"stat"}, Example: " pb dataset info backend_logs", Short: "Get statistics for a dataset", Args: cobra.ExactArgs(1), SilenceUsage: true, RunE: func(cmd *cobra.Command, args []string) error { startTime := time.Now() cmd.Annotations = make(map[string]string) defer func() { cmd.Annotations["executionTime"] = time.Since(startTime).String() }() name := args[0] client := internalHTTP.DefaultClient(&DefaultProfile) datasetType, err := fetchInfo(&client, name) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error: %s", err.Error()) return err } stats, err := fetchStats(&client, name) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error: %s", err.Error()) return err } ingestionCount := stats.Ingestion.Count ingestionSize := stats.Ingestion.Size storageSize := stats.Storage.Size var compressionRatio float64 if ingestionSize > 0 { compressionRatio = 100 - (float64(storageSize) / float64(ingestionSize) * 100) } retention, err := fetchRetention(&client, name) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error: %s", err.Error()) return err } alertsData, err := fetchAlerts(&client, name) if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error: %s", err.Error()) return err } output, _ := cmd.Flags().GetString("output") if output == "json" { data := map[string]interface{}{ "info": map[string]interface{}{ "event_count": ingestionCount, "ingestion_size": humanize.Bytes(uint64(ingestionSize)), "storage_size": humanize.Bytes(uint64(storageSize)), "compression_ratio": fmt.Sprintf("%.2f%%", compressionRatio), }, "retention": retention, "alerts": alertsData.Alerts, "dataset_type": datasetType, } jsonData, err := json.MarshalIndent(data, "", " ") if err != nil { cmd.Annotations["errors"] = fmt.Sprintf("Error: %s", err.Error()) return err } fmt.Println(string(jsonData)) } else { isRetentionSet := len(retention) > 0 isAlertsSet := len(alertsData.Alerts) > 0 fmt.Println(SelectedStyle.Render("\nInfo:")) fmt.Printf(" %-18s %d\n", "Event Count:", ingestionCount) fmt.Printf(" %-18s %s\n", "Ingestion Size:", humanize.Bytes(uint64(ingestionSize))) fmt.Printf(" %-18s %s\n", "Storage Size:", humanize.Bytes(uint64(storageSize))) fmt.Printf(" %-18s %.2f%s\n", "Compression Ratio:", compressionRatio, "%") fmt.Printf(" %-18s %s\n", "Dataset Type:", SelectedStyle.Render(datasetType)) fmt.Println() if isRetentionSet { fmt.Println(SelectedStyle.Render("Retention:")) for _, item := range retention { fmt.Printf(" Action: %s\n", StyleBold.Render(item.Action)) fmt.Printf(" Duration: %s\n", StyleBold.Render(item.Duration)) fmt.Println() } } else { fmt.Println(SelectedStyle.Render("No retention period set on dataset\n")) } if isAlertsSet { fmt.Println(SelectedStyle.Render("Alerts:")) for _, alert := range alertsData.Alerts { fmt.Printf(" Alert: %s\n", StyleBold.Render(alert.Name)) ruleFmt := fmt.Sprintf( "%s %s %s repeated %d times", alert.Rule.Config.Column, alert.Rule.Config.Operator, fmt.Sprint(alert.Rule.Config.Value), alert.Rule.Config.Repeats, ) fmt.Printf(" Rule: %s\n", ruleFmt) fmt.Printf(" Targets: ") for _, target := range alert.Targets { fmt.Printf("%s, ", target.Type) } fmt.Print("\n\n") } } else { fmt.Println(SelectedStyle.Render("No alerts set on dataset\n")) } } return nil }, }
StatDatasetCmd is the stat command for dataset
var StatusCmd = &cobra.Command{ Use: "status", Short: "Check connection status for the active profile", Example: " pb status", RunE: func(_ *cobra.Command, _ []string) error { fileConfig, err := config.ReadConfigFromFile() if err != nil { return fmt.Errorf("no profile configured. run: pb login") } profileName := fileConfig.DefaultProfile profile, exists := fileConfig.Profiles[profileName] if !exists || profileName == "" { return fmt.Errorf("no active profile. run: pb login") } fmt.Printf("Profile : %s\n", profileName) fmt.Printf("URL : %s\n", profile.URL) client := internalHTTP.DefaultClient(&profile) about, err := analytics.FetchAbout(&client) if err != nil { statusMessage := statusErrorMessage(err) errStyle := lipgloss.NewStyle().Foreground(ui.Active.Err).Bold(true) fmt.Printf("Status : %s\n", errStyle.Render("✗ Not connected")) fmt.Printf("Error : %s\n", statusMessage) return fmt.Errorf("status check failed: %s", statusMessage) } okStyle := lipgloss.NewStyle().Foreground(ui.Active.Ok).Bold(true) fmt.Printf("Status : %s\n", okStyle.Render("✓ Connected")) fmt.Printf("Version : %s\n", about.Version) return nil }, }
var TailCmd = &cobra.Command{ Use: "tail dataset-name", Example: " pb tail backend_logs", Short: "Stream live events from a dataset", Args: cobra.ExactArgs(1), PreRunE: PreRunDefaultProfile, RunE: func(_ *cobra.Command, args []string) error { name := args[0] profile := DefaultProfile return tail(profile, name) }, }
var UninstallOssCmd = &cobra.Command{ Use: "uninstall", Short: "Uninstall Parseable servers", Example: "pb uninstall", Run: func(_ *cobra.Command, _ []string) { _, err := common.PromptK8sContext() if err != nil { log.Fatalf("Failed to prompt for Kubernetes context: %v", err) } entries, err := common.ReadInstallerConfigMap() if err != nil { log.Fatalf("Failed to fetch OSS servers: %v", err) } if len(entries) == 0 { fmt.Println(common.Yellow + "\nNo Parseable OSS servers found to uninstall.") return } selectedCluster, err := common.PromptClusterSelection(entries) if err != nil { log.Fatalf("Failed to select a cluster: %v", err) } fmt.Println("\n────────────────────────────────────────────────────────────────────────────") fmt.Println("⚠️ Deleting this cluster will not delete any data on object storage.") fmt.Println(" This operation will clean up the Parseable deployment on Kubernetes.") fmt.Println("────────────────────────────────────────────────────────────────────────────") fmt.Printf("\nYou have selected to uninstall the cluster '%s' in namespace '%s'.\n", selectedCluster.Name, selectedCluster.Namespace) if !common.PromptConfirmation(fmt.Sprintf("Do you want to proceed with uninstalling '%s'?", selectedCluster.Name)) { fmt.Println(common.Yellow + "Uninstall operation canceled.") return } if err := uninstallCluster(selectedCluster); err != nil { log.Fatalf("Failed to uninstall cluster: %v", err) } if err := common.RemoveInstallerEntry(selectedCluster.Name); err != nil { log.Fatalf("Failed to remove entry from ConfigMap: %v", err) } if err := deleteSecret(selectedCluster.Namespace, "parseable-env-secret"); err != nil { log.Printf("Warning: Failed to delete secret 'parseable-env-secret': %v", err) } else { fmt.Println(common.Green + "Secret 'parseable-env-secret' deleted successfully." + common.Reset) } fmt.Println(common.Green + "Uninstallation completed successfully." + common.Reset) }, }
UninstallOssCmd removes Parseable OSS servers
var UpdateProfileCmd = &cobra.Command{ Use: "update profile-name new-url", Aliases: []string{"set-url"}, Example: " pb profile update local http://localhost:9000", Short: "Update the URL of an existing profile", Args: cobra.ExactArgs(2), RunE: func(cmd *cobra.Command, args []string) error { if cmd.Annotations == nil { cmd.Annotations = make(map[string]string) } startTime := time.Now() name := args[0] rawURL := args[1] if _, err := url.Parse(rawURL); err != nil { return fmt.Errorf("invalid URL: %w", err) } fileConfig, err := config.ReadConfigFromFile() if err != nil { return fmt.Errorf("error reading config: %w", err) } profile, exists := fileConfig.Profiles[name] if !exists { return fmt.Errorf("no profile found with the name: %s", name) } profile.URL = rawURL fileConfig.Profiles[name] = profile commandError := config.WriteConfigToFile(fileConfig) cmd.Annotations["executionTime"] = time.Since(startTime).String() if commandError != nil { cmd.Annotations["error"] = commandError.Error() return commandError } if outputFormat == "json" { return outputResult(profile) } fmt.Printf("Profile '%s' URL updated to %s\n", name, rawURL) return nil }, }
var VersionCmd = &cobra.Command{ Use: "version", Short: "Print version", Long: "Print version and commit information", Example: " pb version", Run: func(cmd *cobra.Command, _ []string) { if cmd.Annotations == nil { cmd.Annotations = make(map[string]string) } startTime := time.Now() defer func() { cmd.Annotations["executionTime"] = time.Since(startTime).String() }() err := PrintVersion("1.0.0", "abc123") if err != nil { cmd.Annotations["error"] = err.Error() } }, }
VersionCmd is the command for printing version information
Functions ¶
func PreRunDefaultProfile ¶
PreRunDefaultProfile if a profile exists. This is required by mostly all commands except profile
func PrintVersion ¶
PrintVersion prints version information
Types ¶
type Alert ¶
type Alert struct {
Targets []Target `json:"targets"`
Name string `json:"name"`
Message string `json:"message"`
Rule Rule `json:"rule"`
}
Alert structure
type AlertConfig ¶
AlertConfig structure
type DatasetListItem ¶
func (*DatasetListItem) Render ¶
func (item *DatasetListItem) Render() string
type DatasetRetentionData ¶
type DatasetRetentionData []struct {
Description string `json:"description"`
Action string `json:"action"`
Duration string `json:"duration"`
}
DatasetRetentionData is the data structure for dataset retention
type DatasetStatsData ¶
type DatasetStatsData struct {
Ingestion struct {
Count int `json:"count"`
Format string `json:"format"`
Size uint64 `json:"size"`
} `json:"ingestion"`
Storage struct {
Format string `json:"format"`
Size uint64 `json:"size"`
} `json:"storage"`
Stream string `json:"stream"`
Time time.Time `json:"time"`
}
DatasetStatsData is the data structure for dataset stats
type ProfileListItem ¶
type ProfileListItem struct {
// contains filtered or unexported fields
}
ProfileListItem is a struct to hold the profile list items
func (*ProfileListItem) Render ¶
func (item *ProfileListItem) Render(highlight bool) string
type RoleData ¶
type RoleData struct {
Privilege string `json:"privilege"`
Resource *RoleResource `json:"resource,omitempty"`
}
type RoleResource ¶
type RoleResource struct {
Stream string `json:"stream,omitempty"`
}
type Rule ¶
type Rule struct {
Type string `json:"type"`
Config RuleConfig `json:"config"`
}
Rule structure
type RuleConfig ¶
type RuleConfig struct {
Column string `json:"column"`
Operator string `json:"operator"`
IgnoreCase bool `json:"ignoreCase"`
Value interface{} `json:"value"`
Repeats int `json:"repeats"`
}
RuleConfig structure
type Target ¶
type Target struct {
Type string `json:"type"`
Endpoint string `json:"endpoint"`
Headers map[string]string `json:"headers"`
SkipTLSCheck bool `json:"skip_tls_check"`
Repeat Repeat `json:"repeat"`
}
Target structure
type UserRoleAction ¶
type UserRoleAction struct {
Privilege string `json:"privilege"`
Resource *RoleResource `json:"resource,omitempty"`
}
UserRoleAction is a single privilege entry within a named role
type UserRolesResponse ¶
type UserRolesResponse struct {
DirectRoles map[string]UserServerRole `json:"roles"`
GroupRoles map[string]map[string]UserServerRole `json:"group_roles"`
}
UserRolesResponse is the response from GET /user/{name}/role
type UserServerRole ¶
type UserServerRole struct {
Actions []UserRoleAction `json:"actions"`
}
UserServerRole is a named role definition returned by the server