Giter Club home page Giter Club logo

cloudenvironment's Introduction

Kitura

APIDoc Build Status - Master macOS Linux Apache 2 Slack Status

CloudEnvironment

CloudEnvironment (formerly known as CloudConfiguration) is a convenience Swift package for accessing environment variables mapped to JSON objects from various Cloud computing environments, such as, but not limited to, Cloud Foundry and Kubernetes.

For example, to obtain the credentials for accessing a Cloudant database, you need to parse the VCAP_SERVICES environment variable when running in Cloud Foundry, while to obtain the same credentials when running in Kubernetes, you may need to parse an environment variable named CLOUDANT_CREDENTIALS. In other words, the path for obtaining certain environment values may differ from one cloud environment to another. By leveraging this package, you can make your Swift application environment-agnostic when it comes to obtaining such values. Using CloudEnvironment allows you to abstract these low-level details from your application's source code.

Swift version

The latest version of CloudEnvironment works with 4.0 and newer versions of the Swift binaries. You can download Swift binaries by following this link.

Abstraction and supported search pattern types

This package allows you to define a lookup key that your Swift application can leverage when searching for its corresponding value. This abstraction decouples your application from the actual name used for the environment variable you are looking for. For example, if you created a Cloudant service named my-awesome-cloudant-db, you don't have to use this name as the key in your Swift code to obtain its credentials. Instead, you can define a lookup key, say cloudant-credentials and map it to the actual service name, my-awesome-cloudant-db.

This library also allows you to define an array of search patterns for looking up a JSON object which is mapped to an environment variable, such as service credentials. Each element in the search patterns array will be executed until the variable is found. CloudEnvironment supports searching for values using the following three search pattern types:

  • cloudfoundry - Allows you to search for a value in Cloud Foundry's services environment variable (i.e. VCAP_SERVICES).
  • env - Allows you to search for a value mapped to an environment variable.
  • file - Allows you to search for a value in a JSON file.

You specify lookup keys and search patterns in a file named mappings.json. This file must exist in a config folder under the root folder of your Swift project. The following shows an example of a mappings.json file:

{
    "cloudant-credentials": {
        "credentials": {
            "searchPatterns": [
                "cloudfoundry:my-awesome-cloudant-db",
                "env:my_awesome_cloudant_db_credentials",
                "file:localdev/my-awesome-cloudant-db-credentials.json"
            ]
        }
    },
    "object-storage-credentials": {
        "credentials": {
            "searchPatterns": [
                "cloudfoundry:my-awesome-object-storage",
                "env:my_awesome_object_storage_credentials",
                "file:localdev/my-awesome-object-storage-credentials.json"
            ]
        }
    }
}

In the example above, cloudant-credentials and object-storage-credentials are the lookup keys your Swift application should use to look up the corresponding credentials. Please note that the path next to the file search pattern must be relative to the root folder of your Swift application.

Usage

Add dependencies

Add the CloudEnvironment package to the dependencies within your application’s Package.swift file. Substitute "x.x.x" with the latest CloudEnvironment release.

.package(url: "https://github.com/Kitura/CloudEnvironment.git", from: "x.x.x")

Add CloudEnvironment to your target's dependencies:

.target(name: "example", dependencies: ["CloudEnvironment"]),

Once the Package.swift file of your application has been updated, import the CloudEnvironment modules and initialize an instance of CloudEnvironment:

import CloudEnvironment

let cloudEnv = CloudEnv()

Once you have a cloudEnv instance you can use it to query the credentials for one of the supported services, such as, Cloudant or ObjectStorage, as shown below this will return the credentials associated with that service:

let cloudantCredentials = cloudEnv.getCloudantCredentials(name: "cloudant-credentials")
// cloudantCredentials.username, cloudantCredentials.password, cloudantCredentials.url, etc.
let objStorageCredentials = cloudEnv.getObjectStorageCredentials(name: "object-storage-credentials")
// objStorageCredentials.username, objStorageCredentials.password, objStorageCredentials.projectID, etc.

let service1Credentials = cloudEnv.getDictionary("service1-credentials")
let service1CredentialsStr = cloudEnv.getString("service1-credentials")

// Get a default PORT and URL
let port = cloudEnv.port
let url = cloudEnv.url

This library simplifies obtaining service credentials, as shown above. For details on the different elements (e.g. username, password, url, etc.) that make up a credentials set and accessor methods for service credentials, check out the API reference documentation.

Following the above approach your application can be implemented in a runtime-environment agnostic way, abstracting differences in environment variable management introduced by different Cloud computing environments.

Supported services

The following services are currently supported by this library. Therefore, you can obtain the service credentials for any of these services with minimum effort:

If you don't see listed above the service you intend to use in your Swift application, you can leverage the generic getDictionary(name: String) method to get the corresponding credentials:

import CloudEnvironment

let cloudEnv = CloudEnv()

if let credentials: [String:Any] = cloudEnv.getDictionary(name: "service1-credentials") {
  // You can now get the corresponding values from the dictionary
}

API documentation

For more information visit our API reference.

Community

We love to talk server-side Swift, and Kitura. Join our Slack to meet the team!

License

This library is licensed under Apache 2.0. Full license text is available in LICENSE.

cloudenvironment's People

Contributors

