Skip to content

Commit

Permalink
Merge pull request #16 from kgoins/channels
Browse files Browse the repository at this point in the history
uses channels for concurrent entity processing
  • Loading branch information
kgoins authored Jan 31, 2021
2 parents 51f5d11 + eb4cd6b commit 0fd4292
Show file tree
Hide file tree
Showing 14 changed files with 255 additions and 150 deletions.
19 changes: 12 additions & 7 deletions cmd/count.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ package cmd

import (
"fmt"

"github.com/spf13/cobra"
ldsview "github.com/kgoins/ldsview/pkg"
"github.com/spf13/cobra"
)

// countCmd represents the count command
Expand All @@ -13,18 +12,24 @@ var countCmd = &cobra.Command{
Short: "Counts the number of entities in an ldif file",
Run: func(cmd *cobra.Command, args []string) {
dumpFile, _ := cmd.Flags().GetString("file")

builder := ldsview.NewLdifParser(dumpFile)
count, err := builder.CountEntities()

entities := make(chan ldsview.Entity)
done := make(chan bool)

// Start the printing goroutine
go ChannelPrinter(entities, done, cmd)

err := builder.BuildEntities(entities, done)
if err != nil {
fmt.Printf("%s\n", err.Error())
fmt.Printf("Unable to parse file: %s\n", err.Error())
return
}

fmt.Printf("Entities: %d\n", count)
},
}

func init() {
rootCmd.AddCommand(countCmd)
countCmd.Flags().Bool( "count", true, "" )
countCmd.Flags().MarkHidden("count")
}
6 changes: 1 addition & 5 deletions cmd/entity.go
Original file line number Diff line number Diff line change
Expand Up @@ -78,11 +78,7 @@ func execEntityCmd(ldifParser ldsview.LdifParser, keyAttr string, keyValue strin
return
}

if parseTdc {
entity.DeocdeTimestamps()
}

PrintEntity(entity)
PrintEntity(entity, parseTdc)
}

