[PYTHON] Points to consider when hitting SoftLayer API from an app on Bluemix

What is not written in Qiita is nothing but a failure of technical material, so I have to drive myself here [SoftLayer Advent Calendar 2015](http://qiita.com/ I registered with advent-calendar / 2015 / softlayer). If I didn't do this, I would feel that there was no technical material, but Iloilo made me unable to write at all. I think it will increase from next year (more drive).

Now. Recently, at an in-house Python study session, there was a plan to hit SoftLayer's API using Python on Bluemix! I wrote Python code with such a story, and I was ashamed to write [github](https: //) It is published on github.com/sho7650/python03). This time, I thought I should touch on the background of having to write such code, not the code itself, so I wrote it. It's not that I'm tired of explaining what I wrote. By all means.

Prerequisite knowledge and objects to read after this

It's very limited, but it's probably only useful to those who seem to be limited.

Points to consider when hitting SoftLayer API etc. with a web application

The title has changed to plain, but it's not really a limited story like Bluemix or SoftLayer, it's a general concept. This time, I happened to write the code that hit SoftLayer's API on Bluemix, so it is written in such a limited way. When you want to put the code, or when you want to try it, it's better that the code exists. Must be good.

Now. Infrastructure engineers who have tried writing batches by hitting SoftLayer's API or slcli (don't limit it), what happened to the USER ID and API key?

Not disappointing to me, most of you are glaring at the USER ID and API key in the shell. Is it wrong? If anyone says it's not in the shell, you may not need to read it anymore.

Don't write the API key as it is in the program

Suddenly I showed the points to consider in the title, but this is it. It's not limited to API keys, but it is common to have data that can be changed and data that is used by showing multiple options, rather than being hard-coded in the program. "Of course.

why

Data and passwords can change, but having to change the program at that time is problematic. There are two things that just come to mind.

Security issues

We know that if the program itself is versioned or if the program itself is accessible, the contents of the data will be visible. Therefore, if you write a key or password in the program that you don't want to see, it will look like someone who shouldn't see it. Like passwords, SoftLayer API keys are important data items that should not be leaked, so do not write them directly in your program.

For security reasons, it is desirable to be able to manage programs and data separately.

Administrative issues

The other is that every time I change the content of the data and commit, the release goes up even though I haven't changed the program logic at all. As the release goes up, there will be a rule that the logic itself, as well as the application regression test must be performed. CI may run the test automatically, even if there are no rules. It's a waste of resources and time. Also, even though there is no change in the program itself, only the release goes up, so it is nothing but waste to record the changed part.

In that respect, if you store your data in a separate location from your logic, you won't need to retest your application logic if changes occur (though many would like to do it).

Therefore, separate the SoftLayaer API key in your program without hard code and write it somewhere else.

So where? There are four patterns, each of which will be explained below.

  1. Have them enter the API key
  2. Save the API key in a separate file
  3. Register the API key in the DB
  4. Register the API key in the environment variable

1. Have them enter the API key