andrew-lees11 avatar dannys42 avatar djones6 avatar enriquel8 avatar helenmasters avatar ianpartridge avatar mbarnach avatar rfdickerson avatar rob-deans avatar rolivieri avatar sandmman avatar seabaylea avatar shihabmehboob avatar tfrank64 avatar youming-lin avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

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

cloudenvironment's Issues

CloudConfiguration 2.x is not compatible with Swift 3.0.2

It would be nice if CloudConfiguration maintained some level of back-compatibility with Swift. For example, Kitura 1.7 works with Swift 3.0.2 and Swift 3.1.1.

Currently I am seeing the following error when compiling my project on Swift 3.0.2 when using CloudConfiguration 2.x:

/tmp/041ffec28bc23291ae0b059c3a2123aa393d3991/swiftserver/Packages/CloudFoundryEnv-4.0.2/Sources/CloudFoundryEnv/AppEnv.swift:184:23: error: use of unresolved identifier 'NSRegularExpression'
      let regex = try NSRegularExpression(pattern: spec, options: NSRegularExpression.Options.caseInsensitive)
                      ^~~~~~~~~~~~~~~~~~~
Foundation.RegularExpression:1:12: note: did you mean 'RegularExpression'?
open class RegularExpression : Foundation.NSObject, NSCopying, NSCoding {
           ^
/tmp/041ffec28bc23291ae0b059c3a2123aa393d3991/swiftserver/Packages/CloudFoundryEnv-4.0.2/Sources/CloudFoundryEnv/AppEnv.swift:184:67: error: use of unresolved identifier 'NSRegularExpression'
      let regex = try NSRegularExpression(pattern: spec, options: NSRegularExpression.Options.caseInsensitive)
                                                                  ^~~~~~~~~~~~~~~~~~~
Foundation.RegularExpression:1:12: note: did you mean 'RegularExpression'?
open class RegularExpression : Foundation.NSObject, NSCopying, NSCoding {
           ^
<unknown>:0: error: build had 1 command failures

Add AppID

  • Add AppID to CloudConfiguration
  • Add AppID partial to the generator-swiftserver
  • Add AppID partial to generator-web

Support finding configuration information from other platforms or config structures

Right now, CloudConfiguration relies very heavily on the conventions of VCAP_SERVICES. We should allow the configuration information to come from not only a path inside VCAP_SERVICES, and instead multiple paths that could be compatible with other platforms like Heroku, Amazon AWS, and our Docker deployment.

In other words, we should should support loading files with data that has been the result of something like this:

cf env MyApp > config.json

But often times, the user will want something even easier, especially the Docker case:

Some examples:

I think that a typical config.yml used for a Docker deployment could look like:

- port: 8080
- services:
    - postgresql
        - username: robert
        - password: pa55w0rd
        - hostname: postgresql.bluemix.net 

CloudEnvironment.Credentials is incompatible with Kitura-Credentials (or the other way around)

If both modules CoudEnvirnment and Kitura-Credentials (Credentials) is imported, the type Credentials is ambiguous for the compiler. It looks like it's a compiler limitation https://bugs.swift.org/browse/SR-6705 so It may be a good idea to address the issue on the source level. Since CloudEnvironment is often used with the Kitura framework, it may be a good idea to clarify the Credentials type.

Kitura-Credentials report: Kitura/Kitura-Credentials#36

import CloudEnvironment
import Credentials

public class App {
    let credentials: Credentials.Credentials
}
Application.swift:18:22: error: 'Credentials' is ambiguous for type lookup in this context
    var credentials: Credentials.Credentials
                     ^~~~~~~~~~~
CloudEnvironment.Credentials:4:14: note: found this candidate
public class Credentials {
             ^
Credentials.Credentials:2:14: note: found this candidate
public class Credentials : RouterMiddleware {
             ^

Hardcoded "Bluemix" URLs

In some places, bluemix.net is hardcoded. At the minimum, this must be upgraded to cloud.ibm.com, if not removed entirely.

PushSDKCredentials.swift - CloudEnvironment can be used on other cloud providers (esp given OpenShift will be coming…) but in this code I see “bluemix.net” hardcoded - is that supposed to be there?

   guard let host = url.host,
     host.hasSuffix(“.bluemix.net”)
   else{
     return nil
   }
   let parts = host.split(separator: “.”).suffix(3)
   guard parts.count > 2 && parts.first != “imfpush” else {
     return nil
   }
   return parts.joined(separator: “.”)
 }```

Allow for a default load order as a convention

Configuration allows for a very rich way to specify multiple sources for configuration information with priority ordering. However, for many applications, a convention that does the equivalent of:

let config = ConfigurationManager
                                 .load(file: "config.json")
                                 .load(.environmentFiles)
                                 .load(.commandLineArguments)

So that the user simply has to do:

let config = ConfigurationManager.default()

Redis returns Int instead of Int32

Kitura-Redis expects Int32 for the port and as a result using the service and getting the port from it causes a compilation error:

redis?.connect(host: redisService.host, port: redisService.port) { (redisError: NSError?) in

Allow obtaining a service without specifying its name.

In other words, instead of:

if let psqlService = ConfigurationManager.getPostgreSQLService("MyPostgreSQLService") {}

You can simply do:

if let psqlService = ConfigurationManager.getPostgreSQLService() {}

The rationale is that the majority of projects will only have a single database of that given type in the application that has been configured. So we should have this option available to them.

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.