{"id":18907321,"url":"https://github.com/tisgoud/makesnapshot","last_synced_at":"2025-08-03T03:34:24.459Z","repository":{"id":103488760,"uuid":"188311386","full_name":"tIsGoud/makeSnapshot","owner":"tIsGoud","description":"Create a snapshot of a virtual machine through the vRA APIs","archived":false,"fork":false,"pushed_at":"2019-05-30T09:34:35.000Z","size":27256,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":4,"default_branch":"master","last_synced_at":"2024-12-31T11:45:24.298Z","etag":null,"topics":["cli","go","gol","vra"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/tIsGoud.png","metadata":{"files":{"readme":"readme.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2019-05-23T21:49:48.000Z","updated_at":"2024-01-04T00:32:16.000Z","dependencies_parsed_at":null,"dependency_job_id":"5d43937e-1066-4f03-b951-476e46373357","html_url":"https://github.com/tIsGoud/makeSnapshot","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tIsGoud%2FmakeSnapshot","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tIsGoud%2FmakeSnapshot/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tIsGoud%2FmakeSnapshot/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/tIsGoud%2FmakeSnapshot/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/tIsGoud","download_url":"https://codeload.github.com/tIsGoud/makeSnapshot/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239891081,"owners_count":19714073,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["cli","go","gol","vra"],"created_at":"2024-11-08T09:20:48.606Z","updated_at":"2025-02-20T18:27:06.989Z","avatar_url":"https://github.com/tIsGoud.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# makeSnapshot\n\n![makeSnapshot](img/makeSnapshot.png)\n\nmakeSnapshot is a CLI tool to create a snapshot of a virtual machine on the KPN vRA platform.\nRestricted by a platform policy only one snapshot per VM is allowed. The default behaviour is to overwrite the existing snapshot.\n\nThe main goal to build this app was that it enables the full automation of software deployment on a tenant environment. We normally create a snapshot of a VM before upgrading software.\nBefore we had to go into the vRA portal to create a snapshot manually, now we can incorporate the \"snapshotting\" in an automated workflow.\n\n## vRA API's\n\nSeveral API calls are needed to creates a snapshot of the virtual machine. I wrote a blogpost \"[Creating a snapshot via the vRA API](https://tisgoud.nl/creating-a-snapshot-via-the-vra-api/)\" describing the different vRA API-calls.\n\n## Config file\n\nA yaml configuration file is used to store some required parameters like the baseURL, name of the tenant, login domain, and credentials. The default configuration file (makeSnapshot.yaml) is stored in the application directory.\nThe content of a sample config file:\n\n```yaml\n---\nbaseURL: \"https://base-platformURL\"\ntenant: \"tenantName\"\ndomain: \"login domain\"\nuserName: \"userName\"\npassword: \"password\"\n...\n```\n\nYou can create the yaml config file based on this sample or generate it through the 'generateConfig' command.\n\nCreate the default config file: `$ makeSnapshot generateConfig`\n\nCreate a non-default config file: `$ makeSnapshot generateConfig -s ~/myconfigfile.yaml`\n\n## CLI flags\n\nThe command line options can be used in the shorthand form `-c [value]` or `-c=[value]`.\n\n### --config or -c\n\nLoad a non-default configuration file, different name, different location.\n\n_Optional flag. In addition a string value has to be provided._\n\n### --domain or -d\n\nThe 'domain' flag overrides the login domain provided in the config file.\n\n_Optional flag._\n\n### --dry-run or -r\n\nThe 'dry-run' flags enable you to run the application against your environment testing the configuration without making the actual request for a snapshot.\n\n_Optional flag._\n\n### --help or -h\n\nHelp for makeSnapshot application.\n\n_Optional flag._\n\n### --ignoreCase or -i\n\nDue to a feature request this flag was added to make the search for the 'machineName' case insensitive.\n\n_Optional flag._\n\n### --keepExisting or -k\n\nOnly one snapshot is allowed due to a platform policy. The default behaviour is to overwrite the existing snapshot. The 'keepExisting' flag makes sure that the existing snapshot is not overwritten.\n\nWhen a snapshot exists and the 'keepExisting' flag is used the application will fail with a status code 1. This can be used to test the fail scenario in a workflow.\n\n_Optional flag._\n\n### --machineName or -m\n\nThe 'machineName' is a required flag, it expects an additional case-sensitive string as input parameter. The 'machineName' is the name of the virtual machine to snapshot.\nTake note that in the vRA portal the name will be shown with a three letter prefix (tenant specific prefix), this prefix is ignored in the search.\n\n_Mandatory flag. In addition a case-sensitive string value has to be provided._\n\n### --trace or -t\n\nThe 'trace' flag provides information on the different steps of the application. These different steps are described in my blogpost \"[Creating a snapshot via the vRA API](https://tisgoud.nl/creating-a-snapshot-via-the-vra-api/)\".\n\n_Optional flag._\n\n### --version\n\nDisplay the version of the application.\n\n_Optional flag._\n\n## Running the app\n\nThe application interacts with vRA by calling the vRA APIs. The first API calls are merely initialization, once the \"create snapshot\" request is send, vRA processes the request. The request is send from from vRA to vRO to vCenter etc. The processing time is depending on the load of the system but usually takes about half-a-minute.\n\nThe status of the request is checked every 10 seconds until the status is 'succesfull' or 'failed'.\n\nWhen the status is succesfull the snapshot is created and the exit status code will be 0.\nIn case of a failure the snapshot is not created and the exit status code is 1 or higher.\n\nThe exit status code is not displayed when running the application from the commandline but can be checked right after the application has run with the following command `echo $?`.\n\nJenkins takes notion of the status code.\n\nSample output for a succesfull request and how to display the exit status code:\n\n```\n$ ./makeSnapshot -c myConfig.yaml -m myVirtualMachineToSnap -t\n2019/05/29 01:33:15 Using config file: myConfig.yaml\n2019/05/29 01:33:15 Creating snapshot of virtual machine \"myVirtualMachineToSnap\" for tenant \"tIsGoud\"\n2019/05/29 01:33:15 Step 1 - Get bearer token\n2019/05/29 01:33:16 Step 2 - Get virtual machine resource ID for myVirtualMachineToSnap\n2019/05/29 01:33:16 Step 3 - Get snapshot resource action ID for myVirtualMachineToSnap\n2019/05/29 01:33:18 Step 4 - Get resource action template\n2019/05/29 01:33:18 Step 5 - Send snapshot request for myVirtualMachineToSnap\n2019/05/29 01:33:19 Step 6 - Get snapshot request status...\n2019/05/29 01:33:29 Step 6 - Snapshot request status: In Progress\n2019/05/29 01:33:39 Step 6 - Snapshot request status: In Progress\n2019/05/29 01:33:49 Step 6 - Snapshot request status: Successful\n2019/05/29 01:33:49 Bye from makeSnapshot\n\n$ echo $?\n0\n```\n\n Output of a failing request with the exit status code of 1:\n\n```\n$ ./makeSnapshot -c myConfig.yaml -m myVirtualMachineToSnap -t -k\n2019/05/29 01:34:11 Using config file: myConfig.yaml\n2019/05/29 01:34:11 Creating snapshot of virtual machine \"myVirtualMachineToSnap\" for tenant \"tIsGoud\"\n2019/05/29 01:34:11 Step 1 - Get bearer token\n2019/05/29 01:34:11 Step 2 - Get virtual machine resource ID for myVirtualMachineToSnap\n2019/05/29 01:34:12 Step 3 - Get snapshot resource action ID for myVirtualMachineToSnap\n2019/05/29 01:34:12 Step 4 - Get resource action template\n2019/05/29 01:34:12 Step 5 - Send snapshot request for myVirtualMachineToSnap\n2019/05/29 01:34:12 Step 6 - Get snapshot request status...\n2019/05/29 01:34:23 Step 6 - Snapshot request status: In Progress\n2019/05/29 01:34:33 Step 6 - Snapshot request status: Failed\n2019/05/29 01:34:33 Error: Snapshot request failed, check the vRA portal for more info\n\n$ echo $?\n1\n```\n\n## Go(lang)\n\nThe software was written in Go version 1.12.1.\n\nBeing it a CLI-tool I used the combination of [Cobra](https://github.com/spf13/cobra) and [Viper](https://github.com/spf13/viper) to handle the commandline parameters and the configuration file.\n\n## Cross platform building\n\nThe software was developed on a Mac.\n\nMacOS build:\n\n```shell\ngo build -o builds/macos/makeSnapshot .\n```\n\nLinux build:\n\n```shell\nenv GOOS=linux GOARCH=386 go build -o builds/linux-386/makeSnapshot .\n```\n\nWindows build:\n\n```shell\nenv GOOS=windows GOARCH=386 go build -o builds/windows/makeSnapshot.exe .\n```\n\nNote: For the Windows build, [mousetrap](https://github.com/inconshreveable/mousetrap) was required.\n\n## DISCLAIMER\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN\nTHE SOFTWARE.\n\n## Personal note\n\nI see this application as a one-trick-pony, just doing one thing very well. While developing the application and through the use of the Cobra-framework and Viper, many features were added. Probably too much. Writing documentation like this 'readme.md' also felt as too much. Almost the same information can be found when running the application with --help flag.\n\nAnother thing I noticed is that neither the documentation nor the help flag was used for the first implementation (or even afterwards ...). That made me wonder, why do I put all this effort in this unread documentation? Just skip it next time?\nThen I read the following quote:\n\n\u003e Documentation is a love letter that you write to your future self - Damian Conway\n\nSo next time I again will write that love letter.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftisgoud%2Fmakesnapshot","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftisgoud%2Fmakesnapshot","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftisgoud%2Fmakesnapshot/lists"}