@@ -20,27 +20,48 @@ const (
20
20
LogstreamCriblEndpoint LogstreamEndpointType = "cribl"
21
21
LogstreamDatadogEndpoint LogstreamEndpointType = "datadog"
22
22
LogstreamAxiomEndpoint LogstreamEndpointType = "axiom"
23
+ LogstreamS3Endpoint LogstreamEndpointType = "s3"
23
24
)
24
25
25
26
const (
26
27
LogTypeConfig LogType = "configuration"
27
28
LogTypeNetwork LogType = "network"
28
29
)
29
30
31
+ const (
32
+ S3AccessKeyAuthentication S3AuthenticationType = "accesskey"
33
+ S3RoleARNAuthentication S3AuthenticationType = "rolearn"
34
+ )
35
+
30
36
// LogstreamConfiguration type defines a log stream entity in tailscale.
31
37
type LogstreamConfiguration struct {
32
- LogType LogType `json:"logType,omitempty"`
33
- DestinationType LogstreamEndpointType `json:"destinationType,omitempty"`
34
- URL string `json:"url,omitempty"`
35
- User string `json:"user,omitempty"`
38
+ LogType LogType `json:"logType,omitempty"`
39
+ DestinationType LogstreamEndpointType `json:"destinationType,omitempty"`
40
+ URL string `json:"url,omitempty"`
41
+ User string `json:"user,omitempty"`
42
+ S3Bucket string `json:"s3Bucket,omitempty"`
43
+ S3Region string `json:"s3Region,omitempty"`
44
+ S3KeyPrefix string `json:"s3KeyPrefix,omitempty"`
45
+ S3AuthenticationType S3AuthenticationType `json:"s3AuthenticationType,omitempty"`
46
+ S3AccessKeyID string `json:"s3AccessKeyId,omitempty"`
47
+ S3RoleARN string `json:"s3RoleArn,omitempty"`
48
+ S3ExternalID string `json:"s3ExternalId,omitempty"`
36
49
}
37
50
38
51
// SetLogstreamConfigurationRequest type defines a request for setting a LogstreamConfiguration.
39
52
type SetLogstreamConfigurationRequest struct {
40
- DestinationType LogstreamEndpointType `json:"destinationType,omitempty"`
41
- URL string `json:"url,omitempty"`
42
- User string `json:"user,omitempty"`
43
- Token string `json:"token,omitempty"`
53
+ DestinationType LogstreamEndpointType `json:"destinationType,omitempty"`
54
+ URL string `json:"url,omitempty"`
55
+ User string `json:"user,omitempty"`
56
+ Token string `json:"token,omitempty"`
57
+ S3Bucket string `json:"s3Bucket,omitempty"`
58
+ S3Region string `json:"s3Region,omitempty"`
59
+ S3KeyPrefix string `json:"s3KeyPrefix,omitempty"`
60
+ S3AuthenticationType S3AuthenticationType `json:"s3AuthenticationType,omitempty"`
61
+ S3AccessKeyID string `json:"s3AccessKeyId,omitempty"`
62
+ S3SecretAccessKey string `json:"s3SecretAccessKey,omitempty"`
63
+ S3RoleARN string `json:"s3RoleArn,omitempty"`
64
+ S3ExternalID string `json:"s3ExternalId,omitempty"`
44
65
}
45
66
46
67
// LogstreamEndpointType describes the type of the endpoint.
@@ -49,6 +70,9 @@ type LogstreamEndpointType string
49
70
// LogType describes the type of logging.
50
71
type LogType string
51
72
73
+ // S3AuthenticationType describes the type of authentication used to stream logs to a LogstreamS3Endpoint.
74
+ type S3AuthenticationType string
75
+
52
76
// LogstreamConfiguration retrieves the tailnet's [LogstreamConfiguration] for the given [LogType].
53
77
func (lr * LoggingResource ) LogstreamConfiguration (ctx context.Context , logType LogType ) (* LogstreamConfiguration , error ) {
54
78
req , err := lr .buildRequest (ctx , http .MethodGet , lr .buildTailnetURL ("logging" , logType , "stream" ))
@@ -78,3 +102,35 @@ func (lr *LoggingResource) DeleteLogstreamConfiguration(ctx context.Context, log
78
102
79
103
return lr .do (req , nil )
80
104
}
105
+
106
+ // AWSExternalID represents an AWS External ID that Tailscale can use to stream logs from a
107
+ // particular Tailscale AWS account to a LogstreamS3Endpoint that uses S3RoleARNAuthentication.
108
+ type AWSExternalID struct {
109
+ ExternalID string `json:"externalId,omitempty"`
110
+ TailscaleAWSAccountID string `json:"tailscaleAwsAccountId,omitempty"`
111
+ }
112
+
113
+ // CreateOrGetAwsExternalId gets an AWS External ID that Tailscale can use to stream logs to
114
+ // a LogstreamS3Endpoint using S3RoleARNAuthentication, creating a new one for this tailnet
115
+ // when necessary.
116
+ func (lr * LoggingResource ) CreateOrGetAwsExternalId (ctx context.Context , reusable bool ) (* AWSExternalID , error ) {
117
+ req , err := lr .buildRequest (ctx , http .MethodPost , lr .buildTailnetURL ("aws-external-id" ), requestBody (map [string ]bool {
118
+ "reusable" : reusable ,
119
+ }))
120
+ if err != nil {
121
+ return nil , err
122
+ }
123
+ return body [AWSExternalID ](lr , req )
124
+ }
125
+
126
+ // ValidateAWSTrustPolicy validates that Tailscale can assume your AWS IAM role with (and only
127
+ // with) the given AWS External ID.
128
+ func (lr * LoggingResource ) ValidateAWSTrustPolicy (ctx context.Context , awsExternalID string , roleARN string ) error {
129
+ req , err := lr .buildRequest (ctx , http .MethodPost , lr .buildTailnetURL ("aws-external-id" , awsExternalID , "validate-aws-trust-policy" ), requestBody (map [string ]string {
130
+ "roleArn" : roleARN ,
131
+ }))
132
+ if err != nil {
133
+ return err
134
+ }
135
+ return lr .do (req , nil )
136
+ }
0 commit comments