Skip to content

Commit

Permalink
feat: Made non-sa-auth possible with gcloud
Browse files Browse the repository at this point in the history
  • Loading branch information
dploeger committed Jun 1, 2023
1 parent 922aa36 commit 8104a24
Show file tree
Hide file tree
Showing 7 changed files with 97 additions and 24 deletions.
17 changes: 17 additions & 0 deletions ccc/ccc.go
Original file line number Diff line number Diff line change
Expand Up @@ -327,7 +327,24 @@ func main() {
if err := file.Close(); err != nil {
fatal(err)
}
})

api.POST("/googleAuth", func(c *gin.Context) {
var json Mfa
if err := c.ShouldBindJSON(&json); err != nil {
c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()})
return
}
file, err := os.Create("/tmp/gcloud_auth")
if err != nil {
fatal(err)
}
if _, err := file.WriteString(fmt.Sprintf("%s\n", json.Code)); err != nil {
fatal(err)
}
if err := file.Close(); err != nil {
fatal(err)
}
})

if err := router.Run(fmt.Sprintf(":%s", port)); err != nil {
Expand Down
41 changes: 36 additions & 5 deletions ccc/client/src/components/Progress.vue
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,16 @@
Open Authentication
</v-btn>
</v-alert>
<v-alert :value="oAuthCode === '' && oAuthUrl !== ''" type="info">
CloudControlCenter has detected an authentication request. Click here to open the authentication URL:
<v-alert :value="googleAuth && !completedAuth" type="info">
CloudControlCenter has detected a google authentication request. After you've clicked the following
button and authenticated in, copy the Google authorization code you'll get into the text input below.
<v-btn v-on:click="doOAuth">
Open Authentication
</v-btn>
<v-form v-on:submit="sendGoogleAuth">
<v-text-field autofocus v-model="googleAuthCode"></v-text-field>
<v-btn type="submit">Send code</v-btn>
</v-form>
</v-alert>
<v-alert :value="requiresMFA" type="info">
CloudControlCenter has detected an MFA code request. Enter the current code of your authenticator:
Expand Down Expand Up @@ -83,8 +88,12 @@ export default class Progress extends Vue {
public currentError: string = '';
public requiresMFA: boolean = false;
public googleAuth: boolean = false;
public googleAuthCode: string = '';
public mfaCode: string = '';
public completedAuth: boolean = false;
public mounted() {
axios.default.get('/api/steps')
.then(
Expand Down Expand Up @@ -151,13 +160,12 @@ export default class Progress extends Vue {
}
}
const googleOauthRegexp = new RegExp(
'Your browser has been opened to visit:\n\n\s+(.+)$'
);
const googleOauthRegexp = new RegExp('Go to the following link in your browser:\r<br/>\r<br/> +(.+)')
if (googleOauthRegexp.test(output)) {
const matches = googleOauthRegexp.exec(output);
if (matches) {
this.oAuthUrl = matches[1];
this.googleAuth = true;
}
}
// MFA feature. Check for a regexp request, but also check if the MFA was already entered.
Expand Down Expand Up @@ -193,6 +201,29 @@ export default class Progress extends Vue {
});
}
public sendGoogleAuth(event: Event) {
event.preventDefault();
axios.default.post('/api/googleAuth', {
code: this.googleAuthCode,
})
.then(() => {
this.googleAuth = false;
this.googleAuthCode = '';
this.currentError = '';
this.completedAuth = true;
})
.catch((error) => {
this.currentError = 'Can not set Google Auth code:';
if (error.response) {
this.currentError = `${this.currentError} ([${error.response.status}] ${error.response.data})`;
} else if (error.message) {
this.currentError = `${this.currentError} (${error.message})`;
}
});
}
}
</script>

Expand Down
4 changes: 2 additions & 2 deletions feature/kubernetes/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,8 @@ then
do
ZONE=$(echo "${ZONEDCLUSTER}" | cut -d ":" -f 1)
CLUSTER=$(echo "${ZONEDCLUSTER}" | cut -d ":" -f 2)
execHandle "Authenticating against cluster ${CLUSTER} in zone ${ZONE}" gcloud container clusters get-credentials "${CLUSTER}" --zone "${ZONE}" --project "${GCLOUD_PROJECTID}"
echo gcloud container clusters get-credentials "${CLUSTER}" --zone "${ZONE}" --project "${GCLOUD_PROJECTID}" >> ~/bin/k8s-relogin
execHandle "Authenticating against cluster ${CLUSTER} in zone ${ZONE}" gcloud container clusters get-credentials "${CLUSTER}" --zone "${ZONE}"
echo gcloud container clusters get-credentials "${CLUSTER}" --zone "${ZONE}" >> ~/bin/k8s-relogin
chmod +x ~/bin/k8s-relogin
done
fi
Expand Down
1 change: 1 addition & 0 deletions flavour/gcloud/Dockerfile.flavour
Original file line number Diff line number Diff line change
Expand Up @@ -14,4 +14,5 @@ RUN apk add sudo bash curl && \

