zscaler / zscaler-sdk-go

Zscaler SDK for Golang (ZPA/ZIA/ZDX/ZCC APIs)
https://zscaler.com
MIT License
9 stars 1 forks source link

Support z queries in the ZDX > Reports > Users > GetUsersFilters struct #260

Closed bosatsu closed 1 month ago

bosatsu commented 2 months ago

Current zscaler-sdk-go version

2.61.0

Description

The documentation for the ZDX REST API shows that the reports /users endpoint accepts a q string query for a username or email address: https://help.zscaler.com/zdx/reports#/users-get, however this doesn't seem to be available in the GetUsersFilters struct: https://github.com/zscaler/zscaler-sdk-go/blob/master/zdx/services/reports/users/types.go#L3.

Use cases

The ability to fetch a user's UserID given their username or email as understood by ZDX.

Potential zscaler-sdk-go usage

type GetUsersFilters struct {
    // The start time (in seconds) for the query. The value is entered in Unix Epoch. If not entered, returns the data for the last 2 hours.
    From int `json:"from,omitempty" url:"from,omitempty"`
    // The end time (in seconds) for the query. The value is entered in Unix Epoch. If not entered, returns the data for the last 2 hours.
    To int `json:"to,omitempty" url:"to,omitempty"`
    // The Zscaler location (ID). You can add multiple location IDs.
    Loc []int `json:"loc,omitempty" url:"loc,omitempty"`
    // The department (ID). You can add multiple department IDs.
    Dept []int `json:"dept,omitempty" url:"dept,omitempty"`
    // The active geolocation (ID). You can add multiple active geolocation IDs.
    Geo []string `json:"geo,omitempty" url:"geo,omitempty"`
    // The next_offset value from the last request. You must enter this value to get the next batch from the list. When the next_offset value becomes null, the list is complete.
    Offset string `json:"offset,omitempty" url:"offset,omitempty"`
    // The number of items that must be returned per request from the list.
    Limit int `json:"limit,omitempty" url:"limit,omitempty"`
    // Search for a user name or email. The search results include active users for the first 1000 matches.
    Q string `json:"q,omitempty" url:"q,omitempty"`
}

func getUser(s *services.Service, username string) users.User {
    zdxUsers, _, err := users.GetAllUsers(s, users.GetUsersFilters{
        Q: username,
    })
}

References

No response

bosatsu commented 2 months ago

@willguibr If there's interest, I'd be happy to submit a pull request for this.

bosatsu commented 2 months ago

For the time being, I've made a work around using the following code, and it returns what I would expect:

func getUser(s *services.Service, username string) []users.User {
    var v struct {
        NextOffSet interface{}  `json:"next_offset"`
        List       []users.User `json:"users"`
    }

    type CustomGetUsersFilters struct {
        // The start time (in seconds) for the query. The value is entered in Unix Epoch. If not entered, returns the data for the last 2 hours.
        From int `json:"from,omitempty" url:"from,omitempty"`
        // The end time (in seconds) for the query. The value is entered in Unix Epoch. If not entered, returns the data for the last 2 hours.
        To int `json:"to,omitempty" url:"to,omitempty"`
        // The Zscaler location (ID). You can add multiple location IDs.
        Loc []int `json:"loc,omitempty" url:"loc,omitempty"`
        // The department (ID). You can add multiple department IDs.
        Dept []int `json:"dept,omitempty" url:"dept,omitempty"`
        // The active geolocation (ID). You can add multiple active geolocation IDs.
        Geo []string `json:"geo,omitempty" url:"geo,omitempty"`
        // The next_offset value from the last request. You must enter this value to get the next batch from the list. When the next_offset value becomes null, the list is complete.
        Offset string `json:"offset,omitempty" url:"offset,omitempty"`
        // The number of items that must be returned per request from the list.
        Limit int `json:"limit,omitempty" url:"limit,omitempty"`
        // Search for a user name or email. The search results include active users for the first 1000 matches.
        Q string `json:"q,omitempty" url:"q,omitempty"`
    }

    _, err := s.Client.NewRequestDo("GET", usersEndpoint, CustomGetUsersFilters{
        Q: username,
    }, nil, &v)

    if err != nil {
        log.Printf("[ERROR] creating config failed %v]n", err)
    }

    return v.List
}

This is run from a main function:

func main() {
    apiKey := os.Getenv("ZDX_API_KEY_ID")
    apiSecret := os.Getenv("ZDX_API_SECRET")
    cfg, err := zdx.NewConfig(apiKey, apiSecret, "userAgent")
    if err != nil {
        log.Printf("[ERROR] creating client failed: %v\n", err)
        return
    }

    client := zdx.NewClient(cfg)
    service := services.New(client)

    email := "user@example.com"

    users := getUser(service, email)
    log.Printf("Users: %v", users)
}

This prints the following: (name and email are made generic, but otherwise this from a live run)

2024/06/20 11:06:06 Users: [{53059464 User Name user@example.com []}]
willguibr commented 1 month ago

Hi @bosatsu Please give it a try with version 2.61.5 Thanks