rubrikinc / rubrik-extension-for-vcd

VMware Cloud Director Extension for Rubrik CDM
https://build.rubrik.com/tooling-integrations/rubrik-extension-for-vcloud-director/
MIT License
8 stars 3 forks source link

Documentation to automate the plugin configuration for tenants #45

Open odraghi opened 3 years ago

odraghi commented 3 years ago

What would you like to be added: Documentation to automate the configuration of the plugin for tenants. My understanding is that you add 2 metadatas on the VDC rbk-connection (string) and rbk-feature (String). Can you add in the documentation how you construct the json you put inside ?

Why is this needed: We need to automate the configuration of the plugin for tenants.

b0xCH commented 3 years ago

I'd also add myself to this request. We're automating the deployment of our cloud solution, however, we always need to manually set those two values because we dont know the hashing mechanism. Could you provide a manual or some sort of API on Rubrik to generate such values?

rmjstn commented 2 years ago

Works with pre-release v2.0 EA.

I was able to automate the declaration of tenants through the vCloud API.

The information is stored as Metadata in the organization level in vCloud. This data is encrypt. In the plugin source file (bundle.js include in the plugin.zip), we can see the format of the JSON structure, the way it's encrypted and the method API used.

                }, e.prototype.hashSalt = function(t, e) {
                    var n = e.toString();
                    return Gt.AES.encrypt(t.toString(), n, {
                        keySize: 32,
                        mode: Gt.mode.CBC,
                        padding: Gt.pad.Pkcs7
                    })

The metadata after a base64 decode is in the following format : b'Salted__\xba\xa4+\xf7\x80;^\xcb\xff\xbftO\xcb\xf7eu!r\xb1\xf1\\Z<D\x14\x19F\xfaiS\xc0\x8aPr\xcf_\xbc\xe8\x10/Jzm\xdb\x07\x9c\xcb\xde\x03}\xdd\xb8!B*\xeb...

With the 16 bits (after the "Salted__" string) and the vCloud organization ID we can deduce the key and the initialization vector. With that, we can decrypt the metadata to see the JSON format (the same as in the bundle.js file).

SALT_HEADER="Salted__"
KEY_SIZE=32
IV_SIZE=16

def derive_key_and_iv(password, salt):
    d = d_i = b''
    while len(d) < KEY_SIZE + IV_SIZE:
        d_i = md5(d_i + str.encode(password) + salt).digest()
        d += d_i
    return d[:KEY_SIZE], d[KEY_SIZE:KEY_SIZE+KEY_SIZE]

def decrypt(metadata, organization_id):
    metadata=b64decode(metadata)
    salt = metadata[len(SALT_HEADER):IV_SIZE]
    key, iv = derive_key_and_iv(organization_id, salt)
    cipher = AES.new(key, AES.MODE_CBC, iv)
    decypted_metadata=cipher.decrypt(metadata[IV_SIZE:])
    encoder = PKCS7Encoder()
    unpadded_metadata=encoder.decode(decypted_metadata.decode())
    return unpadded_metadata
{
   "cloudDirectorOrgId":"***",
   "cloudDirectorOrgName":"***",
   "rubrikAddress":"***",
   "profileAuthUsername":"***",
   "profileAuthPassword":"***",
   "profileAuthToken":"",
   "rubrikOrgId":"***",
   "rubrikOrgName":"***",
   "isTokenBasedAuthentication":false,
   "SSOEndpoint":"",
   "rubrikPluginFeatures":{
      "reports":true,
      "dashboard":true,
      "activity":false,
      "singleSignOn":false,
      "restore":true,
      "export":false,
      "fileRecovery":false,
      "exclusion":false,
      "events":false
   }
}

Once the format has been deduced, it's easy publish the plugin for the organization via the vCloud API and encrypt and save the metadata via the the vCoud API.

def encrypt(metadata, organization_id):
    salt = urandom(IV_SIZE - len(SALT_HEADER))
    key, iv = derive_key_and_iv(organization_id, salt)
    encoder = PKCS7Encoder()
    cipher = AES.new(key, AES.MODE_CBC, iv)
    metadata_padded = encoder.encode(metadata)
    metadata_encrypted=str.encode(SALT_HEADER) + salt + cipher

For the Rubrik side, the creation of the users, organizations, roles, authorisations... is done through API calls. I used a browser Developer Tools to get the API methods.

Rémy

rmjstn commented 2 years ago

The metadata format change in 2.0.1. You have to add the feature "assignSla".

{
    "cloudDirectorOrgId": "***",
    "cloudDirectorOrgName": "***",
    "rubrikAddress": "***",
    "profileAuthUsername": "***",
    "profileAuthPassword": "***",
    "profileAuthToken": "",
    "rubrikOrgId": "Organization:::***",
    "rubrikOrgName": "***",
    "isTokenBasedAuthentication": false,
    "SSOEndpoint": "",
    "rubrikPluginFeatures": {
        "reports": true,
        "dashboard": true,
        "activity": true,
        "singleSignOn": false,
        "restore": false,
        "export": false,
        "fileRecovery": true,
        "exclusion": true,
        "events": true,
        "assignSla": true
    }
}

Rémy