Updating application config does not persist

#1

When I update an application’s config in the UI the changes to Permissions (or any other section) is not persistent.

After I change the settings and click “Update”, i see the changes visible. Now, if i refresh the browser window, the changes I made are no longer visible and its basically been reverted. I can confirm this behavior with another member of my team.

Now, if i use the API to update those settings, they are persistent.

We do see in the changes in the S3 bucket, which is really strange.

We are using spinnaker 1.12.9.

I’d appreciate any tips on what potentially could be going on here.

Thanks,

Sijis

#2

So i’ve got to the point of where to be able to modify the pipeline again.
I had to do the following:

  • Go into the s3 bucket and find my app
  • Modify the application-metadata.json and delete the following keys within the file attributes and cluster.
  • Upload the changed file
  • Reload the app in UI.

After that above I was able to change config in the UI again.

Any ideas what issue is causing this behavior that i’ll need to do this?

#3

Sijis and I came up with a script for the workaround while we wait for a concrete solution.

#!/usr/bin/env python3
"""Removes faulty keys from Spinnaker Application metadata in Front50 S3 Bucket.

* https://community.spinnaker.io/t/updating-application-config-does-not-persist/1230/2

This fixes the UI issue where modifying the Application configuration does not
persist across page reloads.

Requires:

..code-block:: bash

   pip install boto3 click

"""
import io
import json

import boto3
import click

BUCKET = 's3-bucket-name'
OBJECT_NAME_FORMAT = 'front50/applications/{application}/application-metadata.json'


def download(bucket_name='', object_name=''):
    """Download metadata file and convert to :obj:`dict`.

    Args:
        bucket_name (str): Name of S3 Bucket.
        object_name (str): Path to file in S3 Bucket.

    Returns:
        dict: Metadata JSON converted into native object.

    """
    client = boto3.client('s3')

    metadata = io.BytesIO()
    client.download_fileobj(bucket_name, object_name, metadata)
    content = json.loads(metadata.getvalue())

    return content


def upload(bucket_name='', content='', object_name=''):
    """Upload modified metadata to S3.

    Args:
        bucket_name (str): Name of S3 Bucket.
        content (dict): Spinnaker Application metadata.
        object_name (str): Path to file in S3 Bucket.

    Returns:
        bool: :obj:`True` when upload successful.

    """
    modified_content = json.dumps(content, indent=2)
    modified_metadata = io.BytesIO(modified_content.encode())

    client = boto3.client('s3')
    client.upload_fileobj(modified_metadata, bucket_name, object_name)

    return True


@click.command()
@click.option('--application', '-a', required=True, help='Name of Spinnaker Application')
def main(application):
    """Remove fault keys from Spinnaker Application metadata file.

    Download the Front50 metadata file from S3 and remove the bad keys.

    """
    object_name = OBJECT_NAME_FORMAT.format(application=application)

    content = download(bucket_name=BUCKET, object_name=object_name)

    if content.pop('attributes', None):
        click.echo('Deleted "attributes"')

    if content.pop('clusters', None):
        click.echo('Deleted "clusters"')

    upload(bucket_name=BUCKET, object_name=object_name, content=content)

    click.echo(f'Fixed {application}')


if __name__ == '__main__':
    main()  # pylint: disable=no-value-for-parameter