@minso_minso/openstack
v0.3.3
Published
Openstack client
Downloads
17
Readme
README
Promise based library to interact with the Openstack APIs. Currently only implemented a part of Keystone and Swift but that will probably increase over time.
For even better understanding of how the different APIs work, the unit tests should provide some more context.
Usage
To use this package you have to have credentials for your Openstack implementation. Either regular credentials (username/password) or application credentials (id/secret) can be used.
Get started
npm install @minso_minso/openstack
- Create credentials object to be used in all the parts of the library, either password:
import { AuthContext, Storage } from '@minso_minso/openstack'
const context: AuthContext = {
authType: 'password',
baseUrl: 'https://auth.google.se',
endpoint: '/v2/myauth', // optional, defaults to `/v3/auth/tokens` if omitted
credentials: {
domain: 'default',
name: 'username',
password: 'password',
},
project: 'myproject',
authPort: 5000,
}
- Or application, same as above except for
authType
andcredentials
:
import { AuthContext, Storage } from '@minso_minso/openstack'
const context: AuthContext = {
authType: 'application_credential',
baseUrl: 'https://auth.google.se',
endpoint: '/v2/myauth',
credentials: {
id: 'myappid',
secret: 'a1ATIsk9bm5rE2d0qGL6',
},
project: 'myproject',
authPort: 5000,
}
Storage
The Storage module is an abstraction of the Swift REST API. It is used for creating containers and working with storage objects.
const storage = new Storage(context)
Create container
const newContainer = await storage.createContainer('newContainer', {
metadata: { custom: 'customMetadata' },
})
Get container(s)
// List all containers:
const allContainers = await storage.getContainers()
// Get one container
const myContainer = await storage.getContainer('my-container')
Remove container
await myContainer.remove()
Container content
To create a file you can provide the data as a file path or an object with a buffer or a stream as well as the content type as the first argument. The second argument is the file name to add in the container.
You can also add options as the third argument such as custom metadata or if the container should be created if it does not exist.
const file = await newContainer.uploadFile('path/to/file.pdf', 'filename.pdf')
// OR:
const secondFile = await storage.uploadFile(
{ contentType: 'application/pdf', data: fs.createReadStream('path/to/file.pdf') },
'non-existing-container',
'filename.pdf',
{
// to create the container if it does not exist
createContainer: true,
metadata: { foo: 'bar' },
}
)
When listing the container content you can pass { forceRefresh: true }
in cases where other services might write to the same bucket and ensure that you always get fresh data.
const files = await myContainer.listFiles({ forceRefresh: true })
// Or you can manually refresh:
await myContainer.refresh()
To remove files in batch from a container you can use the removeFiles
method. It has an optional parameter which is a filter function that accepts a function with the same same signature as Array.prototype.filter
where the array is an array of [[StorageObject]]
const myContainer = await storage.getContainer('my-container')
// Remove _ALL_ files
await myContainer.removeFiles()
// Remove the first file and all other files with size of 1 byte or less
const filterFunc = (file: StorageObject, i: number) => {
const sizeCondition = file.bytes <= 1
const isFirst = i === 0
return sizeCondition || isFirst
}
await myContainer.removeFiles(filterFunc)
// Manually remove files:
for (const file of await myContainer.listFiles()) {
if (someCondition) {
file.remove()
}
}
To download a file you first need to find the [[StorageObject]] you want. This can be done by [[Container.listFiles]] or [[Storage.getFile]] and then calling download on that instance. The file contents will be returned as a ReadStream. In future releases it will be possible to provide what response type you want.
const containerFiles = await myContainer.listFiles()
const firstFile = containerFiles.find((f) => f.name === 'file.pdf')
const firstData = await firstFile.download()
// Note that you can pass either a container name or a container instance as the
// first argument here. So both `'my-container'` and `myContainer` would be valid.
const directAccess = await storage.getFile('my-container', 'file.pdf')
const directAccessData = await directAccess.download()
// Write the file to disk as example usage
const writeStream = fs.createWriteStream('./local.pdf')
// Pipe in the first or the second file to the write stream:
firstData.pipe(writeStream)
Identity
Identity is an abstraction of the Keystone REST API. It's implementation is very basic as it currently only fetches tokens and the catalog of what services are available.
const identity = new Identity(context)
// This is a Token instance that keeps track of when it expires etc.
// To get the actual token you need to access token.token
const token = await identity.getToken()
// Access the service catalog and the different endpoints for each service
const catalog = await identity.getServiceCatalog()
const barbican = catalog['key-manager']
console.log(`Barbican public URL: ${barbican.public}`)
Authenticated Axios Instance
The AuthenticatedClient
is an axios instance which comes preset with baseURL and authentication token for all the services implemented by Openstack, even the ones that does not have a proper API in this package, so this can be used for all operations but requires a bit more work.
This class also serves as a parent class to all other classes that requires API access to Openstack.
// Create a client for the public Barbican API
const client = new AuthenticatedClient(context, 'key-manager', 'public')
// Check that the token is still valid etc and create an AxiosInstance
const axios = await client.getAxios()
console.log(axios.defaults.baseURL) // 'https://host.openstack.com:9311
console.log(axios.defaults.headers) // {'X-Auth-Token': 'secret-token'}
const barbicanResp = await axios.get('') // Get the base URL