It is a method to input using the input field one by one. Since the data is not stored anywhere, some people may think that it is ('∀`) b good! For security reasons. However, Bluemix is "http" when you use it casually without doing anything. Also, although it may reduce usability if you enter that long one every time, there is a risk that the API key will be stored somewhere else and leaked from there.

In the first place, if the site you want to enter is a phishing site ... It seems that this method is not recommended because it is endless when you think about it.

2. Save the API key in a separate file

This is a good way to do it. However, there are three things to keep in mind. It is essential that it cannot be accessed from the outside and can only be accessed by the necessary users. However, in such cases, the program and data file are often placed on the same server, and if the program administrator does the appropriate thing, the data may be accessible. Then, one developer can easily access the data file, so be careful from that point of view.

  1. Place it as static content in a location that cannot be accessed from the outside. A directory higher than DocumentRoot in Apache.
  2. Make sure that the user privileges are accessible only to the developers who should use them, which cannot be accessed as static content.
  3. Encrypt if possible. However, the question of what to do with that key always comes up.

There may be a way to place it as an external file on the file server behind it and separate the administrator of the data file, but I feel that the access method to that file is troublesome. Somehow.

3. Register the API key in the DB

The current trend is that it will be this. All changeable data is placed in the DB like other data. What's good about this is that it's easy to arrange for data management to be completely different from the program's administrator. That said, there are some things to watch out for.

  1. Users who can access the DB from the program should have only the minimum required access rights. If the user who uses the application can control the data itself that can access the DB, the developer can also leave it alone.
  2. Separate the app and DB. If you set it to a logically different server so that the DB server can only be accessed programmatically, there are fewer ways to freely view the data in the DB. It will be a little safe.
  3. Still, let's encrypt it. Again, the question of what to do with the encryption key comes up, but not so much if you have fine-grained access control to your data before that. This is done in the aspect that the data administrator does not know when the record is accessed.

4. Register the API key in the environment variable

If the application server is started as a child process from the shell, you can also specify it in the environment variable.

However, if the executor always defines the value in the environment variable and then starts the application, the environment variable cannot be used as a safe method. It's a very bad usability method. Especially when you want to execute it with Bluemix, you need to specify the execution method and shell script to execute it in manifest.yml and start it. In this case, after all, you will put an instruction to assign data to environment variables in the shell script, so the management method will be the same as storing it in a separate file. For the time being, it would be possible to separate the person who writes the shell to start and the person who writes the logic, but the files of each other will be completely visible.

other...?

I just came up with another method but forgot it. I will write it if I remember (´ ・ ω ・ `)

This time, the method realized

For the method I implemented this time, I chose the method of "registering the API key in the DB".

Since Django has a user management function as standard, we have made it possible to change the target SoftLayer site for each user by associating that user with the "username" and "API KEY" registered in the DB. Somehow, that seemed to be more convenient.

This time, I made a part to display the list of accounts registered by the corresponding SoftLayer user. In the source code, it is located at ʻaccounts / views.py`.

views.py


def account_list(request):
    loginname = None
    if request.user.is_authenticated():
        loginname = request.user.username
    username = CustomUser.objects.get(username=loginname)
    user   = softlayer_api.objects.get(pk=username.softlayer_id)
    client = SoftLayer.create_client_from_env(username=user.username, api_key=user.api_key)
    acct   = client['Account'].getUsers()
    return render_to_response('account_list.html', {'accounts': acct}, context_instance=RequestContext(request))

This def declaration is preceded by @ login_required so that only authenticated logged-in users can access it. Even so, I first make sure that I'm the user who has properly authenticated and accessed loginname.

Using that loginname as a key, I have read the SoftLayer information registered in the DB. It is the part of ʻusername = and ʻuser =. At this time, the ʻuser variable contains the ʻusername ʻapi_key` information of SoftLayer registered in the DB.

The next part, client =, is actually calling the SoftLayer API with the specified SoftLayer User. ʻAcct = gets all SoftLayer user information registered with .getUsers () from that user information. Finally, you're doing render_to_response` to display all that information.

In this way, it is not possible to know information such as ʻusername and ʻapi_key of SoftLayer from the program. Also, depending on the logged-in user, it is possible to switch between SoftLayer users, so I made it myself and got euphoric.

Summary

If you want to hit the SoftLayer API from a web app on Bluemix, you can do the following.

  1. Store API information in DB
  2. Keep the DB in a logically and physically separate location from the app
  3. Separate program and data managers

How to use the sample program created this time is properly posted on github, so please try it as it is. It should work.

However, since sqlite does not encrypt any data, try using another server for the DB.

Recommended Posts

Points to consider when hitting SoftLayer API from an app on Bluemix
Points to note when switching from NAOqi OS 2.4.3 to 2.5.5
Hit Watson's REST API from Python on IBM Bluemix
Save Bluemix IaaS (formerly SoftLayer) quotes to PDF via API
(Note) Points to be addicted to when installing Scilab on ArchLinux
Things to note when running Python on EC2 from AWS Lambda