Search code examples
ambari

How to programmatically change Ambari admin password


​I am working on automating the installation and provisioning of clusters, which includes installing Ambari and using a Blueprint via the API. This is all working fine, but I have one more thing which I'm having trouble with, and that is changing the Ambari password during the overall provisioning process (I'm referring to my process here, not the Ambari cluster creation process). What I do NOT want is to leave newly provisioned Ambari installs sitting around with the default "admin/admin" credentials, and I also can't have a human going in to change this every time.

I've tried the REST API, but even though the call appears to execute correctly (eg, no errors are returned), the new password never takes effect.

I thought about using the ambari-admin-password-reset command via ssh, but my Ambari install (using 2.1.0) doesn't appear to have that command. I've double checked that the agent is running, and I've tried it as the root user, and in every case, it yields a "command not found" error.

I also thought about using JDBC, connecting directly to Postgres, and munging the password directly, but I'm not sure which hash algorithm Ambari uses, and/or where it stores the salt (if one is used).

If anyone can provide any advice on how to make any or all of these approaches work, it would be greatly appreciated. Right now I'm about to tear my last hair out fighting with this.

Edit: FWIW, here's what I'm doing with my call to the REST API, which seems to fail silently.

public static void main( String[] args )
{


    // make REST call to Ambari to change password
    try (CloseableHttpClient httpClient = HttpClientBuilder.create().build()) 
    {
        HttpHost target = new HttpHost("admin.test-cluster-6.example.com", 8080, "http");

        String authorizationEncoded = Base64.encodeBase64String( "admin:admin".getBytes() );

        // specify the put request
        HttpPut putRequest = new HttpPut( "/api/v1/users/admin" );

        StringEntity jsonEntity = new StringEntity( "{\"Users/password\":\"newpassword\"}" );

        putRequest.setEntity( jsonEntity );
        putRequest.setHeader( "X-Requested-By:", "ambari");
        putRequest.setHeader("Authorization", "Basic " + authorizationEncoded);

        System.out.println("executing request to " + target);

        HttpResponse httpResponse = httpClient.execute(target, putRequest);
        HttpEntity entity = httpResponse.getEntity();
        System.out.println( "status: " + httpResponse.getStatusLine());
        InputStream is = entity.getContent();
        String responseBody = streamToString( is );

        System.out.println( "response: " +  responseBody );

    } 
    catch (IOException e) 
    {
        e.printStackTrace();

    }

    System.out.println( "done" );
}

Doing this yields the output

status: HTTP/1.1 200 OK

Which would lead one to believe that the operation succeeded. But no dice.

Also this is Ambari 2.1.0 and the same behavior occurs regardless of which user's password you try to change.


Solution

  • You have the correct URL but the json you're sending is not correct. It should be of the form:

    {
      "Users": {
        "user_name": "myusername",
        "old_password": "myoldpassword",
        "password": "mynewpassword"
      }
    

    }

    This is detailed on this page in the ambari wiki.