Giter VIP home page Giter VIP logo

stackql / stackql Goto Github PK

View Code? Open in Web Editor NEW
435.0 10.0 44.0 17.44 MB

Query, provision and operate Cloud and SaaS resources and APIs using an extensible SQL based framework

Home Page: https://stackql.io/

License: MIT License

Go 72.14% Jsonnet 0.28% Python 7.69% RobotFramework 19.51% Standard ML 0.13% Dockerfile 0.25%
asset-management cloud cloud-automation cloud-config cloud-operations cloud-security cspm devops devsecops infrastructure-as-code

stackql's Introduction

logo
badge1 badge2 badge3 badge4

Deploy, manage and query cloud resources and interact with APIs using SQL

Read the docs »
Raise an Issue · Request a Feature · Developer Guide · BYO Providers

Contents
  1. About The Project
  2. Installation
  3. Usage
  4. Contributing
  5. License
  6. Contact
  7. Acknowledgements

About The Project

StackQL is an open-source project built with Golang that allows you to create, modify and query the state of services and resources across different cloud and SaaS providers (Google, AWS, Azure, Okta, GitHub, etc.) using SQL semantics

stackql-shell stackql-shell

How it works

StackQL is a standalone application that can be used in client mode (via exec or shell) or accessed via a Postgres wire protocol client (psycopg2, etc.) using server mode (srv).

StackQL parses SQL statements and transpiles them into API requests to the cloud provider. The API calls are then executed and the results are returned to the user.

StackQL provider definitions are defined in OpenAPI extensions to the providers specification. These definitions are then used to generate the SQL schema and the API client. The source for the provider definitions are stored in the StackQL Registry.

StackQL Context Diagram
The following context diagram describes the StackQL architecture at a high level:
flowchart LR
  subgraph StackQL
    direction BT
    subgraph ProviderDefs
        Registry[Provider Registry Docs]    
    end
    subgraph App
        Proc[$ stackql exec\n$ stackql shell\n$ stackql srv]
        style Proc fill:#000,stroke:#000,color:#fff,text-align:left;

        %% ,font-family:'Courier New', Courier, monospace
    end
  end
  User((User)) <--> StackQL <--> Provider[Cloud Provider API]
  ProviderDefs --> App

More detailed design documentation can be found in the here.

Installation

StackQL is available for Windows, MacOS, Linux, Docker, GitHub Actions and more. See the installation instructions below for your platform.

Installing on MacOS
  • Homebrew (amd64 and arm64)
    • brew install stackql or brew tap stackql/tap && brew install stackql/tap/stackql
  • MacOS PKG Installer (amd64 and arm64)
Installing on Windows
  • MSI Installer
  • Chocolatey
  • ZIP Archive
    • download the latest Windows ZIP archive for StackQL
    • extract the archive (code signed stackql.exe file) to a directory of your choice
    • add the directory to your PATH environment variable (optional)
Installing on Linux
  • ZIP Archive
    • download the latest Linux ZIP archive for StackQL
      • or via curl -L https://bit.ly/stackql-zip -O && unzip stackql-zip
    • extract the archive (stackql file) to a directory of your choice
    • add the directory to your PATH environment variable (optional)
Getting StackQL from DockerHub

View all available StackQL images on DockerHub. Images available include stackql, stackql-jupyter-demo and more. Pull the latest StackQL base image using:

docker pull stackql/stackql
Using StackQL with GitHub Actions

Use StackQL in your GitHub Actions workflows to automate cloud infrastructure provisioning, IaC assurance, or compliance/security. Available GitHub Actions include: setup-stackql, stackql-exec and more

Usage

StackQL can be used via the interactive REPL shell, or via the exec command or ran as a server using the Postgres wire protocol.

ℹ️ StackQL does not require or install a database.

  • Interactive Shell

    # run interactive stackql queries
    stackql shell --auth="${AUTH}"
  • Execute a statement or file

    stackql exec --auth="${AUTH}" -i myscript.iql --iqldata vars.jsonnet --output json
    
    # or
    
    stackql exec --auth="${AUTH}" "SELECT id, status FROM aws.ec2.instances WHERE region = 'us-east-1'"

    ℹ️ output options of json, csv, table and text are available for the exec command using the --output flag

    ℹ️ StackQL supports passing parameters using jsonnet or json, see Using Variables

  • Server

    # serve client requests over the Postgres wire protocol (psycopg2, etc.) 
    stackql srv --auth="${AUTH}"

