如何使用bash批量检索Airflow连接? (Google Composer) [英] How to retrieve Airflow connections in bulk using bash? (Google Composer)
问题描述
我正在尝试使用基础架构作为代码的方法创建一个作曲者环境. 为此,我需要能够以编程方式存储和检索气流变量,并将它们的版本保持在某个地方.
I am trying to create a composer environment with the approach of infrastructure as code. For this, I need to be able to store and retrieve airflow variables programmatically, and keep them versioned somewhere.
以下命令可让我列出指定的$COMPOSER_ENV
The following command lets me list all my connections within the specified $COMPOSER_ENV
gcloud composer environments run `$COMPOSER_ENV` --location <location> connections -- --list
这是输出:
╒════════════════════════════════╤═════════════════════════════╤════════════════════════════════╤════════╤════════════════╤══════════════════════╤════════════════════════════════╕
│ Conn Id │ Conn Type │ Host │ Port │ Is Encrypted │ Is Extra Encrypted │ Extra │
╞════════════════════════════════╪═════════════════════════════╪════════════════════════════════╪════════╪════════════════╪══════════════════════╪════════════════════════════════╡
│ 'airflow_db' │ 'mysql' │ 'airflow-sqlp...rvice.default' │ None │ True │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'beeline_default' │ 'beeline' │ 'localhost' │ 10000 │ False │ True │ 'gAAAAABfdZs0...yjt7nj1C2Dzgm' │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'bigquery_default' │ 'google_cloud_platform' │ None │ None │ False │ True │ 'gAAAAABfdZs2...AOdwY-EnZLg==' │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'local_mysql' │ 'mysql' │ 'localhost' │ None │ True │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'presto_default' │ 'presto' │ 'localhost' │ 3400 │ False │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'google_cloud_default' │ 'google_cloud_platform' │ None │ None │ False │ True │ 'gAAAAABfdZs2...oMm2saUwAxQ==' │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'hive_cli_default' │ 'hive_cli' │ None │ None │ False │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'pig_cli_default' │ 'pig_cli' │ None │ None │ False │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'hiveserver2_default' │ 'hiveserver2' │ 'localhost' │ 10000 │ False │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'metastore_default' │ 'hive_metastore' │ 'localhost' │ 9083 │ False │ True │ 'gAAAAABfdZs0...vNSgFh1mE1HY=' │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'mongo_default' │ 'mongo' │ 'mongo' │ 27017 │ False │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'mysql_default' │ 'mysql' │ 'mysql' │ None │ False │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'postgres_default' │ 'postgres' │ 'postgres' │ None │ True │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'sqlite_default' │ 'sqlite' │ '/tmp/sqlite_default.db' │ None │ False │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'http_default' │ 'http' │ 'https://www.httpbin.org/' │ None │ False │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'mssql_default' │ 'mssql' │ 'localhost' │ 1433 │ False │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'vertica_default' │ 'vertica' │ 'localhost' │ 5433 │ False │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'wasb_default' │ 'wasb' │ None │ None │ False │ True │ 'gAAAAABfdZs0...ST7E2347-uG4=' │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'webhdfs_default' │ 'hdfs' │ 'localhost' │ 50070 │ False │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'ssh_default' │ 'ssh' │ 'localhost' │ None │ False │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'sftp_default' │ 'sftp' │ 'localhost' │ 22 │ False │ True │ 'gAAAAABfdZs0...guLrr1ky5XpN2' │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'fs_default' │ 'fs' │ None │ None │ False │ True │ 'gAAAAABfdZs0...WqhP9ZLa8gQ==' │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'aws_default' │ 'aws' │ None │ None │ False │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'spark_default' │ 'spark' │ 'yarn' │ None │ False │ True │ 'gAAAAABfdZs0...18ws2BelkcL8=' │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'druid_broker_default' │ 'druid' │ 'druid-broker' │ 8082 │ False │ True │ 'gAAAAABfdZs0...sC6Kcd9mOKhE=' │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'druid_ingest_default' │ 'druid' │ 'druid-overlord' │ 8081 │ False │ True │ 'gAAAAABfdZs0...CpBdCkHuk5lqw' │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'redis_default' │ 'redis' │ 'redis' │ 6379 │ False │ True │ 'gAAAAABfdZs0...E1qdjhMngIg==' │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'sqoop_default' │ 'sqoop' │ 'rmdbs' │ None │ False │ False │ '' │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'emr_default' │ 'emr' │ None │ None │ False │ True │ 'gAAAAABfdZs0...GsJIS8IjaBuM=' │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'databricks_default' │ 'databricks' │ 'localhost' │ None │ False │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'qubole_default' │ 'qubole' │ 'localhost' │ None │ False │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'segment_default' │ 'segment' │ None │ None │ False │ True │ 'gAAAAABfdZs0...oawClUj4Qzj8i' │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'azure_data_lake_default' │ 'azure_data_lake' │ None │ None │ False │ True │ 'gAAAAABfdZs0...DMIAMmOeZNg==' │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'azure_cosmos_default' │ 'azure_cosmos' │ None │ None │ False │ True │ 'gAAAAABfdZs0...tusOfGrWviAk=' │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'azure_contai...ances_default' │ 'azure_container_instances' │ None │ None │ False │ True │ 'gAAAAABfdZs0...q460BKvTu4Lk=' │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'cassandra_default' │ 'cassandra' │ 'cassandra' │ 9042 │ False │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'dingding_default' │ 'http' │ '' │ None │ False │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'opsgenie_default' │ 'http' │ '' │ None │ False │ False │ None │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'google_cloud...store_default' │ 'google_cloud_platform' │ None │ None │ False │ True │ 'gAAAAABfdZs2...ltsxQHWUgxA==' │
├────────────────────────────────┼─────────────────────────────┼────────────────────────────────┼────────┼────────────────┼──────────────────────┼────────────────────────────────┤
│ 'google_cloud_storage_default' │ 'google_cloud_platform' │ None │ None │ False │ True │ 'gAAAAABfdZs2...RNLazPEE7gQ==' │
╘════════════════════════════════╧═════════════════════════════╧════════════════════════════════╧════════╧════════════════╧══════════════════════╧════════════════════════════════╛
此输出的问题是它返回了几乎不可用的数据表(请参见下面的图像).理想情况下,它应该返回类似json的结构.
The issue with this output is that it returns a hardly usable table of data (See image bellow). Ideally, it should return a json like structure.
- 问题1:有没有一种快速的方法可以将连接(和变量)导出(并导入)为json?
- 问题2:如果问题1是没有办法",那么如何将这些数据转换成漂亮的字典或类似键值的结构?
此外,非常感谢您对awk/grep
模式进行任何其他解释.
Also, any additional explanation on the awk/grep
patterns would be very much appreciated.
推荐答案
使用cat file
代替您的gcloud
命令,我不必在您的问题中生成表格:
Using cat file
instead of your gcloud
command which I don't have to generate the table in your question:
$ cat tst.awk
!/[[:space:]]/ {
# Skip all lines that separate the data rows
next
}
(++nr) == 1 {
# Set FS to whatever the combination of control chars is at the start of the first data line
match($0,/[^[:blank:]]+/)
FS = "[[:blank:]]*" substr($0,1,RLENGTH) "[[:blank:]]*"
}
{
# Get rid of the FSs at the start and end of the line to avoid leading/trailing null fields
gsub("^" FS "|" FS "$","")
}
nr == 1 {
# Store the header lines for later use
for (i=1; i<=NF; i++) {
gsub(/[[:blank:]]+/,"_",$i)
hdr[i] = $i
}
print "{"
next
}
{
# Print the json-equivalent for the data on the current line
gsub(/\047/,"\"")
printf "%s %s: {\n", (nr>2 ? ",\n" : ""), $1
for (i=2; i<=NF; i++) {
printf " \"%s\": %s%s\n", hdr[i], $i, (i<NF ? "," : "")
}
printf " }", $1
}
END {
print "\n}"
}
$ cat file | awk -f tst.awk
{
"airflow_db": {
"Conn_Type": "mysql",
"Host": "airflow-sqlp...rvice.default",
"Port": None,
"Is_Encrypted": True,
"Is_Extra_Encrypted": False,
"Extra": None
},
"beeline_default": {
"Conn_Type": "beeline",
"Host": "localhost",
"Port": 10000,
"Is_Encrypted": False,
"Is_Extra_Encrypted": True,
"Extra": "gAAAAABfdZs0...yjt7nj1C2Dzgm"
},
"bigquery_default": {
"Conn_Type": "google_cloud_platform",
"Host": None,
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": True,
"Extra": "gAAAAABfdZs2...AOdwY-EnZLg=="
},
"local_mysql": {
"Conn_Type": "mysql",
"Host": "localhost",
"Port": None,
"Is_Encrypted": True,
"Is_Extra_Encrypted": False,
"Extra": None
},
"presto_default": {
"Conn_Type": "presto",
"Host": "localhost",
"Port": 3400,
"Is_Encrypted": False,
"Is_Extra_Encrypted": False,
"Extra": None
},
"google_cloud_default": {
"Conn_Type": "google_cloud_platform",
"Host": None,
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": True,
"Extra": "gAAAAABfdZs2...oMm2saUwAxQ=="
},
"hive_cli_default": {
"Conn_Type": "hive_cli",
"Host": None,
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": False,
"Extra": None
},
"pig_cli_default": {
"Conn_Type": "pig_cli",
"Host": None,
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": False,
"Extra": None
},
"hiveserver2_default": {
"Conn_Type": "hiveserver2",
"Host": "localhost",
"Port": 10000,
"Is_Encrypted": False,
"Is_Extra_Encrypted": False,
"Extra": None
},
"metastore_default": {
"Conn_Type": "hive_metastore",
"Host": "localhost",
"Port": 9083,
"Is_Encrypted": False,
"Is_Extra_Encrypted": True,
"Extra": "gAAAAABfdZs0...vNSgFh1mE1HY="
},
"mongo_default": {
"Conn_Type": "mongo",
"Host": "mongo",
"Port": 27017,
"Is_Encrypted": False,
"Is_Extra_Encrypted": False,
"Extra": None
},
"mysql_default": {
"Conn_Type": "mysql",
"Host": "mysql",
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": False,
"Extra": None
},
"postgres_default": {
"Conn_Type": "postgres",
"Host": "postgres",
"Port": None,
"Is_Encrypted": True,
"Is_Extra_Encrypted": False,
"Extra": None
},
"sqlite_default": {
"Conn_Type": "sqlite",
"Host": "/tmp/sqlite_default.db",
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": False,
"Extra": None
},
"http_default": {
"Conn_Type": "http",
"Host": "https://www.httpbin.org/",
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": False,
"Extra": None
},
"mssql_default": {
"Conn_Type": "mssql",
"Host": "localhost",
"Port": 1433,
"Is_Encrypted": False,
"Is_Extra_Encrypted": False,
"Extra": None
},
"vertica_default": {
"Conn_Type": "vertica",
"Host": "localhost",
"Port": 5433,
"Is_Encrypted": False,
"Is_Extra_Encrypted": False,
"Extra": None
},
"wasb_default": {
"Conn_Type": "wasb",
"Host": None,
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": True,
"Extra": "gAAAAABfdZs0...ST7E2347-uG4="
},
"webhdfs_default": {
"Conn_Type": "hdfs",
"Host": "localhost",
"Port": 50070,
"Is_Encrypted": False,
"Is_Extra_Encrypted": False,
"Extra": None
},
"ssh_default": {
"Conn_Type": "ssh",
"Host": "localhost",
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": False,
"Extra": None
},
"sftp_default": {
"Conn_Type": "sftp",
"Host": "localhost",
"Port": 22,
"Is_Encrypted": False,
"Is_Extra_Encrypted": True,
"Extra": "gAAAAABfdZs0...guLrr1ky5XpN2"
},
"fs_default": {
"Conn_Type": "fs",
"Host": None,
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": True,
"Extra": "gAAAAABfdZs0...WqhP9ZLa8gQ=="
},
"aws_default": {
"Conn_Type": "aws",
"Host": None,
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": False,
"Extra": None
},
"spark_default": {
"Conn_Type": "spark",
"Host": "yarn",
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": True,
"Extra": "gAAAAABfdZs0...18ws2BelkcL8="
},
"druid_broker_default": {
"Conn_Type": "druid",
"Host": "druid-broker",
"Port": 8082,
"Is_Encrypted": False,
"Is_Extra_Encrypted": True,
"Extra": "gAAAAABfdZs0...sC6Kcd9mOKhE="
},
"druid_ingest_default": {
"Conn_Type": "druid",
"Host": "druid-overlord",
"Port": 8081,
"Is_Encrypted": False,
"Is_Extra_Encrypted": True,
"Extra": "gAAAAABfdZs0...CpBdCkHuk5lqw"
},
"redis_default": {
"Conn_Type": "redis",
"Host": "redis",
"Port": 6379,
"Is_Encrypted": False,
"Is_Extra_Encrypted": True,
"Extra": "gAAAAABfdZs0...E1qdjhMngIg=="
},
"sqoop_default": {
"Conn_Type": "sqoop",
"Host": "rmdbs",
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": False,
"Extra": ""
},
"emr_default": {
"Conn_Type": "emr",
"Host": None,
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": True,
"Extra": "gAAAAABfdZs0...GsJIS8IjaBuM="
},
"databricks_default": {
"Conn_Type": "databricks",
"Host": "localhost",
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": False,
"Extra": None
},
"qubole_default": {
"Conn_Type": "qubole",
"Host": "localhost",
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": False,
"Extra": None
},
"segment_default": {
"Conn_Type": "segment",
"Host": None,
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": True,
"Extra": "gAAAAABfdZs0...oawClUj4Qzj8i"
},
"azure_data_lake_default": {
"Conn_Type": "azure_data_lake",
"Host": None,
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": True,
"Extra": "gAAAAABfdZs0...DMIAMmOeZNg=="
},
"azure_cosmos_default": {
"Conn_Type": "azure_cosmos",
"Host": None,
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": True,
"Extra": "gAAAAABfdZs0...tusOfGrWviAk="
},
"azure_contai...ances_default": {
"Conn_Type": "azure_container_instances",
"Host": None,
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": True,
"Extra": "gAAAAABfdZs0...q460BKvTu4Lk="
},
"cassandra_default": {
"Conn_Type": "cassandra",
"Host": "cassandra",
"Port": 9042,
"Is_Encrypted": False,
"Is_Extra_Encrypted": False,
"Extra": None
},
"dingding_default": {
"Conn_Type": "http",
"Host": "",
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": False,
"Extra": None
},
"opsgenie_default": {
"Conn_Type": "http",
"Host": "",
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": False,
"Extra": None
},
"google_cloud...store_default": {
"Conn_Type": "google_cloud_platform",
"Host": None,
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": True,
"Extra": "gAAAAABfdZs2...ltsxQHWUgxA=="
},
"google_cloud_storage_default": {
"Conn_Type": "google_cloud_platform",
"Host": None,
"Port": None,
"Is_Encrypted": False,
"Is_Extra_Encrypted": True,
"Extra": "gAAAAABfdZs2...RNLazPEE7gQ=="
}
}
请注意,如果idk实际上不是有效的json,我只是将文本块从输入位置移动到输出位置.希望对您来说,进行所需的任何更改以产生您实际想要的输出(问题中遗漏了)就足够容易了.
Note that idk if that's actually valid json or not, I'm just moving blocks of text from positions in your input to positions in your output. Hopefully it'll be easy enough for you to make whatever changes you need to make to produce whatever output you actually wanted to get (which was missing from your question).
这篇关于如何使用bash批量检索Airflow连接? (Google Composer)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!