Uploaded image for project: 'Brooklyn'
  1. Brooklyn
  2. BROOKLYN-421

Catalog libraries: externalized config for basic-auth credentials in url (via YAML)

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 0.10.0
    • 1.0.0
    • None

    Description

      A customer wants to use YAML catalog items, where the library bundles are retrieved from their Nexus repo using basic-auth. They want the nexus credentials to be stored in an externalized credential store. They want the credentials to be able to contain special characters (e.g. "@") that are not valid in a URL.

      Building up to this, here is what we currently support...

      Either of the catalog items below is valid (i.e. the credentials can be encoded in the url; the library can be supplied either as a string or as a map (where the map currently takes keys of "url", "name" and "version")):

      brooklyn.catalog:
        id: simple-example
        version: "1.0"
        itemType: template
        libraries:
        - url: https://myuser:mypass@nexus.example.com/mybundle.jar
        item:
          ...
      
      
      brooklyn.catalog:
        id: simple-example
        version: "1.0"
        itemType: template
        libraries:
        - https://myuser:mypass@nexus.example.com/mybundle.jar
        item:
          ...
      

      For usernames / passwords with special characters, these need to be escaped before adding to the url. For example, for username "myuser@example.com", the url would be https://myuser%40mydomain.com:mypass@nexus.example.com/mybundle.jar.

      For externalized config, one can use the example below:

      brooklyn.catalog:
        id: simple-example
        version: "1.0"
        itemType: template
        libraries:
        - $brooklyn:formatString:
          - https://%s:%s@nexus.example.com/mybundle.jar
          - $brooklyn:external("myprovider", "username")
          - $brooklyn:external("myprovider", "password")
        item:
          ...
      

      However, this requires that the externalised config stores the username and password in its url-escaped form (rather than as the raw password).

      It also means that the password is embedded in the url, which is potentially logged or persisted.


      We could fix the first of these problems (i.e. credentials store can just supply the raw username/password) by adding DSL support for $brooklyn:escapeUrl. One could write something like:

      brooklyn.catalog:
        id: simple-example
        version: "1.0"
        itemType: template
        libraries:
        - $brooklyn:formatString:
          - https://%s:%s@nexus.example.com/mybundle.jar
          - $brooklyn:escapeUrl:
            - $brooklyn:external("myprovider", "username")
          - $brooklyn:escapeUrl:
            - $brooklyn:external("myprovider", "password")
        item:
          ...
      


      Alternatively (as well?) we could supply the basic-auth credentials as an explicit configuration option. The advantage of this is that we should be able to keep it as the DSL "deferred supplier" so not persist the password.

      For example, something like the YAML below:

      brooklyn.catalog:
        id: simple-example
        version: "1.0"
        itemType: template
        libraries:
        - url: https://nexus.example.com/mybundle.jar
          basicAuth:
            username: $brooklyn:external("myprovider", "username")
            password: $brooklyn:external("myprovider", "password")
        item:
          ...
      

      However, this is fiddly to implement. Looking at the code path for where it eventually loads the bundle over http(s):

      "main" prio=5 tid=0x00007fa34c002000 nid=0x1703 at breakpoint[0x0000700000217000]
         java.lang.Thread.State: RUNNABLE
              at org.apache.brooklyn.util.core.ResourceUtils.getResourceViaHttp(ResourceUtils.java:420)
              at org.apache.brooklyn.util.core.ResourceUtils.getResourceFromUrl(ResourceUtils.java:251)
              at org.apache.brooklyn.util.core.osgi.Osgis.getUrlStream(Osgis.java:421)
              at org.apache.brooklyn.util.core.osgi.Osgis.cacheFile(Osgis.java:369)
              at org.apache.brooklyn.util.core.osgi.Osgis.install(Osgis.java:342)
              at org.apache.brooklyn.core.mgmt.ha.OsgiManager.registerBundle(OsgiManager.java:122)
              at org.apache.brooklyn.core.catalog.internal.CatalogUtils.installLibraries(CatalogUtils.java:160)
              at org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog.collectCatalogItems(BasicBrooklynCatalog.java:494)
              at org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog.collectCatalogItems(BasicBrooklynCatalog.java:428)
              at org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog.collectCatalogItems(BasicBrooklynCatalog.java:417)
              at org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog.addItems(BasicBrooklynCatalog.java:974)
              at org.apache.brooklyn.core.catalog.internal.BasicBrooklynCatalog.addItems(BasicBrooklynCatalog.java:1)
              at org.apache.brooklyn.camp.brooklyn.AbstractYamlTest.addCatalogItems(AbstractYamlTest.java:199)
              at org.apache.brooklyn.camp.brooklyn.AbstractYamlTest.addCatalogItems(AbstractYamlTest.java:195)
              at org.apache.brooklyn.camp.brooklyn.catalog.CatalogOsgiVersionMoreEntityTest.testLibraryUrlsUsingExternalizedConfig(CatalogOsgiVersionMoreEntityTest.java:318)
      

      One needs to go all the way back to OsgiManager.registerBundle before we have the CatalogBundle object - after that, we only have the URL string. So that is a lot of methods that would need to change!

      Attachments

        Activity

          People

            Unassigned Unassigned
            aled.sage Aled Sage
            Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

              Created:
              Updated:
              Resolved: