Aled Sage created BROOKLYN-421:
----------------------------------

             Summary: Catalog libraries: externalized config for basic-auth 
credentials in url (via YAML)
                 Key: BROOKLYN-421
                 URL: https://issues.apache.org/jira/browse/BROOKLYN-421
             Project: Brooklyn
          Issue Type: Bug
    Affects Versions: 0.10.0
            Reporter: Aled Sage


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")):

{noformat}
brooklyn.catalog:
  id: simple-example
  version: "1.0"
  itemType: template
  libraries:
  - url: https://myuser:[email protected]/mybundle.jar
  item:
    ...


brooklyn.catalog:
  id: simple-example
  version: "1.0"
  itemType: template
  libraries:
  - https://myuser:[email protected]/mybundle.jar
  item:
    ...
{noformat}

For usernames / passwords with special characters, these need to be escaped 
before adding to the url. For example, for username "[email protected]", the 
url would be 
{{https://myuser%40mydomain.com:[email protected]/mybundle.jar}}.

For externalized config, one can use the example below:

{noformat}
brooklyn.catalog:
  id: simple-example
  version: "1.0"
  itemType: template
  libraries:
  - $brooklyn:formatString:
    - https://%s:%[email protected]/mybundle.jar
    - $brooklyn:external("myprovider", "username")
    - $brooklyn:external("myprovider", "password")
  item:
    ...
{noformat}

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:

{noformat}
brooklyn.catalog:
  id: simple-example
  version: "1.0"
  itemType: template
  libraries:
  - $brooklyn:formatString:
    - https://%s:%[email protected]/mybundle.jar
    - $brooklyn:escapeUrl:
      - $brooklyn:external("myprovider", "username")
    - $brooklyn:escapeUrl:
      - $brooklyn:external("myprovider", "password")
  item:
    ...
{noformat}

---
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:

{noformat}
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:
    ...
{noformat}

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

{noformat}
"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)
{noformat}

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!




--
This message was sent by Atlassian JIRA
(v6.3.4#6332)

Reply via email to