-
Notifications
You must be signed in to change notification settings - Fork 425
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
Internal server error 500 getting the list of connections of a virtual connection #1558
Comments
There was a request to support Virtual Connections in TSC here, and a PR was merged here. So this bug is a regression. |
Closes tableau#1558 Connection XML element for VirtualConnections has different attribute keys compared to connection XML elements when returned by Datasources, Workbooks, and Flows. This PR adds in flexibility to ConnectionItem's reading of XML to account for both sets of attributes that may be present elements.
This was challenging to troubleshoot, so leaving some notes here. First, setup resources in AWS using Terraform. terraform {
required_providers {
aws = {
source = "hashicorp/aws"
version = "~> 5.86.0"
}
}
required_version = ">= 1.9"
}
provider "aws" {
region = "us-west-2"
}
variable "prefix" {
type = string
description = "Prefix for resources"
}
resource "local_file" "this" {
content = "col1,col2\nval1,val2"
filename = "example.csv"
}
resource "aws_s3_bucket" "this" {
bucket = replace("${var.prefix}_bucket", "_", "-")
force_destroy = true
}
resource "aws_s3_object" "this" {
bucket = aws_s3_bucket.this.bucket
key = "input/${local_file.this.filename}"
source = local_file.this.filename
}
resource "aws_glue_catalog_database" "this" {
name = "${var.prefix}_db"
}
resource "aws_glue_catalog_table" "this" {
catalog_id = aws_glue_catalog_database.this.catalog_id
database_name = aws_glue_catalog_database.this.name
name = "${var.prefix}_table"
parameters = {
"classification" = "csv"
}
table_type = "EXTERNAL_TABLE"
storage_descriptor {
compressed = false
input_format = "org.apache.hadoop.mapred.TextInputFormat"
location = "s3://${aws_s3_bucket.this.bucket}/${dirname(aws_s3_object.this.key)}"
output_format = "org.apache.hadoop.hive.ql.io.HiveIgnoreKeyTextOutputFormat"
columns {
name = "col1"
type = "string"
}
columns {
name = "col2"
type = "string"
}
ser_de_info {
parameters = {
"separatorChar" = ","
}
serialization_library = "org.apache.hadoop.hive.serde2.OpenCSVSerde"
}
}
}
resource "aws_athena_workgroup" "this" {
name = var.prefix
configuration {
enforce_workgroup_configuration = true
publish_cloudwatch_metrics_enabled = false
result_configuration {
output_location = "s3://${aws_s3_bucket.this.bucket}/output"
}
}
}
data "aws_caller_identity" "this" {}
data "aws_region" "current" {}
data "aws_iam_policy_document" "this" {
statement {
actions = [
"athena:StartQueryExecution",
"athena:StartSession",
"athena:StopQueryExecution",
"athena:Get*",
"athena:List*",
"athena:RunQuery",
"glue:BatchGet*",
"glue:Get*",
"glue:List*",
"glue:TestConnection",
"glue:CreateConnection",
]
resources = [
aws_glue_catalog_database.this.arn,
aws_glue_catalog_table.this.arn,
aws_athena_workgroup.this.arn,
"arn:aws:athena:${data.aws_region.current.name}:${data.aws_caller_identity.this.account_id}:workgroup/*",
"arn:aws:athena:${data.aws_region.current.name}:${data.aws_caller_identity.this.account_id}:DataCatalog/*",
"arn:aws:glue:${data.aws_region.current.name}:${data.aws_caller_identity.this.account_id}:catalog",
]
}
statement {
actions = [
"s3:Get*",
"s3:List*",
"s3:Put*",
]
resources = [
aws_s3_bucket.this.arn,
"${aws_s3_bucket.this.arn}/*",
]
}
}
resource "aws_iam_user" "this" {
name = var.prefix
}
resource "aws_iam_user_policy" "this" {
name = var.prefix
user = aws_iam_user.this.name
policy = data.aws_iam_policy_document.this.json
}
resource "aws_iam_access_key" "this" {
user = aws_iam_user.this.name
}
output "ak" {
value = aws_iam_access_key.this.id
}
output "sk" {
sensitive = true
value = aws_iam_access_key.this.secret
}
output "athena_server" {
value = "athena.${data.aws_region.current.name}.amazonaws.com:443;Workgroup=${aws_athena_workgroup.this.name}"
}
output "s3_output" {
value = aws_athena_workgroup.this.configuration[0].result_configuration[0].output_location
}
output "glue_table" {
value = aws_glue_catalog_table.this.name
}
output "region" {
value = data.aws_region.current.name
} Use the access key and secret key created to populate the virtual connection on the server. Connections can only be created via the Web UI, and not the REST API, so I don't have an example of that. I also named it "bug" so I could find it easier during the script. Then rotate the keys, create the json, and run the python script. terraform taint aws_iam_access_key.this
terraform plan -out tfplan
terraform apply tfplan
terraform output -json > keys.json Then run the python script: #/// script
# requires_python = ">=3.9"
# dependencies = ["tableauserverclient==0.35", "python-dotenv"]
#///
import json
import os
from pathlib import Path
from dotenv import load_dotenv
import tableauserverclient as TSC
load_dotenv()
def update_environment() -> None:
with (Path(__file__).parent / "keys.json").open() as f:
keys = json.load(f)
for k,v in keys.items():
os.environ[k] = v["value"]
def main() -> None:
server = TSC.Server(os.getenv("TABLEAU_SERVER"), use_server_version=True)
auth = TSC.PersonalAccessTokenAuth(
token_name=os.environ["TOKEN_NAME"],
personal_access_token=os.environ["TOKEN_SECRET"],
site_id=os.environ["TABLEAU_SITE"]
)
with server.auth.sign_in(auth):
for vc in TSC.Pager(server.virtual_connections):
if vc.name != 'bug':
continue
server.virtual_connections.populate_connections(vc)
for conn in vc.connections:
conn: TSC.ConnectionItem
if conn.connection_type != 'athena':
continue
print(f"{conn.server_address}:{conn.server_port}")
target = conn
target.username = os.environ["ak"]
target.password = os.environ["sk"]
print(target)
conn = server.virtual_connections.update_connection_db_connection(vc, target)
print(conn)
if __name__ == "__main__":
update_environment()
main() The failure happens during the updated process as the |
If that is the case, shouldn't it be a 400 error? |
I believe its because the server side doesn't validate whether or not you sent a connection id. It retrieves it from that path. It doesn't make sense for you to "update" the connection with the ID of |
Describe the bug
getting the list of connections of a virtual connection throws an internal server error 500
Versions
Details of your environment, including:
To Reproduce
Results
The text was updated successfully, but these errors were encountered: