ML
    • Recent
    • Categories
    • Tags
    • Popular
    • Users
    • Groups
    • Register
    • Login
    1. Topics
    2. stacksofplates
    3. Best
    • Profile
    • Following 0
    • Followers 13
    • Topics 145
    • Posts 7,946
    • Groups 0

    Posts

    Recent Best Controversial
    • RE: Force USB encryption Windows and Mac

      I do know they also used Kingston DataTravelers. So if you didn't want to have to type the pin on the USB drive, you could just plug that model in and there was a small piece of software that ran and you could type in the password. It worked on both Linux and Windows.

      Here's the link to the Kingston site with the encrypted ones:
      https://www.kingston.com/en/usb-flash-drives?use=data security

      posted in IT Discussion
      stacksofplatesS
      stacksofplates
    • RE: Managing Public Github project with private files

      If you wanted to do more of a true 12 factor native approach, you would use environment variables. That way you can easily change deployments without changing any code base at all.

      posted in IT Discussion
      stacksofplatesS
      stacksofplates
    • RE: Managing Public Github project with private files

      So for example, I have a dot file in my home directory I use to set env variables for my Terraform deployments. It sets the particulars for the provider auth and the backend auth. That way I can just do source ~/.terraform and I have all of that set. I don't keep the password in there. I do:

       export ENV_VAR="this is the password"
      

      and I include the space in front. That way the line isn't recorded in my history. Now when I deploy with our CI/CD process I can inject the environment variables directly into the pipeline.

      posted in IT Discussion
      stacksofplatesS
      stacksofplates
    • Mocking API Endpoints with Go

      So I had to mock an API in something I'm writing for testing and I figured I'd post this to show you an easy way to do it in Go.

      First you need to get the JSON structure for the response you'll be mocking. To do this you can just use cURL or whatever tool you want.

      Let's use JSON Placeholder since it's free and doesn't require any authentication. If you go to this URL, you'll see the comments API: https://jsonplaceholder.typicode.com/posts/1/comments

      I use this site to convert JSON to structs. If you paste in the JSON data you get a struct like this:

      type Comment []struct {
          PostID int    `json:"postId"`
          ID     int    `json:"id"`
          Name   string `json:"name"`
          Email  string `json:"email"`
          Body   string `json:"body"`
      }
      

      So we just need to be able to mock this in our unit tests. Here's a small app that reaches out to JSON Placeholder and gets all of the comments that exist for a specific post.

      package main
      
      import (
      	"encoding/json"
      	"fmt"
      	"io/ioutil"
      	"log"
      	"net/http"
      )
      
      type Comment []struct {
      	PostID int    `json:"postId"`
      	ID     int    `json:"id"`
      	Name   string `json:"name"`
      	Email  string `json:"email"`
      	Body   string `json:"body"`
      }
      
      func (c Comment) getComment(u string) {
      
      	req, err := http.Get(u)
      	if err != nil {
      		log.Fatal(err)
      	}
      
      	body, err := ioutil.ReadAll(req.Body)
      	if err != nil {
      		log.Fatal(err)
      	}
      
      	error := json.Unmarshal(body, &c)
      	if error != nil {
      		log.Fatal(error)
      	}
      
      	fmt.Println(c[0].Name)
      
      }
      
      func main() {
      	var c Comment
      
      	c.getComment("https://jsonplaceholder.typicode.com/posts/1/comments")
      }
      

      However, when you're unit testing, you don't want to have to actually reach out to the site. That's more of an integration test. So to be able to test our method, we need to mock that API endpoint. So to do that Go has a test server built in for this reason. You can use it like this:

      package main
      
      import (
      	"io"
      	"net/http"
      	"net/http/httptest"
      	"testing"
      )
      
      type commentTest struct {
      	actual   string
      	expected string
      }
      
      type commentInt struct {
      	actual   int
      	expected int
      }
      
      func TestgetComment(t *testing.T) {
      	data := `
      	[
        		{
          		"postId": 1,
          		"id": 1,
          		"name": "test name",
          		"email": "[email protected]",
          		"body": "this is the body"
        		},
        	]
      	`
      
      	ts := httptest.NewServer(
      		http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
      			io.WriteString(w, data)
      		}))
      
      	defer ts.Close()
      
      	var c Comment
      
      	c.getComment(ts.URL)
      
      	var tests = []commentTest{
      		{c[0].Name, "test name"},
      		{c[0].Email, "[email protected]"},
      		{c[0].Body, "this is the body"},
      	}
      
      	for _, tt := range tests {
      		if tt.actual != tt.expected {
      			t.Errorf("got %v, want %v", tt.actual, tt.expected)
      		}
      	}
      
      	var testInt = []commentInt {
      		{c[0].PostID, 1},
      		{c[0].ID, 1},
      	}
      
      	for _, ti := range testInt {
      		if ti.actual != ti.expected {
      			t.Errorf("got %v, want %v", ti.actual, ti.expected)
      		}
      	}
      
      }
      

      This particular test happened to be a little long because of the two types of data. There might be an easier way by building one struct for both the int and string types but this way was easy to write really quickly.

      I don't want to get into how testing in Go works. However, the important line is ts := httptest.NewServer(). That's where we define our test server. We tell it to take data and put that into w which is our response. So when we run our c.getComment() method we wrote earlier, we can pass ts.URL which is the URL of our test server and we will get a response of whatever is in data. Then we just compare the results to what we expect them to be and if they aren't the same the test will fail.

      It's good to note that if your JSON data is long, you probably don't want to put it in line. So you could store it in a file alongside your code and pass the data in that way. You would just use something like data, err := ioutil.ReadFile("./data.json").

      posted in IT Discussion golang unit test mock api api
      stacksofplatesS
      stacksofplates
    • RE: Researching OpenDental Software

      https://www.opendental.com/site/sourcecode.html

      Tortoise SVN.............

      You have to install the trial version to get the initial database tables set up? What is this?

      posted in IT Discussion
      stacksofplatesS
      stacksofplates
    • RE: Researching OpenDental Software

      I'm honestly surprised it's not built with FoxPro.

      posted in IT Discussion
      stacksofplatesS
      stacksofplates
    • RE: Automated Provisioning - KVM & CM tools

      Terraform will do this and I have an Ansible role to do it also.

      As @IRJ mentioned Vagrant will work also. However I feel Terraform is a better fit as you have more control over the specific pieces of your infrastructure.

      posted in IT Discussion
      stacksofplatesS
      stacksofplates
    • RE: Copying log to file share in realtime (or close)

      Even though you already found an answer, there's a couple of other things you can do. Since you are on CentO6, you can use inotify to keep the files synchronized. If you ever get to CentOS 7, you can do a similar task with a systemd.path unit.

      posted in IT Discussion
      stacksofplatesS
      stacksofplates
    • RE: Art applications

      The mangolassi logo was done in Inkscape. All of the logos Ive done are.

      posted in IT Discussion
      stacksofplatesS
      stacksofplates
    • RE: Cross platform automated patch management

      This is the provider I use to clone KVM guests with Terraform https://github.com/dmacvicar/terraform-provider-libvirt

      posted in IT Discussion
      stacksofplatesS
      stacksofplates
    • RE: Containers on Bare Metal

      @travisdh1 said in Containers on Bare Metal:

      @stacksofplates said in Containers on Bare Metal:

      @travisdh1 said in Containers on Bare Metal:

      Containers never run on bare metal. They are all considered Type-3 hypervisors. Assuming I remember correctly, it's been a while since we had that discussion.

      I'm assuming he means run them on bare metal vs inside of a VM.

      Then the answer is no, because it's impossible.

      It really doesn't matter. So long as you've got enough cpu/ram/iops to handle your workload.

      Idk what this is supposed to mean but you can def deploy to bare metal. Depending on how the container is constructed and what engine you're using you can deploy just a binary that's just process on the system. All containers are just processes but not all of them are single binaries with no dependencies.

      Even if you're using a full OS inside of a container running in Docker it's still using the kernel on bare metal.

      posted in IT Discussion
      stacksofplatesS
      stacksofplates
    • RE: Containers on Bare Metal

      @scottalanmiller said in Containers on Bare Metal:

      LXD is what we use. Very fast, very mature, and good tools for it.

      @Emad-R Yeah LXD has taken the OCI image idea and applied it to LXC. LXC was doing something kind of like that later on. When you did an lxc-create -t download it would look at a text file with links to tarballs to download. LXD has incorporated images from the beginning which has given them a lot of flexibility like updating and layering.

      posted in IT Discussion
      stacksofplatesS
      stacksofplates
    • RE: Tracking Tasks

      My group uses a tool called Kanboard. We've used Microsoft planner also which is ok I guess. We are moving over to VersionOne. Zoho sprints is also a decent tracking tool as well.

      posted in IT Discussion
      stacksofplatesS
      stacksofplates
    • Extending Packages with Go

      Go makes extending packages easy. You can easily take a package and add your own functionality. Let's use logging as an example.

      A popular logging package for Go is logrus. It's at "github.com/sirupsen/logrus". So let's start by creating a package of our own and import logrus as a dependency:

      package mangologs
      
      import (
          "github.com/sirupsen/logrus"
      )
      
      

      Now that we've imported logrus, let's extend it by creating our own custom logging entry. Let's say that our company Mangos, Inc requires that we have the app owner and their phone number as part of their application logs (stupid example but you get the point) and that the logs be in JSON format for easier parsing. Let's create our own logging entry so that you don't need to define that every time you write an application:

      package mangologs
      
      import (
          "os"
          "github.com/sirupsen/logrus"
      )
      
      type AppOwner struct {
          Name   string
          Number string
      }
      
      type MangoLogger interface {
          Debug(args ...interface{})
          Info(args ...interface{})
          Print(args ...interface{})
          Warn(args ...interface{})
          Warning(args ...interface{})
          Error(args ...interface{})
          Fatal(args ...interface{})
          Panic(args ...interface{})
      }
      
      var hostName := os.Getenv("HOSTNAME")
      
      func New(name, number string) MangoLogger {
      
          logger := logrus.New()    
      
          logger.SetFormatter(&logrus.JSONFormatter{})
      
          logger.SetReportCaller(true)
      
          entry := logger.WithFields(logrus.Fields{
              "owner_name": name,
              "owner_number": number,
          })
      
          return entry
      
      }
      
      

      We create our own interface that implements only the methods we want our logging package to have. This is both to simplify the example and to show that you can slim down the options available to people if you only want to expose certain things. Then we set the formatting for the logging in the New() function.

      Then in our actual application we call our package:

      package main
      
      import (
          "github.com/mangos/mangologs"
      )
      
      var owner mangologs.AppOwner
      
      func main() {
          owner.Name = "John"
          owner.Number = "555-555-5555"
      
          var log = mangologs.New(owner.Name, owner.Number)
      
          log.Error("something went wrong")
      }
      

      So now our format looks like this

      {"file":"/data/data/com.termux/files/usr/tmp/test.MhzSYLadxB/main.go:15","func":"main.main","level":"error","msg":"something went wrong","owner_name":"John","owner_number":"555-555-5555","time":"2019-10-01T23:58:38Z"}
      

      You can see it includes our file, function name, our level, the owner_name, owner_number, and timestamp.
      Whereas if we just import logrus and did log.Error("something went wrong") it would look like this:

      ERRO[0000] something went wrong
      

      So now any time you want to use this format, you just need to import your package and call the mangologs.New() function with the name and number parameters and it sets up your logging format for you.

      posted in IT Discussion golang
      stacksofplatesS
      stacksofplates
    • RE: Static Site Generators

      @scottalanmiller said in Static Site Generators:

      @stacksofplates said in Static Site Generators:

      @scottalanmiller said in Static Site Generators:

      @stacksofplates said in Static Site Generators:

      I honestly don't understand how Jekyll could be easier than Hugo.

      Maybe we're both having the same issue with Hugo that something is so easy to use that we are overlooking it and trying to make it harder than it is.

      Maybe. The workflow is almost identical to Jekyll. But it's faster building and you don't need to set up a ruby environment.

      Can you start with a theme and just begin working from inside of it?

      Yeah. That's how I usually do it.

      posted in IT Discussion
      stacksofplatesS
      stacksofplates
    • RE: Static Site Generators

      https://mangolassi.it/topic/20702/building-a-hugo-site-from-a-theme

      posted in IT Discussion
      stacksofplatesS
      stacksofplates
    • RE: Building A Hugo Site From a Theme

      @Obsolesce said in Building A Hugo Site From a Theme:

      Yeah, that's not working (now it is). Here is what I did from fresh Ubuntu install.

      1. sudo apt update
      2. sudo apt upgrade
      3. sudo apt install hugo
      4. hugo version to verify installation
      5. hugo new site testsite.com
      6. Downloaded https://github.com/themefisher/meghna-hugo/archive/master.zip
      7. Extracted it into the /home/testsite.com/themes directory
      8. Renamed folder in themes directory to meghna-hugo.
      9. Copied the exampleSite folder to site root, replacing/merging/overwriting everything when asked.
      10. Ran hugo serve -D from the /home/testsite.com directory.

      Result: Blank white page.

      UPDATE (added steps 7,8,9)
      Okay I missed your step 5, and did that, after I found the directory you were referring to:

      ERRORS:

      1. Says my hugo version is too old for the theme. It looks like the default repo uses version 0.40.x, and the theme requires v0.55.x. So I found the place in the theme config to change minimal version, and continued to get a wall of errors.

      --

      1. Installed latest version via built-in software install GUI

      2. Retried my steps starting at step 4.

      3. NOW I get a working site.

      c92768ff-5867-4eed-bb98-ab895d60c3f5-image.png

      I don't ever install from the repos. It's a single binary so I grab the latest release from their releases page and put it in ~/bin. In my experience the themes are more likely to work with the newer version and not an older one. But 40 is exceptionally old, around a year and a half. That's why I usually just grab from releases every so often.

      posted in IT Discussion
      stacksofplatesS
      stacksofplates
    • RE: Building A Hugo Site From a Theme

      @Obsolesce said in Building A Hugo Site From a Theme:

      @black3dynamite said in Building A Hugo Site From a Theme:

      @stacksofplates said in Building A Hugo Site From a Theme:

      @Obsolesce said in Building A Hugo Site From a Theme:

      Yeah, that's not working (now it is). Here is what I did from fresh Ubuntu install.

      1. sudo apt update
      2. sudo apt upgrade
      3. sudo apt install hugo
      4. hugo version to verify installation
      5. hugo new site testsite.com
      6. Downloaded https://github.com/themefisher/meghna-hugo/archive/master.zip
      7. Extracted it into the /home/testsite.com/themes directory
      8. Renamed folder in themes directory to meghna-hugo.
      9. Copied the exampleSite folder to site root, replacing/merging/overwriting everything when asked.
      10. Ran hugo serve -D from the /home/testsite.com directory.

      Result: Blank white page.

      UPDATE (added steps 7,8,9)
      Okay I missed your step 5, and did that, after I found the directory you were referring to:

      ERRORS:

      1. Says my hugo version is too old for the theme. It looks like the default repo uses version 0.40.x, and the theme requires v0.55.x. So I found the place in the theme config to change minimal version, and continued to get a wall of errors.

      --

      1. Installed latest version via built-in software install GUI

      2. Retried my steps starting at step 4.

      3. NOW I get a working site.

      c92768ff-5867-4eed-bb98-ab895d60c3f5-image.png

      I don't ever install from the repos. It's a single binary so I grab the latest release from their releases page and put it in ~/bin. In my experience the themes are more likely to work with the newer version and not an older one. But 40 is exceptionally old, around a year and a half. That's why I usually just grab from releases every so often.

      Another resacón to avoid LTS releases unless you are using the latest release from there website.

      Ya I was just using the install guide from the Hugo website... I think about how the Ubuntu repo was such shit being so behind.

      But then again I suppose that's why not to install the LTS release. I used Hyper-V's built-in wizard and blindly selected Ubuntu. But, it does offer 19.04, however, even 19.04 gives an extremely old version of Hugo (0.52-1 LOL!)

      I would have been much better off had I used Windows and Chocolatey, as that uses the current version (0.59).

      Doing things with Go has really made me lazy. Having a single binary is so nice. If I need separate dependencies for applications it kind of annoys me now.

      posted in IT Discussion
      stacksofplatesS
      stacksofplates
    • RE: Centrally Controlled Local Backup System Options

      I mean an outside the box scenario is you could use Jenkins to schedule all of this. Then just use something like Restic or Borg to do the backups either locally or to a central location.

      Then you can have Jenkins send messages/emails on a failure. You'd just need a Jenkins slave at every site (can be whatever you are running the backup on).

      posted in IT Discussion
      stacksofplatesS
      stacksofplates
    • RE: Centrally Controlled Local Backup System Options

      I use Borg for my laptop and it's been running forever. It's just a systemd timer, but you could easily have that script customized for each site and run the exact same job at each site, just the script would determine what happens.

      posted in IT Discussion
      stacksofplatesS
      stacksofplates
    • 1 / 1