For more examples, please check our Blog

Contributing

Contributions are welcome and encouraged. For more information on how to contribute, please see our contributing guide.

License

Distributed under the MIT License. See LICENSE for more information. Licenses for third party software we are using are included in the /docs/licenses directory.

Contact

Get in touch with us via Twitter at @stackql, email us at [email protected] or start a conversation using discussions.

Acknowledgements

Forks of the following support our work:

We gratefully acknowledge these pieces of work.

stackql's People

Contributors

bulkbeing avatar datwiz avatar general-kroll-4-life avatar iqbalabdi avatar jeffreyaven avatar jthegedus avatar kieranrimmer avatar racso-3141 avatar rameshgkwd05 avatar ryuichi-maeda avatar ryukinoz avatar sanketmp avatar tomekz avatar yunchengyang515 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

stackql's Issues

[FEATURE] Syntax highlighting/color for `shell`

Feature Description
For user/SQL IDE like experience, it would be nice to have syntax highlighting in the shell, with the prompt (stackql >>) in yellow, and keywords such as SELECT, WHERE and FROM in blue, this can listen to keystroke events, ideally the code will be shareable with or portable to a VS Code extension for StackQL so we don't have to reinvent the wheel when we do this

[FEATURE] Use `goreleaser` for build workflows

Feature Description
Current build and test workflows in GitHub Action use go.yml and lint.yml. We would like to move to goreleaser as a build and test framework, to automatically generate releases from tags.

Builds should include:

  • Windows AMD64
  • Darwin Universal (Fat) binary - ARM and AMD
  • Linux AMD64 and ARM64
  • Docker

Package artefacts should include:

  • Docker images pushed to dockerhub (see existing workflows)
  • Linux packages .deb, .rpm, .apk, and Archlinux packages
  • Chocolatey Windows packages

other artefacts are built offline (such as the Windows MSI file and MacOS PKG artefacts as these require external signing or notarization)

Example(s)
The following workflow file .github/workflows/goreleaser.yml has been created but not completed or implemented.

[FEATURE] Predicate Push Down Abstract Implementation

Feature Description
Design and implement an abstract interface (through a provider's x-stackQL-resources object) to take advantage of predicate push down to limit data (columns and/or rows) returned.

Example(s)
Given API operations which map to SELECT verbs in StackQL, identify the optional query parameters which can be mapped to the following operation:

  • column list for projection, invoked using SELECT <field1>, <field2> including fields operated on by scalar functions (such as SPLIT_PART, JSON_EXTRACT, etc.)
  • limiting records returned, invoked using LIMIT <num>
  • filter expressions, invoked using WHERE <field> = '<something>'
  • ordering predicates, invoked using ORDER BY <field>

for example...

  parameters:
    fields:
      description: Selector specifying which fields to include in a partial response.
      in: query
      name: fields
      schema:
        type: string

Create a document based interface to map verbs in the parser to the specified query parameters.

Possible Approaches or Libraries to Consider
A possible approach would be to create an extension to the provider interface for example...

components:
    x-stackQL-resources:
        databases:
          id: google.spanner.databases
          name: databases
          title: Databases
          methods:
            projects_instances_databases_get:
              operation:
                $ref: '#/paths/~1v1~1projects~1{projectsId}~1instances~1{instancesId}~1databases~1{databasesId}/get'
              response:
                mediaType: application/json
                openAPIDocKey: '200'
            projects_instances_databases_list:
              operation:
                $ref: '#/paths/~1v1~1projects~1{projectsId}~1instances~1{instancesId}~1databases/get'
              response:
                mediaType: application/json
                openAPIDocKey: '200'
                objectKey: $.databases
            ...
          sqlVerbs:
            select:
              - $ref: '#/components/x-stackQL-resources/databases/methods/projects_instances_databases_get'
              - $ref: '#/components/x-stackQL-resources/databases/methods/projects_instances_databases_list'
            insert:
              - $ref: '#/components/x-stackQL-resources/databases/methods/projects_instances_databases_create'
            update: []
            delete: []
          predicates:
            select:
              rowFilter: 
                param: filter
                example: "column1 = 'value1' AND column2 = 'value2'"
              colFilter:
                param: fields
                example: "column1,column2"
              orderBy:
                param: orderBy
                example: "column1 ASC"
              limit:
                param: limit
                example: 10

may need to implement generalized formats for each type of predicate.

[BUG] Fix all of the actionlint issues detected in the workflow files.

Describe the bug

The recently introduced actionlint function detects a number of issues in the workflow file go,yml in particular. this piece of work is to fix these and have the check pass.

The check can be seen at: https://github.com/stackql/stackql/actions/runs/4194391714/jobs/7272489405

To Reproduce

The check can be seen at: https://github.com/stackql/stackql/actions/runs/4194391714/jobs/7272489405

Expected behavior

The actionlint check should pass.

Screenshots

N/A

Desktop (please complete the following information):

N/A

Smartphone (please complete the following information):

N/A

Additional context

N/A

Transactions v1

Support for transactions v1.

Eager read only queries in-transaction.

Lazy mutations, executed on commit.

Attempted mutation failures to spill a human-readable undo log of those resources that were successfully mutated, in inverse order. That is, a path to revert (with the generous assumption that inverse order undo will work).

Replace java mock server with some Python http server

Replace the existing java mock server with some python http server that is:

  • lightweight.
  • template-enabled.
  • simply orchestratible from robot framework.

Acceptance criteria:

  • Mock server completely removed from repository.
  • All existing robot tests working.
  • All CICD working as expected.
  • All documentation updated.

[FEATURE] Tab completion for the `shell`

Feature Description
For analyst/user experience it would be good to include tab completion in the shell, this would work for keywords such as select, etc but ultimately would include object context (e.e services in a provider, resources in a service, projected fields in a resource)

table lifecycle support

Support for create, mutate and delete of tables, NOT including temporary lifetime support.

[FEATURE] Support for BigQuery

Feature Description

BigQuery tables ought to be queryable through stackql.

Note: This is an example from the team at stackql, for a large feature. We shall also provide examples for smaller features and bugs. Example or no, this card will be actioned.

Example(s)

I want to be able to query BigQuery tables from within stackql. Eg: select column1, column2 from <connection_name>.my_big_query_table where....

The motivating use case is accessing and reporting BQ metadata. Concrete example: table count.

Other use cases include:

  • Control tables in BQ, for example supporting Infrastructure As Code workflows.
  • All the classical reporting structures over stackql.

Possible Approaches or Libraries to Consider

One candidate approach is the sql driver pattern using https://github.com/solcates/go-sql-bigquery.

Additional context

This is a large feature request.

[BUG] Infra templates contain references to a non-existent object

Describe the bug
When running a SHOW INSERT INTO operation, to query template contains a reference to .values which does not exist in the jsonne config block generated.

To Reproduce
running...

./stackql exec --output=text -H -f virtual_machines.iql "SHOW INSERT /*+ REQUIRED */ INTO azure.compute.virtual_machines"

produces a template which looks like this:

<<<jsonnet
{
   resourceGroupName: << resourceGroupName >>,
   subscriptionId: << subscriptionId >>,
   vmName: << vmName >>
}
>>>
INSERT INTO azure.compute.virtual_machines(
  resourceGroupName,
  subscriptionId,
  vmName
)
SELECT
  '{{ .values.resourceGroupName }}',
  '{{ .values.subscriptionId }}',
  '{{ .values.vmName }}'
;

Expected behavior
The template should look like this...

<<<jsonnet
{
   resourceGroupName: << resourceGroupName >>,
   subscriptionId: << subscriptionId >>,
   vmName: << vmName >>
}
>>>
INSERT INTO azure.compute.virtual_machines(
  resourceGroupName,
  subscriptionId,
  vmName
)
SELECT
  '{{ .resourceGroupName }}',
  '{{ .subscriptionId }}',
  '{{ .vmName }}'
;

[BUG] Field not found kills server

Describe the bug
Attempting to query a field that does not exist kills the server

To Reproduce
Steps to reproduce the behavior:

  1. Run the following query via the shell or exec:
select id, created_at, size_in_bytes
from github.actions.artifacts
where owner = 'stackql' and repo = 'stackql'

will get the error (with the current GitHub provider doc):

sql packet preparation error: no such column: id
  1. Run the same query against the server - it will kill the server process

Expected behavior
Should just return a pg error with text similar to what is returned in the shell, should not kill the server

[FEATURE] Support for scalar functions in outer query columns in a subquery

Feature Description
It would help to reduce repeated code if we could use scalar functions in the column list in the outer query in a subquery, for instance:

SELECT 
name,
iif(isResidencyRestricted = 0, 'false', 'true') as isResidencyRestricted,
backupStorageRedundancies,
supportsAvailabilityZone 
FROM (
    SELECT 
    name,
    json_extract(properties, '$.isResidencyRestricted') as isResidencyRestricted,
    json_extract(properties, '$.supportsAvailabilityZone') as supportsAvailabilityZone,
    json_extract(properties, '$.backupStorageRedundancies') as backupStorageRedundancies 
    FROM azure.cosmos_db.locations 
    WHERE subscriptionId = '631d1c6d-2a65-43e7-93c2-688bfe4e1468'
) AS virtual_table;

currently this is not supported, however it works if you remove the function, e.g.:

SELECT 
name,
isResidencyRestricted,
backupStorageRedundancies,
supportsAvailabilityZone 
FROM (
    SELECT 
    name,
    json_extract(properties, '$.isResidencyRestricted') as isResidencyRestricted,
    json_extract(properties, '$.supportsAvailabilityZone') as supportsAvailabilityZone,
    json_extract(properties, '$.backupStorageRedundancies') as backupStorageRedundancies 
    FROM azure.cosmos_db.locations 
    WHERE subscriptionId = '631d1c6d-2a65-43e7-93c2-688bfe4e1468'
) AS virtual_table;

[FEATURE] Enhanced INSERT templating

Show enhanced output for SHOW INSERT commands which includes the jsonnet block for users to add their params, for example, this command

./stackql --output=text -H exec "SHOW INSERT INTO google.container.clusters"

would output something to the effect of:

<<<jsonnet
{
 values: {
  locationsId: <<locationsId string>>,
  projectsId: <<projectsId string>>,
  data__cluster: {
	addonsConfig: <<addonsConfig object>>,
	authenticatorGroupsConfig: <<authenticatorGroupsConfig object>>,
	autopilot: <<autopilot boolean>>,
	autoscaling: <<autoscaling boolean>>,
	binaryAuthorization: <<binaryAuthorization boolean>>,
	clusterIpv4Cidr: <<clusterIpv4Cidr string>>,
	conditions: [
		<<condition object>>
	],
	...
  }
 }
>>>
INSERT INTO google.container.clusters(
  locationsId,
  projectsId,
  data__cluster,
  data__parent,
  data__projectId,
  data__zone
)
SELECT
  '{{ .values.locationsId }}',
  '{{ .values.projectsId }}',
  '{ "addonsConfig": "{{ .values.data__cluster.addonsConfig }}", "authenticatorGroupsConfig": "{{ .values.data__cluster.authenticatorGroupsConfig }}", "autopilot": "{{ .values.data__cluster.autopilot }}", "autoscaling": "{{ .values.data__cluster.autoscaling }}", "binaryAuthorization": "{{ .values.data__cluster.binaryAuthorization }}", "clusterIpv4Cidr": "{{ .values.data__cluster.clusterIpv4Cidr 
}}", "conditions": [ "{{ .values.data__cluster.conditions[0] }}" ], "confidentialNodes": "{{ .values.data__cluster.confidentialNodes }}", "costManagementConfig": "{{ .values.data__cluster.costManagementConfig }}", "createTime": "{{ .values.data__cluster.createTime }}", "currentMasterVersion": "{{ .values.data__cluster.currentMasterVersion }}", "currentNodeCount": {{ .values.data__cluster.currentNodeCount }}, "currentNodeVersion": "{{ .values.data__cluster.currentNodeVersion }}", "databaseEncryption": "{{ .values.data__cluster.databaseEncryption }}", "defaultMaxPodsConstraint": "{{ .values.data__cluster.defaultMaxPodsConstraint }}", "description": "{{ .values.data__cluster.description }}", "enableKubernetesAlpha": {{ .values.data__cluster.enableKubernetesAlpha }}, "enableTpu": {{ .values.data__cluster.enableTpu }}, "endpoint": "{{ .values.data__cluster.endpoint }}", "etag": "{{ .values.data__cluster.etag }}", "expireTime": "{{ .values.data__cluster.expireTime }}", "id": "{{ .values.data__cluster.id }}", "identityServiceConfig": "{{ .values.data__cluster.identityServiceConfig }}", "initialClusterVersion": "{{ .values.data__cluster.initialClusterVersion }}", "initialNodeCount": 
{{ .values.data__cluster.initialNodeCount }}, "instanceGroupUrls": [ "{{ .values.data__cluster.instanceGroupUrls[0] }}" ], "ipAllocationPolicy": "{{ .values.data__cluster.ipAllocationPolicy }}", "labelFingerprint": "{{ .values.data__cluster.labelFingerprint }}", "legacyAbac": "{{ .values.data__cluster.legacyAbac }}", "location": "{{ .values.data__cluster.location }}", "locations": [ "{{ .values.data__cluster.locations[0] }}" ], "loggingConfig": "{{ .values.data__cluster.loggingConfig }}", "loggingService": "{{ .values.data__cluster.loggingService }}", "maintenancePolicy": "{{ .values.data__cluster.maintenancePolicy }}", "masterAuth": "{{ .values.data__cluster.masterAuth }}", "masterAuthorizedNetworksConfig": "{{ .values.data__cluster.masterAuthorizedNetworksConfig }}", "meshCertificates": "{{ .values.data__cluster.meshCertificates }}", "monitoringConfig": "{{ .values.data__cluster.monitoringConfig }}", "monitoringService": "{{ .values.data__cluster.monitoringService }}", "name": "{{ .values.data__cluster.name }}", "network": "{{ .values.data__cluster.network }}", "networkConfig": "{{ .values.data__cluster.networkConfig }}", "networkPolicy": "{{ .values.data__cluster.networkPolicy }}", "nodeConfig": "{{ .values.data__cluster.nodeConfig }}", "nodeIpv4CidrSize": {{ .values.data__cluster.nodeIpv4CidrSize }}, "nodePoolAutoConfig": "{{ .values.data__cluster.nodePoolAutoConfig 
}}", "nodePoolDefaults": "{{ .values.data__cluster.nodePoolDefaults }}", "nodePools": [ "{{ .values.data__cluster.nodePools[0] }}" ], "notificationConfig": "{{ .values.data__cluster.notificationConfig }}", "privateClusterConfig": "{{ .values.data__cluster.privateClusterConfig }}", "releaseChannel": "{{ .values.data__cluster.releaseChannel }}", "resourceLabels": { "{{ .values.data__cluster.resourceLabels[0].key }}": "{{ .values.data__cluster.resourceLabels[0].val }}" }, "resourceUsageExportConfig": "{{ .values.data__cluster.resourceUsageExportConfig }}", "selfLink": "{{ .values.data__cluster.selfLink }}", "servicesIpv4Cidr": "{{ .values.data__cluster.servicesIpv4Cidr }}", "shieldedNodes": "{{ .values.data__cluster.shieldedNodes }}", "status": "{{ .values.data__cluster.status }}", "statusMessage": "{{ .values.data__cluster.statusMessage }}", "subnetwork": "{{ .values.data__cluster.subnetwork }}", "tpuIpv4CidrBlock": "{{ .values.data__cluster.tpuIpv4CidrBlock }}", "verticalPodAutoscaling": "{{ .values.data__cluster.verticalPodAutoscaling }}", "workloadIdentityConfig": "{{ .values.data__cluster.workloadIdentityConfig }}", "zone": "{{ .values.data__cluster.zone }}" }',
  '{{ .values.data__parent }}',
  '{{ .values.data__projectId }}',
  '{{ .values.data__zone }}'
;

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.