npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

@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 and credentials:
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