Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

✨ tailscale provider #5214

Merged
merged 11 commits into from
Feb 18, 2025
Merged

✨ tailscale provider #5214

merged 11 commits into from
Feb 18, 2025

Conversation

afiune
Copy link
Contributor

@afiune afiune commented Feb 13, 2025

✨ Tailscale Provider

Use the tailscale provider to query devices, users, DNS namespaces, and more information about a Tailscale network,
known as a tailnet.

To authenticate using an API access token:

cnquery shell tailscale --token <access-token>

To authenticate using an OAuth client:

cnquery shell tailscale --client-id <id> --client-secret <secret>

You can also use the default environment variables TAILSCALE_OAUTH_CLIENT_ID, TAILSCALE_OAUTH_CLIENT_SECRET,
and TAILSCALE_TAILNET to provide your credentials.

If you are using an API access token instead of an OAuth client, use the TAILSCALE_API_KEY variable instead.

Examples

List all devices in a tailnet

cnquery> tailscale.devices()

Get information on a single device

cnquery> tailscale.device(id: "55161288425123456") {*}
tailscale.device: {
  id: "55161288425123456"
  isExternal: false
  os: "linux"
  created: 2021-06-25 12:34:34 -0700 PDT
  updateAvailable: true
  nodeKey: "nodekey:abc123"
  lastSeen: 2024-03-25 08:01:04 -0700 PDT
  user: "afiune@mondoo.com"
  hostname: "raspberrypi"
  clientVersion: "1.10.0-t766ae6c10-g3e6822772"
  authorized: true
  blocksIncomingConnections: false
  addresses: [
    0: "100.71.181.41"
    1: "abc1:abc1:a1e0:ab12:abc1:cd96:abc1:bf33"
  ]
  keyExpiryDisabled: true
  expires: 2022-08-02 18:55:39 -0700 PDT
  name: "raspberrypi.tail1a4a6.ts.net"
  machineKey: "mkey:abc123"
  tailnetLockKey: ""
  tailnetLockError: ""
}

List all users in a tailnet

cnquery> tailscale.users()

Get information on a single user

cnquery> tailscale.user(id: "uiR4AD141DAA") {*}
tailscale.user: {
  id: "uiR4AD141DAA"
  type: "member"
  deviceCount: 64
  createdAt: 2021-06-24 11:17:02.151878675 -0700 PDT
  loginName: "afiune@mondoo.com"
  status: "active"
  lastSeenAt: 2025-02-18 13:56:23.715800061 -0800 PST
  tailnetId: "12345678900012344"
  profilePicUrl: "https://lh3.googleusercontent.com/a/ACg8ocKPxpFdO4al-Si9YXhJz_iN9qnZ-8h5UorbQrKWxrS-uPutP6E=s96-c"
  role: "owner"
  displayName: "Salim Afiune Maya"
}

Advanced usage

Discover all devices (any computer or mobile device) that join the tailnet example.com

cnquery shell tailscale example.com --discover devices

This comment has been minimized.

Copy link
Contributor

github-actions bot commented Feb 13, 2025

Test Results

3 335 tests  ±0   3 331 ✅ ±0   1m 39s ⏱️ -14s
  391 suites +6       4 💤 ±0 
   30 files   +1       0 ❌ ±0 

Results for commit 175517d. ± Comparison against base commit 097be40.

♻️ This comment has been updated with latest results.

This comment has been minimized.

This comment has been minimized.

This comment has been minimized.

Use the tailscale provider to query devices, DNS namespaces, and more information about a Tailscale network
known as `tailnet`.

To authenticate using an API access token:

```
cnquery shell tailscale --token <access-token>
```

To authenticate using an OAuth client:

```
cnquery shell tailscale --client-id <id> --client-secret <secret>
```

You can also use the default environment variables `TAILSCALE_OAUTH_CLIENT_ID`, `TAILSCALE_OAUTH_CLIENT_SECRET`,
and `TAILSCALE_TAILNET` to provide your credentials.

If you are using an API access token instead of an OAuth client, use the `TAILSCALE_API_KEY` variable instead.

Examples

**List all devices in a tailnet**

```shell
cnquery> tailscale.devices()
```

**Show a single device information**