COPY flavour/gcloud/flavour /home/cloudcontrol/flavour
COPY flavour/gcloud/flavourinit.sh /home/cloudcontrol/bin/flavourinit.sh
COPY flavour/gcloud/login.expect /home/cloudcontrol/bin/login.expect
RUN chmod +x /home/cloudcontrol/bin/flavourinit.sh
7 changes: 4 additions & 3 deletions flavour/gcloud/flavour.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@ description: |
* Create a key and download it as a JSON file
* Mount a directory that contains the JSON file into the CloudControl container and set GCLOUD_KEYPATH accordingly
configuration:
- "Environment GCLOUD_PROJECTID: The id of the Google Cloud project to connect to"
- "Environment GCLOUD_USE_SA (Possible values: true, false. Defaults to false): Use a service account to log into Google Cloud. Requires GCLOUD_KEYPATH"
- "Environment GCLOUD_KEYPATH: Path inside CloudControl that holds the service account JSON file"
- "Environment GOOGLE_PROJECT: The id of the Google Cloud project to connect to"
- |
Environment GOOGLE_CREDENTIALS: Path inside CloudControl that holds the service account JSON file. Will use
browser based login if unset.
platforms:
- linux/amd64
- linux/arm64
33 changes: 19 additions & 14 deletions flavour/gcloud/flavourinit.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,30 +2,35 @@

. /feature-installer-utils.sh

if [ "X${GCLOUD_USE_SA:-false}X" == "XtrueX" ] && [ -z "$GCLOUD_KEYPATH" ]
if [ "X${GCLOUD_USE_SA:-false}X" == "XtrueX" ]
then
echo "Please set GCLOUD_KEYPATH environment variable"
exit 1
echo "Use of GCLOUD_USE_SA is deprecated, please simply set GOOGLE_CREDENTIALS to the path of a service account"
echo "key file."
if [ -z "${GCLOUD_KEYPATH}" ]
then
echo "GCLOUD_USE_SA was enabled, but GCLOUD_KEYPATH was not set."
exit 1
fi
GOOGLE_CREDENTIALS="${GCLOUD_KEYPATH}"
fi

if [ "X${GCLOUD_USE_SA:-false}X" == "XtrueX" ] && [ ! -r "$GCLOUD_KEYPATH" ]
if [ -n "${GOOGLE_CREDENTIALS}" ]
then
echo "File ${GCLOUD_KEYPATH} is not readable"
exit 1
execHandle "Authenticating service account" gcloud auth activate-service-account --key-file "${GOOGLE_CREDENTIALS}"
else
execHandle "Installing expect" sudo apk add expect
expect /home/cloudcontrol/bin/login.expect
fi

if [ -z "$GCLOUD_PROJECTID" ]
if [ -n "${GCLOUD_PROJECTID}" ]
then
echo "Please set GCLOUD_PROJECTID environment variable"
exit 1
echo "Usage of GCLOUD_PROJECTID is deprecated. Please use GOOGLE_PROJECT instead."
GOOGLE_PROJECT="${GCLOUD_PROJECTID}"
fi

if [ "X${GCLOUD_USE_SA:-false}X" == "XtrueX" ]
if [ -n "${GOOGLE_PROJECT}" ]
then
execHandle "Authenticating service account" gcloud auth activate-service-account --key-file "$GCLOUD_KEYPATH"
else
execHandle "Authenticating service account" gcloud auth login
execHandle "Setting project" gcloud config set project "${GOOGLE_PROJECT}"
fi
execHandle "Setting project" gcloud config set project "$GCLOUD_PROJECTID"

exit 0
18 changes: 18 additions & 0 deletions flavour/gcloud/login.expect
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
proc wait_for_auth_code {} {
if {[file exists /tmp/gcloud_auth]} {
set fp [open "/tmp/gcloud_auth" r]
set file_data [read $fp]
close $fp
return $file_data
} else {
after 3000
wait_for_auth_code
}
}

set timeout 90000
spawn gcloud auth login --no-launch-browser
expect "Enter authorization code"
set auth_code [wait_for_auth_code]
send $auth_code
expect eof

0 comments on commit 8104a24

Please sign in to comment.