func init() {
Expand Down
36 changes: 7 additions & 29 deletions cmd/search.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,50 +27,28 @@ Example:
--> matches all computer objects with a hostname containing "net"`,
Run: func(cmd *cobra.Command, args []string) {
dumpFile, _ := cmd.Flags().GetString("file")

builder := ldsview.NewLdifParser(dumpFile)

filter, err := buildEntityFilter(cmd, args)
if err != nil {
fmt.Printf("Unable to parse filter\n")
return
}
builder.SetEntityFilter(filter)

builder.SetEntityFilter(filter)
attrFilter := buildAttrFilter(cmd)
builder.SetAttributeFilter(attrFilter)

count, _ := cmd.Flags().GetBool("count")
if count {
numEntities, _ := builder.CountEntities()
fmt.Printf("Entities: %d\n", numEntities)
return
}
entities := make(chan ldsview.Entity)
done := make(chan bool)

entities, err := builder.BuildEntities()
// Start the printing goroutine
go ChannelPrinter(entities, done, cmd)

err = builder.BuildEntities(entities, done)
if err != nil {
fmt.Printf("Unable to parse file: %s\n", err.Error())
return
}

printLimit, intParseErr := cmd.Flags().GetInt("first")
if intParseErr != nil {
fmt.Printf("Unable to parse value: %s\n", intParseErr.Error())
}

if printLimit != 0 {
entities = entities[:printLimit]
}

tdc, _ := cmd.Flags().GetBool("tdc")

for _, entity := range entities {
if tdc {
entity.DeocdeTimestamps()
}

PrintEntity(entity)
}
},
}

Expand Down
34 changes: 22 additions & 12 deletions cmd/spns.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,8 @@ package cmd

import (
"fmt"

"github.com/spf13/cobra"
ldsview "github.com/kgoins/ldsview/pkg"
"github.com/spf13/cobra"
)

var spnsCmd = &cobra.Command{
Expand All @@ -14,14 +13,14 @@ var spnsCmd = &cobra.Command{
dumpFile, _ := cmd.Flags().GetString("file")
builder := ldsview.NewLdifParser(dumpFile)

filterParts := []string{"servicePrincipalName~:/"}
filterParts := []string{"servicePrincipalName:~/"}

getUsers, _ := cmd.Flags().GetBool("users")
if getUsers {
filterParts = []string{
"objectClass=:user",
"objectClass!=:computer",
"servicePrincipalName~:/",
"objectClass:=user",
"objectClass:!=computer",
"servicePrincipalName:~/",
}
}

Expand All @@ -32,21 +31,32 @@ var spnsCmd = &cobra.Command{
includeFilter := ldsview.BuildAttributeFilter(includeFilterparts)
builder.SetAttributeFilter(includeFilter)

entities, err := builder.BuildEntities()
entities := make(chan ldsview.Entity)
done := make(chan bool)

// Start the printing goroutine
go ChannelPrinter(entities, done, cmd)

err := builder.BuildEntities(entities, done)
if err != nil {
fmt.Println(err)
fmt.Printf("Unable to parse file: %s\n", err.Error())
return
}

for _, entity := range entities {
PrintEntity(entity)
}
},
}

func init() {
rootCmd.AddCommand(spnsCmd)

spnsCmd.PersistentFlags().BoolP("count", "c", false, "")
spnsCmd.PersistentFlags().Int("first", 0, "Print only the first <n> entries")

spnsCmd.PersistentFlags().Bool(
"tdc",
false,
"Decodes timestamps to a human readable format",
)

spnsCmd.PersistentFlags().BoolP(
"users",
"u",
Expand Down
2 changes: 1 addition & 1 deletion cmd/structure.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@ package cmd

import (
"fmt"
"github.com/spf13/cobra"
"sort"

"github.com/spf13/cobra"
ldsview "github.com/kgoins/ldsview/pkg"
)

Expand Down
46 changes: 38 additions & 8 deletions cmd/uac.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,18 +23,32 @@ var uacCmd = &cobra.Command{

shouldSearch, _ := cmd.Flags().GetInt("search")
if shouldSearch != 0 {
file, _ := cmd.Flags().GetString("file")
ldifFile := ldsview.NewLdifParser(file)
entities, err := ldifFile.BuildEntities()
dumpFile, _ := cmd.Flags().GetString("file")
builder := ldsview.NewLdifParser(dumpFile)
filter := []ldsview.IEntityFilter {
ldsview.NewUACFilter(shouldSearch),
}
builder.SetEntityFilter(filter)
attrFilter := buildAttrFilter(cmd)

usedI := cmd.Flags().Changed("include")
if usedI {
// must use AttrFilter if intent is to Match with
// EntityFilter
attrFilter.Add("useraccountcontrol")
}
builder.SetAttributeFilter(attrFilter)

entities := make(chan ldsview.Entity)
done := make(chan bool)

// Start the printing goroutine
go ChannelPrinter(entities, done, cmd)
err := builder.BuildEntities(entities, done)
if err != nil {
cmd.PrintErr("Error while parsing entities: ", err)
return
}

matches := ldsview.UACSearch(&entities, shouldSearch)
for _, match := range matches {
PrintEntity(match)
}
return
}

Expand Down Expand Up @@ -68,4 +82,20 @@ func init() {
0,
"UAC property by which to search",
)

uacCmd.PersistentFlags().BoolP("count", "c", false, "")
uacCmd.PersistentFlags().Int("first", 0, "Print only the first <n> entries")

uacCmd.PersistentFlags().Bool(
"tdc",
false,
"Decodes timestamps to a human readable format",
)

uacCmd.PersistentFlags().StringSliceP(
"include",
"i",
[]string{},
"Select which attributes are displayed from the returned entities",
)
}
41 changes: 38 additions & 3 deletions cmd/ui.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@ package cmd

import (
"fmt"
ldsview "github.com/kgoins/ldsview/pkg"
"github.com/spf13/cobra"
"os"
"sort"

ldsview "github.com/kgoins/ldsview/pkg"
)

func PrintAttribute(attr ldsview.EntityAttribute) {
Expand All @@ -14,7 +14,7 @@ func PrintAttribute(attr ldsview.EntityAttribute) {
}
}

func PrintEntity(entity ldsview.Entity) {
func PrintEntity(entity ldsview.Entity, decodeTS bool) {
titleLine, err := BuildTitleLine(entity)
if err != nil {
os.Stderr.WriteString("Skipping output of malformed object\n")
Expand All @@ -24,6 +24,10 @@ func PrintEntity(entity ldsview.Entity) {

attrNames := entity.GetAllAttributeNames()

if decodeTS {
entity.DeocdeTimestamps()
}

sort.Strings(attrNames)

for _, name := range attrNames {
Expand All @@ -33,3 +37,34 @@ func PrintEntity(entity ldsview.Entity) {

fmt.Println()
}

// ChannelPrinter concurrently prints entity results and signals shared `done` channel
// when finished
func ChannelPrinter(entities chan ldsview.Entity, done chan bool, cmd *cobra.Command ) {

count, _ := cmd.Flags().GetBool("count")
tdc, _ := cmd.Flags().GetBool("tdc")
printLimit, intParseErr := cmd.Flags().GetInt("first")
if intParseErr != nil {
fmt.Printf("Unable to parse value: %s\n", intParseErr.Error())
}

entCount := 0

for entity := range entities {
entCount = entCount + 1

if !count {
PrintEntity(entity, tdc)
}

if entCount == printLimit {
break
}
}

if count {
fmt.Println("Entities: ", entCount)
}
done <- true
}
2 changes: 0 additions & 2 deletions pkg/entity_source.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@ import "github.com/kgoins/ldsview/internal"
// EntitySource returns LDAP Entites constructed from an input data source.
// If filter values are not set, they will default to empty lists. Null values will cause a panic.
type EntitySource interface {
CountEntities() (int, error)

BuildEntity(keyAttrName string, keyAttrVal string) (Entity, error)
BuildEntities() ([]Entity, error)

Expand Down
Loading

0 comments on commit 0fd4292

Please sign in to comment.