```shell
cnquery> tailscale.device(id: "55161288425123456") {*}
tailscale.device: {
  id: "55161288425123456"
  isExternal: false
  os: "linux"
  created: 2021-06-25 12:34:34 -0700 PDT
  updateAvailable: true
  nodeKey: "nodekey:abc123"
  lastSeen: 2024-03-25 08:01:04 -0700 PDT
  user: "afiune@mondoo.com"
  hostname: "raspberrypi"
  clientVersion: "1.10.0-t766ae6c10-g3e6822772"
  authorized: true
  blocksIncomingConnections: false
  addresses: [
    0: "100.71.181.41"
    1: "abc1:abc1:a1e0:ab12:abc1:cd96:abc1:bf33"
  ]
  keyExpiryDisabled: true
  expires: 2022-08-02 18:55:39 -0700 PDT
  name: "raspberrypi.tail1a4a6.ts.net"
  machineKey: "mkey:abc123"
  tailnetLockKey: ""
  tailnetLockError: ""
}
```

Advanced Usage

Discover all devices (any computer or mobile device) that joins the tailnet `example.com`.

```shell
cnquery shell tailscale example.com --discover devices
```

Signed-off-by: Salim Afiune Maya <afiune@mondoo.com>

This comment has been minimized.

Copy link
Member

@chris-rock chris-rock left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@afiune Great first version for the tailscale provider! I added a few comments that we should address before we can merge it. Its close!

option provider = "go.mondoo.com/cnquery/v11/providers/tailscale"
option go_package = "go.mondoo.com/cnquery/v11/providers/tailscale/resources"

// The Tailscale provider
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this represents the tailscale organization

conf := conn.Asset().Connections[0]
assetList := []*inventory.Asset{}

cf, err := getMqlTailscale(runtime)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we want also discover the root asset (org/tailnet).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think we can fetch this information.

@chris-rock chris-rock self-requested a review February 14, 2025 11:19
Signed-off-by: Salim Afiune Maya <afiune@mondoo.com>
Signed-off-by: Salim Afiune Maya <afiune@mondoo.com>

This comment has been minimized.

This comment has been minimized.

Signed-off-by: Salim Afiune Maya <afiune@mondoo.com>
Signed-off-by: Salim Afiune Maya <afiune@mondoo.com>
Signed-off-by: Salim Afiune Maya <afiune@mondoo.com>
Signed-off-by: Salim Afiune Maya <afiune@mondoo.com>
Signed-off-by: Salim Afiune Maya <afiune@mondoo.com>
Signed-off-by: Salim Afiune Maya <afiune@mondoo.com>

This comment has been minimized.

Copy link
Contributor

@misterpantz misterpantz left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Really good docs in this PR, as always, superstar! I made some suggestions. On some of them you'll find question marks where I wasn't 100% confident. 😁

// The time the user joined their tailnet
createdAt time
// This time can be either:
// a) The last time any of the user's nodes were connected to the network
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
// a) The last time any of the user's nodes were connected to the network
// a) The last time any of the user's nodes were connected to the network
// or

}
}

func (s *Service) ParseCLI(req *plugin.ParseCLIReq) (*plugin.ParseCLIRes, error) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Using an empty token does not throw an error in the initial phase:

echo $TAILSCALE_API_KEY

cnquery shell tailscale --token $TAILSCALE_API_KEY --discover devices
→ tailscale> authentication configured method=token
→ connected to Tailscale
  ___ _ __   __ _ _   _  ___ _ __ _   _ 
 / __| '_ \ / _` | | | |/ _ \ '__| | | |
| (__| | | | (_| | |_| |  __/ |  | |_| |
 \___|_| |_|\__, |\__,_|\___|_|   \__, |
  mondoo™      |_|                |___/  interactive shell

cnquery> tailscale
tailscale: tailscale id = devices
cnquery> tailscale.devices
API token invalid (401)
tailscale.devices: no data available

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I will add a verify step to fail fast, just like we do with the GitHub provider, good call! 💯

Co-authored-by: Letha <letha@mondoo.com>

This comment has been minimized.

Signed-off-by: Salim Afiune Maya <afiune@mondoo.com>
@afiune afiune requested review from misterpantz and tas50 February 18, 2025 22:06
@afiune
Copy link
Contributor Author

afiune commented Feb 18, 2025

Let's go!!!!

@chris-rock chris-rock merged commit f6fb570 into main Feb 18, 2025
17 checks passed
@chris-rock chris-rock deleted the afiune/tailscale branch February 18, 2025 22:14
@github-actions github-actions bot locked and limited conversation to collaborators Feb 18, 2025
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants