{"id":31904120,"url":"https://github.com/cloudfoundry-community/gautocloud","last_synced_at":"2025-10-13T13:47:28.639Z","repository":{"id":16297975,"uuid":"79683717","full_name":"cloudfoundry-community/gautocloud","owner":"cloudfoundry-community","description":"A golang library to let cloud applications connect automatically to services.","archived":false,"fork":false,"pushed_at":"2025-08-27T08:37:51.000Z","size":1364,"stargazers_count":17,"open_issues_count":5,"forks_count":7,"subscribers_count":40,"default_branch":"master","last_synced_at":"2025-10-02T22:38:49.270Z","etag":null,"topics":["cloud-environments","cloud-foundry","heroku","kubernetes","services"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/cloudfoundry-community.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2017-01-22T01:06:26.000Z","updated_at":"2025-08-27T08:33:28.000Z","dependencies_parsed_at":"2024-01-10T16:07:19.934Z","dependency_job_id":"f2b68bf2-2ab5-48cd-9380-a15a6d0d8dfa","html_url":"https://github.com/cloudfoundry-community/gautocloud","commit_stats":null,"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"purl":"pkg:github/cloudfoundry-community/gautocloud","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudfoundry-community%2Fgautocloud","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudfoundry-community%2Fgautocloud/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudfoundry-community%2Fgautocloud/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudfoundry-community%2Fgautocloud/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/cloudfoundry-community","download_url":"https://codeload.github.com/cloudfoundry-community/gautocloud/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/cloudfoundry-community%2Fgautocloud/sbom","scorecard":{"id":292644,"data":{"date":"2025-08-11","repo":{"name":"github.com/cloudfoundry-community/gautocloud","commit":"f4b1a08ce7ba4cfad7bb638140b723c564dc3ec9"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":3.7,"checks":[{"name":"Code-Review","score":0,"reason":"Found 0/7 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Dangerous-Workflow","score":10,"reason":"no dangerous workflow patterns detected","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Token-Permissions","score":0,"reason":"detected GitHub workflow tokens with excessive permissions","details":["Info: jobLevel 'packages' permission set to 'read': .github/workflows/codeql.yml:37","Info: jobLevel 'actions' permission set to 'read': .github/workflows/codeql.yml:40","Info: jobLevel 'contents' permission set to 'read': .github/workflows/codeql.yml:41","Warn: no topLevel permission defined: .github/workflows/codeql.yml:1","Info: topLevel 'contents' permission set to 'read': .github/workflows/golangci-lint.yml:10","Warn: no topLevel permission defined: .github/workflows/goreleaser.yml:1","Warn: no topLevel permission defined: .github/workflows/unit-tests.yml:1","Info: no jobLevel write permissions found"],"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Pinned-Dependencies","score":0,"reason":"dependency not pinned by hash detected -- score normalized to 0","details":["Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:59: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudfoundry-community/gautocloud/codeql.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:63: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudfoundry-community/gautocloud/codeql.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/codeql.yml:91: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudfoundry-community/gautocloud/codeql.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/golangci-lint.yml:19: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudfoundry-community/gautocloud/golangci-lint.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/golangci-lint.yml:20: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudfoundry-community/gautocloud/golangci-lint.yml/master?enable=pin","Warn: third-party GitHubAction not pinned by hash: .github/workflows/golangci-lint.yml:24: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudfoundry-community/gautocloud/golangci-lint.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/goreleaser.yml:18: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudfoundry-community/gautocloud/goreleaser.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/goreleaser.yml:23: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudfoundry-community/gautocloud/goreleaser.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/goreleaser.yml:28: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudfoundry-community/gautocloud/goreleaser.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/unit-tests.yml:12: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudfoundry-community/gautocloud/unit-tests.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/unit-tests.yml:17: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudfoundry-community/gautocloud/unit-tests.yml/master?enable=pin","Warn: GitHub-owned GitHubAction not pinned by hash: .github/workflows/unit-tests.yml:22: update your workflow using https://app.stepsecurity.io/secureworkflow/cloudfoundry-community/gautocloud/unit-tests.yml/master?enable=pin","Info:   0 out of  11 GitHub-owned GitHubAction dependencies pinned","Info:   0 out of   1 third-party GitHubAction dependencies pinned"],"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":9,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Warn: project license file does not contain an FSF or OSI license."],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"Vulnerabilities","score":8,"reason":"2 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GO-2025-3787 / GHSA-fv92-fjc5-jj9h","Warn: Project is vulnerable to: GO-2025-3595 / GHSA-vvgc-356p-c3xw"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}},{"name":"SAST","score":7,"reason":"SAST tool detected but not run on all commits","details":["Info: SAST configuration detected: CodeQL","Warn: 2 commits out of 26 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}}]},"last_synced_at":"2025-08-17T18:40:35.463Z","repository_id":16297975,"created_at":"2025-08-17T18:40:35.463Z","updated_at":"2025-08-17T18:40:35.463Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279015339,"owners_count":26085685,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cloud-environments","cloud-foundry","heroku","kubernetes","services"],"created_at":"2025-10-13T13:47:27.082Z","updated_at":"2025-10-13T13:47:28.624Z","avatar_url":"https://github.com/cloudfoundry-community.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"\n# Gautocloud [![Build Status](https://travis-ci.org/cloudfoundry-community/gautocloud.svg?branch=master)](https://travis-ci.org/cloudfoundry-community/gautocloud) [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![GoDoc](https://godoc.org/github.com/cloudfoundry-community/gautocloud?status.svg)](https://godoc.org/github.com/cloudfoundry-community/gautocloud)\n\nGautocloud provides a simple abstraction that golang based applications can use\nto discover information about the cloud environment on which they are running,\nto connect to services automatically with ease of use in mind. It provides out-of-the-box support\nfor discovering common services on Heroku, Cloud Foundry and kubernetes cloud platforms,\nand it supports custom automatic connectors.\n\nThis project can be assimilated to the [spring-cloud-connector](https://github.com/spring-cloud/spring-cloud-connectors) project\n but for golang (and with its own concepts).\n\n## Summary\n\n- [Usage by example](#usage-by-example)\n- [Default connectors](/docs/connectors.md)\n- [Community connectors](https://github.com/cloudfoundry-community/gautocloud/wiki/Connectors)\n- [Cloud Environments](#cloud-environments)\n  - [Cloud Foundry](#cloud-foundry)\n  - [Heroku](#heroku)\n  - [Kubernetes](#kubernetes)\n  - [Local](#local)\n- [Concept](#concept)\n  - [Architecture](#architecture)\n  - [Connector registration sequence](#connector-registration-sequence)\n  - [Usage by injection sequence](#usage-by-injection-sequence)\n- [Create your own connector](#create-your-own-connector)\n- [Create your own Cloud Environment](#create-your-own-cloud-environment)\n- [Use it without the facade](#use-it-without-the-facade)\n- [Use mocked facade for your test](#use-mocked-facade-for-your-test)\n- [Run tests](#run-tests)\n- [Contributing](#contributing)\n- [FAQ](#faq)\n\n## Usage by example\n\nLet's define a context: We are in a Cloud Foundry environment where we connect a MySql service on our\napplication.\n\nWe now wants to use this service without parsing a json or anything else to have a MySql client to use our service.\nGautocloud is here to help for this kind of use case.\n\nThis software will retrieve all services found in your environment and will pass informations from service to what we call\na connector. A connector is responsible to create, in our context, a MySql client which make it available in your program.\n\nYou only needs to import a connector to make it usable by gautocloud.\nThis system of import let you have only what you need to run your app (=do not create a huge binary) and let the possibility to create custom connector.\n\nExample (provide a `*net/sql.DB` struct):\n```go\npackage main\nimport (\n        \"fmt\"\n        \"github.com/cloudfoundry-community/gautocloud\"\n        \"os\"\n        log \"github.com/sirupsen/logrus\"\n        _ \"github.com/cloudfoundry-community/gautocloud/connectors/databases/client/mysql\" // this register the connector mysql to gautocloud\n        \"github.com/cloudfoundry-community/gautocloud/connectors/databases/dbtype\"\n)\n\nfunc init(){\n    // Gautocloud use logrus as logger, see: https://github.com/sirupsen/logrus\n    // When using facade, first log messages are emitted with default level from logrus (INFO) and debug message cannot be seen.\n    // To be able to see log message on load simply add the env var `GAUTOCLOUD_DEBUG` to `true`, you will be able to\n    // see debug message from gautocloud (you can also set `json` instead of `true` to see logs as json).\n    log.SetLevel(log.DebugLevel)\n}\n\nfunc main() {\n        appInfo := gautocloud.GetAppInfo() // retrieve all informations about your application instance\n        fmt.Println(appInfo.Name) // give the app name\n        // by injection\n        var c *dbtype.MysqlDB // this is just a wrapper of *net/sql.DB you can use as normal sql.DB client\n        err := gautocloud.Inject(\u0026c) // you can also use gautocloud.InjectFromId(\"mysql\", \u0026c) where \"mysql\" is the id of the connector to use\n        if err != nil {\n                panic(err)\n        }\n        defer c.Close()\n        // c is now useable as a *sql.DB\n        // e.g.: err = c.Ping()\n\n        // or you can also do by return\n        // data, err := gautocloud.GetFirst(\"mysql\")\n        // if err != nil {\n        //         panic(err)\n        // }\n        // c = data.(*dbtype.MysqlDB)\n\n}\n```\n\nImagine now that we have multiple MySql services connected to your Cloud Foundry app, you can also have multiple client:\n```go\npackage main\nimport (\n        \"github.com/cloudfoundry-community/gautocloud\"\n        _ \"github.com/cloudfoundry-community/gautocloud/connectors/databases/client/mysql\" // this register the connector mysql to gautocloud\n        \"github.com/cloudfoundry-community/gautocloud/connectors/databases/dbtype\"\n)\nfunc main() {\n        // by injection\n        var cs []*dbtype.MysqlDB // this is just a wrapper of *net/sql.DB you can use as normal sql.DB client\n        err := gautocloud.Inject(\u0026cs) // you can also use gautocloud.InjectFromId(\"mysql\", \u0026cs) where \"mysql\" is the id of the connector to use\n        if err != nil {\n                panic(err)\n        }\n        // you have now a slice containing all mysql client you can have\n\n        // or you can also do by return\n        // data, err := gautocloud.GetAll(\"mysql\") // a connector may give you different types that's why GetAll return a slice of interface{}\n        // cs = make([]*dbtype.MysqlDB,0)\n        // for _, elt := range data {\n        //        svcSlice = append(cs, elt.(*dbtype.MysqlDB))\n        // }\n\n}\n```\n\n**Tip**: You can either do the same thing without the gautocloud facade, see: [use gautocloud without facade](#use-it-without-the-facade)\n\n## Connectors\n\nDoc for default connectors can be found here: [/docs/connectors.md](/docs/connectors.md).\n\nYou can see connectors made by the community on the dedicated wiki page: https://github.com/cloudfoundry-community/gautocloud/wiki/Connectors\n\n## Cloud Environments\n\n### Cloud Foundry\n\n- **Cloud Detection**: if the `VCAP_APPLICATION` env var exists and not empty\n- **Service detection by name**: Look if a service in `VCAP_SERVICES` match the name required by a connector.\n- **Service detection by tags**: Look if a service in `VCAP_SERVICES` match one of tag required by a connector.\n- **App information id**: id of the app given by Cloud Foundry\n- **App information name**: name of the app given during `cf push`\n- **App information properties**:\n  - `uris`: (type: *[]string*) list of routes associated to the apps.\n  - `host`: (type: *string*) host of the app.\n  - `home`: (type: *string*) root folder for the deployed app.\n  - `index`: (type: *int*) index of the app.\n  - `memory_limit`: (type: *string*) maximum amount of memory that each instance of the application can consume.\n  - `space_id`: (type: *string*) id of the space.\n  - `space_name_id`: (type: *string*) name of the space.\n  - `temp_dir`: (type: *string*) directory location where temporary and staging files are stored.\n  - `user`: (type: *string*) user account under which the container runs.\n  - `version`: (type: *string*) version of the app.\n  - `working_dir`: (type: *string*) present working directory, where the buildpack that processed the application ran.\n\n### Heroku\n\n**Tip**: you can also use in local but settings the env var `DYNO` and create env var corresponding\nto a service you want to connect. (see: [/test-integration/test_integration_test.go](/test-integration/test_integration_test.go) as an example)\n\n- **Cloud Detection**: if the `DYNO` env var exists\n- **Service detection by name**: Look all env var which contains the name required by a connector. Env var key are after parsed to create credentials.\nExample:\n```\nyou have env var:\n- `MY_SVC_NAME=myname`\n- `MY_SVC_HOST=localhost`\n\nConnector required name `SVC`.\nCloudEnv decode `MY_SVC_NAME` to [MY, SVC, NAME] and [MY, SVC, VALUE]\nand detect that there is SVC in those two env var.\nIt returns a service with credentials:\n{\n  \"name\": \"myname\",\n  \"host\": \"localhost\"\n}\n```\n**Note**:\n- if a env var key doesn't contain `_` (e.g.: `SVC=localhost`) it will give those credentials: `{\"svc\": \"localhost\", \"uri\": \"localhost\"}`.\n- If the value of an env var is in json it will be decode the json and pass content as credentials\n\n**Retrieves**:\n- **Service detection by tags**: each tag work like by name.\n- **App information id**: id of the app given by the env var `DYNO`\n- **App information name**: Set the env var `GAUTOCLOUD_APP_NAME` to give a name to your app instead it will be `\u003cunknown\u003e`\n- **App information properties**:\n  - `host`: (type: *string*) host of the app.\n\n### Kubernetes\n\n- **Cloud Detection**: if the `KUBERNETES_PORT` env var exists\n- **Service detection by name**: Look all env var which contains the name required by a connector. Env var key are after parsed to create credentials.\nExample:\n```\nyou have env var:\n- `MY_SVC_SERVICE_NAME=myname`\n- `MY_SVC_SERVICE_HOST=localhost`\n\nConnector required name `SVC`.\nCloudEnv remove `_SERVICE` from the key and decode `MY_SVC_NAME` to [MY, SVC, NAME] and [MY, SVC, VALUE]\nand detect that there is SVC in those two env var.\nIt returns a service with credentials:\n{\n  \"name\": \"myname\",\n  \"host\": \"localhost\"\n}\n```\n**Note**:\n- if a env var key doesn't contains `_` (e.g.: `SVC=localhost`) it will give those credentials: `{\"svc\": \"localhost\", \"uri\": \"localhost\"}`.\n- If the value of an env var is in json it will be decode the json and pass content as credentials\n\n**Retrieves**:\n- **Service detection by tags**: each tag work like by name.\n- **App information id**: id of the app given by the env var `HOSTNAME`\n- **App information name**: Name of the app given by the env var `HOSTNAME`\n- **App information properties**:\n  - `host`: (type: *string*) host of the app.\n  - All values starting by `KUBERNETES` in env vars key.\n\n### Local\n\nThis is a special *CloudEnv* and can be considered as a fake one. This is cloud env is always triggered if none cloud env was found.\n\nYou can also use it to be able to use a config file directly without pain (but it's not 12 factors).\n\nYou can set the env var `CLOUD_FILE` which contains the path of a configuration files containing services.\n\nYou can create a `config file` called `config.yml` in your current working directory or set the env var `CONFIG_FILE`\nwhich contains the path of your config file. It can contain anything you want, this will register by itself a service\nnamed `config` with tag `config` which contains you configuration from the file.\n\nA `config file` or a `cloud file` can be a `yml`, `json`, `toml` or `hcl` file.\n\nA `config file` can contains anything you want, this will register by itself a service named `config` with tag `config`\nwhich contains you configuration from the file.\n\nA `cloud file` must follow this pattern (example in yml):\n```yml\napp_name: \"myapp\" # set the app name you want (it can be not set)\nservices:\n- name: myelephantsql\n  tags: [postgresql, service] # ...\n  credentials:\n    uri: postgres://seilbmbd:PHxTPJSn@babar.elephantsql.com:5432/seilbmbd\n    host: babar.elephantsql.com\n    # ... you can have other credentials\n```\n\nYou can see how to follow the same pattern with other format here: [/cloudenv/local_cloudenv_test.go#L13-L86](/cloudenv/local_cloudenv_test.go#L13-L86).\n\n- **Cloud Detection**: Always detected, used as fallback when no cloud env found.\n- **Service detection by name**: Look if a service in the config file match the name required by a connector.\n- **Service detection by tags**: Look if a service in the config file match one of tag required by a connector.\n- **App information id**: random uuid\n- **App information name**: The name given in the config file, if not set it will be `\u003cunknown\u003e`\n- **App information properties**: *None*\n\n**NOTE**: A `config` service is always created which permit to use [ConfigFileInterceptor](https://godoc.org/github.com/cloudfoundry-community/gautocloud/interceptor/configfile#ConfigFileInterceptor)\nthis is a great interceptor to use with a [generic config connector](https://github.com/cloudfoundry-community/gautocloud/blob/master/docs/connectors.md#config).\n\n## Concept\n\nGautocloud have a lot of black magics but in fact the concept is quite simple.\n\n### Architecture\n\n![Architecture](/docs/arch.png)\n\n- **Loader**: It has the responsibility to find the *CloudEnv* where your program run, store *Connector*s and retrieve\nservices from *CloudEnv* which corresponds to one or many *Connector*, and finally it will pass to *Connector* the service\nand store the result from connector.\n- **Gautocloud *facade***: This facade was made to make things easier for users. It stores one instance of a *Loader*\n and give the ability to make lazy loading (this is why to register a *Connector* you only need to do `import _ \"a/connector\"`)\n- **CloudEnv**: Each *CloudEnv* correspond to a real cloud. It manages the detection of the environment but\nalso the detections of services asked by the *Loader*.\n- **Connector**: A connector register itself on the loader when using *Gautocloud Facade*. It handles the conversion of\na service to a real client or structure which can be manipulated after by user.\n- **CloudDecoder**: This decoder do the conversion of a service to an expected schema.\nIn *Gautocloud* context this decoder is used to convert a given service to an expected schema given by a connector.\nThis decoder can be used in other context. (see: [/decoder/decoder.go](/decoder/decoder.go) to know about it)\n\n### Connector registration sequence\n\n![Connector registration sequence](/docs/reg.png)\n\n### Usage by injection sequence\n\n![Usage injection sequence](/docs/inject.png)\n\n## Create your own connector\n\nThe best way is to look at an example here: [/connectors/connector_example_test.go](/connectors/connector_example_test.go).\n\nYou can also want to see how to create connector with interceptor here: [/connectors/intercepter_example_test.go](/connectors/intercepter_example_test.go).\n\n**Note**:\n- An interceptor work like a http middleware.\nThis permit to intercept data which will be given back by gautocloud and modified it before giving back to user.\nInterceptor should be used in a connector, to do so, connector have to implement ConnectorIntercepter:\n```go\ntype ConnectorIntercepter interface {\n    Intercepter() interceptor.Intercepter\n}\n```\n- Add your connector on the dedicated wiki page: https://github.com/cloudfoundry-community/gautocloud/wiki/Connectors\n\n## Create your own Cloud Environment\n\nThe best way to implement yourself a cloud environment, is to look at the following interface: [/cloudenv/cloudenv.go](/cloudenv/cloudenv.go).\n\nYou will need to load you cloud env after by [use gautocloud without facade](#use-it-without-the-facade),\nyou can either do a pull request to had your cloud environment as builtin by doing a pull request.\n\n## Use it without the facade\n\nWe will take the same example as we see in [Usage by example](#usage-by-example), but we will not use the facade this time:\n\n```go\npackage main\nimport (\n        \"fmt\"\n        \"github.com/cloudfoundry-community/gautocloud/loader\"\n        \"github.com/cloudfoundry-community/gautocloud/cloudenv\"\n        log \"github.com/sirupsen/logrus\"\n        \"os\"\n        \"github.com/cloudfoundry-community/gautocloud/connectors/databases/client/mysql\" // this register the connector mysql to gautocloud\n        \"github.com/cloudfoundry-community/gautocloud/connectors/databases/dbtype\"\n)\n\nfunc main() {\n        // Gautocloud use logrus as logger, see: https://github.com/sirupsen/logrus\n        // In this case reload connectors is not necessary to see logs.\n        log.SetLevel(log.DebugLevel)\n        ld := loader.NewLoader(\n            []cloudenv.CloudEnv{\n                cloudenv.NewCfCloudEnv(),\n                cloudenv.NewHerokuCloudEnv(),\n                cloudenv.NewKubernetesCloudEnv(),\n                cloudenv.NewLocalCloudEnv(),\n            },\n        )\n        ld.RegisterConnector(mysql.NewMysqlConnector()) // you need to manually register connectors\n\n        appInfo := ld.GetAppInfo() // retrieve all informations about your application instance\n        fmt.Println(appInfo.Name) // give the app name\n        fmt.Println(appInfo.Port) // give the port to listen to\n        // by injection\n        var c *dbtype.MysqlDB // this is just a wrapper of *net/sql.DB you can use as normal sql.DB client\n        err := ld.Inject(\u0026c) // you can also use gautocloud.InjectFromId(\"mysql\", \u0026c) where \"mysql\" is the id of the connector to use\n        if err != nil {\n                panic(err)\n        }\n        defer c.Close()\n\n}\n```\n\n## Use mocked facade for your test\n\nIf you need to write your tests with a mocked gautocloud (and use the facade), you can ask to go compiler to get a mocked version.\n\nTo perform this, simply run your test with the tags `gautocloud_mock` (e.g.: `go test -tags gautocloud_mock`).\n\nThe facade will load a [gomock](https://github.com/golang/mock) version of the loader.\nYou can find, for example, how to perform injection with this mocked version here:\n[/test-mock/test_mock_test.go](/test-mock/test_mock_test.go) (see also [gomock documentation](https://github.com/golang/mock) to learn more)\n\n## Run tests\n\nRequirements:\n- [ginkgo](https://onsi.github.io/ginkgo/)\n\nRequirements for integration tests:\n- [docker](https://docs.docker.com/engine/installation/)\n- [docker-compose](https://docs.docker.com/compose/install/)\n\n**Note**: We need docker and docker-compose for integrations to run services and ensure clients works.\n\nSimply run in a terminal `bin/test.sh`.\n\n## Contributing\n\nAny PR or/and issues are welcomes.\n\nDon't be shy to send a PR to add another cloud environment as a builtin one.\n\n## FAQ\n\n**Why do I need to import a connector even if it's a builtin one ?**\n\nYou need to import it because if you didn't have to it, it will require to load all default connectors with\nassociated dependencies to the connector which can make a huge binary.\n\nIn our case, it will compile only what you need by importing the connector.\n\n**Why the *CloudEnv* interface works with a concept of tags and name?**\n\nThis concept comes directly from Cloud Foundry and the way it gives services. Cloud Foundry has an API called\n[service brokers](https://docs.cloudfoundry.org/services/api.html) this api return services with tags and name.\n\nThis concept will now be used in the future by a lot of cloud environment (PaaS and CaaS) because this api have now\na dedicated governance managed by people from Google (Kubernetes in mind), Pivotal (Cloud Foundry), Red Hat (Openshift) ...\nYou can found their website here: https://www.openservicebrokerapi.org/\n\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudfoundry-community%2Fgautocloud","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fcloudfoundry-community%2Fgautocloud","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fcloudfoundry-community%2Fgautocloud/lists"}